別のSQL2008データベースへのテーブルの移動(インデックス、トリガーなどを含む)


16

1つのSQL2008データベースから別のSQL2008データベースへ、大量(100行以上)の大きなテーブル(数百万行)を移動する必要があります。

もともとインポート/エクスポートウィザードを使用していましたが、すべての宛先テーブルにプライマリキーと外部キー、インデックス、制約、トリガーなどがありませんでした(ID列もプレーンINTに変換されましたが、ウィザード。)

これを行う正しい方法は何ですか?

これがほんの2、3のテーブルである場合、ソースに戻り、テーブル定義(すべてのインデックスなどを含む)をスクリプトで出力してから、スクリプトのインデックス作成部分を宛先で実行します。しかし、テーブルが非常に多いため、これは実用的ではないようです。

データがそれほど多くない場合は、「スクリプトの作成...」ウィザードを使用して、データを含むソースをスクリプト化できますが、72mの行スクリプトはあまり良い考えではありません。


そして、データベース内のすべてのテーブルではありませんか?
木曜日

@thursdaysgeek:ほとんどすべてのテーブルですが、宛先データベースにはすでに100以上のテーブルがあります。そのため、別の名前でバックアップから復元することはオプションではありません。これは基本的に「これら2つの大きなデータベースを結合する」と考えてください。
BradC

回答:


14

テーブルをスクリプト化し、SSISを使用してデータを転送することが、データを新しいデータベースに移動する最も信頼性が高く効果的な方法です。


9

実際には、インポートウィザードと組み合わせて多くの手動スクリプトを使用してそれを行いましたが、今朝、Tibor Karasziのブログ記事のおかげで、より良い答えが見つかりました。

ここでのフラストレーションの一部は、SQL 2000の「DTSインポート/エクスポートウィザード」が、「オブジェクトとデータのコピー」を選択することで、これをほとんど簡単にできることです。

DTSインポートウィザード

この3番目のオプションには、インデックス/トリガーなどを含める機能が含まれます。

高度なオプション

このオプションは、SQL 2005/2008インポートウィザードから削除されました。どうして?わからない:

2008インポートウィザード

2005/2008では、明らかにBIDSでSSISパッケージを手動で作成し、2000ウィザードと同じオプションをすべて含むSQL Serverオブジェクト転送タスクを使用する必要があります。

SSIS SQL Serverオブジェクトの転送タスク


このSSISメソッドを別の同様のタスクに使用したことを投稿したかっただけで、うまくいきました!
BradC

8

テーブルのスクリプトを作成するか、比較ツール(Red Gateなど)を使用してターゲットデータベースにテーブルを生成することを検討します。インデックスまたは制約はまだありません。

次に、同じサーバー上で別の名前でデータベースを復元して、

 INSERT newdb.dbo.newtable SELECT * FROM olddb.dbo.oldtable

..各テーブルに対して、必要に応じてSET IDENTITY INSERT ONを使用

次に、データを読み込んだ後にインデックスと制約を追加します。

それは、SSIS(mrdennyの答え)に対する快適さのレベル、または生のSQLを好むかどうかに依存します。


6

デニー氏の答えに追加します。テーブルスキーマをスクリプト化し、BCPを使用してデータを移動します。SSISに慣れていない場合は、BCPとバッチを簡単に使用できます。数百万行の場合、BCP(一括挿入)に勝るものはありません:)。


4

私はSSISに完全に不快な人です。

ソーステーブルにID列がない場合

  1. ターゲットサーバーに空のデータベースを作成します
  2. ターゲットサーバー上のソースサーバーへのリンクサーバーを作成する
  3. ソースデータベースで以下のスクリプトを実行して、select * into ...ステートメントを生成します
  4. 生成されたスクリプトをターゲットデータベースから実行する
  5. ソースデータベースからの主キー、インデックス、トリガー、関数、およびプロシージャのスクリプト
  6. 生成されたスクリプトによってこれらのオブジェクトを作成します

次に、Select * into ...ステートメントを生成するT-SQL

SET NOCOUNT ON

declare @name sysname
declare @sql varchar(255)

declare db_cursor cursor for
select name from sys.tables order by 1
open db_cursor

fetch next from db_cursor into @name
while @@FETCH_STATUS = 0
begin
    Set @sql = 'select * into [' + @name + '] from [linked_server].[source_db].[dbo].[' + @name + '];'
    print @sql

    fetch next from db_cursor into @name
end

close db_cursor
deallocate db_cursor

これにより、次のようにコピーする各テーブルの行が生成されます

select * into [Table1] from [linked_server].[source_db].[dbo].[Table1];

テーブルにID列が含まれている場合、IDプロパティと主キーを含むテーブルのスクリプトを作成します。

