23

私は次のようなものが欲しい:

insert into server2.database1.table1 select * from server1.database1.table1

両方のテーブルはまったく同じです。

2 つのサーバー インスタンス間でデータをコピーするにはどうすればよいですか?

4

7 に答える 7

53

SQL-リンクサーバー

両方のサーバーがSQLServerの場合は、リンクサーバーを設定できます。セキュリティのためにSQLアカウントを使用することをお勧めします。

その後、あなたは単に実行することができます

insert into server2.database1.dbo.table1 
select * from server1.database1.dbo.table1 where col1 = 'X'

server1に接続されたSQLManagementStudioでクエリを実行し、現在のデータベースをdatabase1に設定した場合、プレフィックスは必要ありません。

server1.database1.dbo.

また、リンクサーバーはserver1で構成され、server2に接続します(その逆ではありません)。

正しいOLEDBドライバーがある場合、この方法は、さまざまな種類のRDBMS(つまり、SQL Server以外のRDBMS)間でも機能します。

クエリを開く

注:条件を適用する前に、元のRDBMSにデータを完全に読み取る必要があるため、特にフィルタリングやサーバー間の結合については、リンクサーバーに過度に依存しないように注意してください。リンクサーバーから多くの問題が発生する可能性があるため、バージョンの違いでさえ頭痛の種になる可能性があるため、開始する前によく読んでください。

このような制限を回避するには、SQLServerに対してOPENQUERYコマンドを使用することをお勧めします。ここに例がありますが、さらに調査することで、ニーズに固有のヘルプを見つける必要があります。

insert into server2.database1.dbo.table1 
select * from OPENQUERY(server1, 'select * from database1.dbo.table1 where col1 = ''X''');

上記のコードはより効率的で、データをポンプスルーする前にソースサーバー上のデータをフィルタリングし(そして利用可能なインデックスを使用して)、ソースサーバーと宛先サーバーの両方の帯域幅/時間/リソースを節約します。

(二重引用符''は、一重引用符を生成するためのエスケープシーケンスであることに注意してください。)

SQL-一時的に同じサーバー上に

有効にします(アンダースコアに注意してください):

insert into server2_database1.dbo.table1 
select * from database1.dbo.table1

まだSQLクエリドメイン内です。server2のデータベースをserver1に一時的に移動できる場合は、リンクサーバーは必要ありません。server1に同じ場所に配置しているときに、データベースの名前を変更する必要があるように見えます。このようなコロケーションを実現するには、さまざまな方法を使用できます。次のいずれかに進む前に、データベースファイルを縮小することをお勧めします。

  1. バックアップ/復元-server2でバックアップ、server1で復元(別の名前)-上記のように挿入を実行しますが、server1またはserver2プレフィックスは使用しません。次に、リバース-server1でバックアップし、server2/で復元します。
  2. デタッチ/アタッチ-データベースの名前を変更し、server2でデタッチし、(圧縮)、ファイルをサーバー1にコピーし、(解凍)、server1にアタッチし、挿入を実行します。次に逆に...

いずれの場合も、SQLServerのバージョンが障壁になる可能性があります。server1のSQLバージョンが低い場合、バックアップとデタッチ/アタッチの両方の方法が失敗する可能性があります。これは、server1データベースをserver2に移動することで回避できます。これは、より適切な場合とそうでない場合があります。

その他の方法

前述のメソッドの好ましい環境要因に失敗する、適切な非SQL/TSQLメソッドである可能性があります。また、正しいアクセス権(OLE DBドライバーなど)がある場合、このメソッドは、さまざまな種類のRDBMS(つまり、SQL Server以外のもの)とデータソース(XML、フラットファイル、Excelスプレッドシートなど)の間でも機能します。 ...)

  • SSISを明示的にBusinessDevelopmentManagement Studioで使用-直接データポンプを使用するか、区切りファイルを中間的に使用します。
  • SSIS SQL Management Studioを介して暗黙的に、server1のdatabase1>タスク>エクスポートを右クリックし、ウィザードを完了します。server2に直接接続するか、フラットファイルの中間を使用して動作する可能性があります。
  • SqlBulkInsertを使用した.Netプログラミング(SSISデータポンプはそのようなオブジェクトを使用していると思います)。興味があれば、これについて詳しく説明します。