この場合はリンクサーバーを使用しますが、これは一括手法ではないため、insert into ... select ...を使用しません。私は[このSOの質問1と同様のPowerShellスクリプトに取り組んでいますが、まだエラー処理に取り組んでいます。SQLBulkCopyを介してデータベースに送信される前に、テーブル全体がメモリにロードされるため、本当に大きなテーブルはメモリ不足エラーを引き起こす可能性があります。

インデックスの再作成などは、上記の場合と同様です。今回は、主キーの再作成をスキップできます。


テーブルにID列が含まれている場合、この質問のようにできます。手動での作業が軽減されます。私は今でも一括挿入バッチ/ SSISを好んでいます。リンクサーバーは、広いネットワーク上では良いソリューションではないかもしれません。
マリアン

1
@Marianを見てみてくださいdba.stackexchange.com/questions/297/...をあなたはSSISを促進したい場合。SSISは試しませんでしたが、インポートエクスポートウィザードも失敗しました(リンクサーバー以外)。
bernd_k

喜んで手伝いましたが、利用できるOracleボックスはありません。とにかく、私が読んだことから、Oracle CLOBをサポートするプロバイダーはありません
Marian

私はこれについてあなたと一緒にいます-私は時々データを移行しますが、SSISは決して使用しません。
AK

2

データベーススキーマとデータを比較し、最初に空のデータベーススキーマを元のデータベースと同期する比較ツールを使用して、すべてのテーブルを作成できます。

次に、元のデータベースのデータを新しいデータベースと同期し(すべてのテーブルがありますが、すべて空です)、テーブルにレコードを挿入します

これにはApexSQL DiffApexSQL Data Diffを使用しますが、他にも同様のツールがあります。

このプロセスの良い点は、ツールを使用してデータベースを実際に同期する必要がないことです。これは、何百万もの行にとって非常に痛いことがあるためです。

INSERT INTO SQLスクリプトを作成するだけで(複数のギグがある場合でも驚かないでください)、実行できます。

非常に大きなスクリプトをSQL Server Management Studioで開くことさえできないため、sqlcmdまたはosqlを使用します


1

@mrdennyが述べたように-

  1. 最初にすべてのインデックス、FKなどを使用してテーブルをスクリプト化し、宛先データベースに空のテーブルを作成します。

SSISを使用する代わりに、BCPを使用してデータを挿入します

  1. 以下のスクリプトを使用してデータをbcp出力します。SSMSをテキストモードに設定し、以下のスクリプトで生成された出力をbatファイルにコピーします。

    -- save below output in a bat file by executing below in SSMS in TEXT mode
    
    -- clean up: create a bat file with this command --> del D:\BCP\*.dat 
    
    select '"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\bcp.exe" ' /* path to BCP.exe */
        +  QUOTENAME(DB_NAME())+ '.' /* Current Database */
        +  QUOTENAME(SCHEMA_NAME(SCHEMA_ID))+'.'            
        +  QUOTENAME(name)  
        +  ' out D:\BCP\'  /* Path where BCP out files will be stored */
        +  REPLACE(SCHEMA_NAME(schema_id),' ','') + '_' 
        +  REPLACE(name,' ','') 
        + '.dat -T -E -SServerName\Instance -n' /* ServerName, -E will take care of Identity, -n is for Native Format */
    from sys.tables
    where is_ms_shipped = 0 and name <> 'sysdiagrams'                       /* sysdiagrams is classified my MS as UserTable and we dont want it */
    /*and schema_name(schema_id) <> 'unwantedschema'    */                             /* Optional to exclude any schema  */
    order by schema_name(schema_id)
  2. 指定したフォルダーに.datファイルを生成するbatファイルを実行します。

  3. 以下のスクリプトを実行します

    --- Execute this on the destination server.database from SSMS.
    
    --- Make sure the change the @Destdbname and the bcp out path as per your environment.
    
    declare @Destdbname sysname
    set @Destdbname = 'destinationDB' /* Destination Database Name where you want to Bulk Insert in */
    select 'BULK INSERT ' 
    /*Remember Tables must be present on destination database */ 
    + QUOTENAME(@Destdbname) + '.' 
    + QUOTENAME(SCHEMA_NAME(SCHEMA_ID)) 
    + '.' + QUOTENAME(name) 
    + ' from ''D:\BCP\' /* Change here for bcp out path */ 
    + REPLACE(SCHEMA_NAME(schema_id), ' ', '') + '_' + REPLACE(name, ' ', '') 
    + '.dat'' with ( KEEPIDENTITY, DATAFILETYPE = ''native'', TABLOCK )' 
    + char(10) 
    + 'print ''Bulk insert for ' + REPLACE(SCHEMA_NAME(schema_id), ' ', '') + '_' + REPLACE(name, ' ', '') + ' is done... ''' 
    + char(10) + 'go'
       from sys.tables
       where is_ms_shipped = 0
    and name <> 'sysdiagrams' /* sysdiagrams is classified my MS as UserTable and we dont want it */
    and schema_name(schema_id) <> 'unwantedschema' /* Optional to exclude any schema */
        order by schema_name(schema_id) 
  4. SSMSを使用して出力を実行し、データをテーブルに挿入します。

これはネイティブモードを使用するため、非常に高速なbcpメソッドです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.