例えば。SQLBulkInsertの(psedo-C#コード)

SqlConnection c = new SqlConnection("connectionStringForServer1Database1Here");
SqlConnection c2 = new SqlConnection("connectionStringForServer2Database1Here");
c.Open();
SqlCommand cm = new SqlCommand(c);
cm.CommandText = "select * from table1;";
using (SqlDataReader reader = cm.ExecuteReader())
{
    using (SqlBulkInsert bc = new SqlBulkInsert(c))
    {
         c2.Open();
         bc.DestinationTable = "table1";
         bc.WriteToServer(reader);
    }
}

かなりかっこいいね?速度/効率が懸念される場合-SqlBulkInsertベースのアプローチ(SSISなど)が最適です。

更新-宛先テーブルの変更

宛先テーブルを更新する必要がある場合は、次のことをお勧めします。

  1. 宛先データベースのステージングテーブル(一時テーブル、またはプロセスの前後で切り捨てる適切なテーブル)に書き込みます。後者の方が望ましいです。CREATE TABLE権限がない場合は、前者が唯一の選択肢になる可能性があります。上記のオプションのいずれかを使用して転送を実行できます。
  2. ステージングテーブルから宛先テーブルまで、要件に従ってMERGEINTOコマンドを実行します。これにより、必要に応じて非常に効率的に挿入、更新、および削除できます。

このようなプロセス全体は、スライディングウィンドウ(最後にチェックされてからの変更)で拡張でき、ソースで最近変更された行のみを宛先に適用するため、プロセスが複雑になるため、少なくとも最初に単純な行を実行する必要があります。スライディングウィンドウバージョンを完了した後、定期的にフルアップデートを実行して、スライディングウィンドウにエラーがないことを確認できます。

于 2012-12-22T13:03:19.483 に答える
8

2 つの異なるサーバー間でデータをコピーするには、いくつかのオプションがあります。

于 2012-12-22T12:32:14.070 に答える
4

トッド C# SqlBulkCopy に似ている

通常、これはリンク サーバーを作成するよりも簡単です。

単体テストを作成し、以下を実行します。トリガーがある場合は注意してください。ALTER 権限が必要になります。

    [Test]
    public void BulkCopy()
    {
        var fromConnectionString = @"fromConnectionString";
        var destinationConnectionString = @"destConnectionString2";

        using (var testConnection = new SqlConnection(fromConnectionString))
        {
            testConnection.Open();
            var command = new SqlCommand("select * from MyTable;", testConnection);
            using (var reader = command.ExecuteReader())
            {
                using (var destinationConnection = new SqlConnection(destinationConnectionString))
                {
                    using (var bc = new SqlBulkCopy(destinationConnection))
                    {
                        destinationConnection.Open();
                        bc.DestinationTableName = "dbo.MyTable";
                        bc.WriteToServer(reader);
                    }
                }
            }
        }
    }
}
于 2015-09-15T10:49:03.993 に答える
1

これを行う最善の方法は、「リンク サーバー」を作成することです。次に、以下のステートメントを挿入ステートメントに使用して、テーブルを定義できます

 [linkedserver].databasename.dbo.tablename
于 2012-12-22T12:52:48.157 に答える
0

サーバー A で、リンク サーバー (B) を追加します。

http://msdn.microsoft.com/en-us/library/ms188279.aspx

その後、2 つの間でデータを転送できます。

ある SQL Server から別の SQL Server にテーブル データをエクスポートする

HTH

于 2012-12-22T12:46:38.637 に答える