it-swarm.asia

Memindahkan tabel ke database SQL2008 lainnya (termasuk indeks, pemicu, dll.)

Saya perlu memindahkan sejumlah besar (100+) besar (jutaan baris) tabel dari satu database SQL2008 ke yang lain.

Saya awalnya hanya menggunakan Wisaya Impor/Ekspor, tetapi semua tabel tujuan tidak memiliki kunci utama dan asing, indeks, batasan, pemicu, dll. (Kolom identitas juga dikonversi ke INT sederhana, tapi saya pikir saya baru saja melewatkan kotak centang di Penyihir.)

Apa cara yang benar untuk melakukan ini?

Jika ini hanya beberapa tabel, saya akan kembali ke sumber, skrip definisi tabel (dengan semua indeks, dll), kemudian jalankan bagian pembuatan indeks skrip pada tujuan. Tetapi dengan begitu banyak tabel, ini tampaknya tidak praktis.

Jika tidak ada begitu banyak data, saya bisa menggunakan wizard "Buat Skrip ..." untuk skrip sumber, termasuk data, tetapi skrip baris 72m sepertinya bukan ide yang bagus!

16
BradC

Kami benar-benar melakukannya menggunakan banyak skrip manual dalam hubungannya dengan wizard Impor, tetapi pagi ini saya menemukan jawaban yang lebih baik, milik artikel blog Tibor Karaszi .

Bagian dari frustrasi kami di sini adalah bahwa SQL 2000 "DTS Import/Export Wizard" sebenarnya membuat ini hampir sepele dengan memilih "Salin Objek dan Data":

DTS Import Wizard

Opsi ketiga ini adalah yang berisi kemampuan untuk memasukkan indeks/pemicu, dll:

Advanced Options

Opsi ini [~ # ~] dihapus [~ # ~] dari SQL 2005/2008 Panduan Impor. Mengapa? Tidak ada ide:

2008 Import Wizard

Pada 2005/2008, Anda tampaknya harus secara manual membuat paket SSIS dalam BIDS dan menggunakan Transfer SQL Server Objects Task , yang berisi semua opsi yang sama yang ada di penyihir 2000:

SSIS Transfer SQL Server Objects Task

9
BradC

Membuat skrip tabel, kemudian menggunakan SSIS untuk mentransfer data akan menjadi cara yang paling dapat diandalkan dan efektif untuk memindahkan data ke database baru.

14
mrdenny

Saya akan mempertimbangkan untuk menuliskan tabel, atau menggunakan alat perbandingan (misalnya Gerbang Merah) untuk menghasilkan tabel dalam database target. Tanpa indeks atau kendala.

Lalu saya akan mempertimbangkan memulihkan database dengan nama yang berbeda dan melakukan di server yang sama

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

.. untuk setiap tabel, dengan SET IDENTITAS INSERT AKTIF jika diminta

Lalu saya akan menambahkan indeks dan batasan setelah memuat data.

Itu tergantung pada tingkat kenyamanan Anda dengan SSIS (jawaban mrdenny) atau jika Anda lebih suka SQL mentah.

8
gbn

Saya akan menambahkan jawaban Tn. Denny: Tuliskan skema tabel lalu gunakan BCP untuk memindahkan data. Jika Anda tidak terbiasa dengan SSIS, maka menggunakan BCP dan batch harus mudah dilakukan. Untuk jutaan baris, tidak ada yang mengalahkan BCP (masukkan massal) :).

6
Marian

Saya orang yang benar-benar tidak nyaman dengan SSIS.

Ketika tabel sumber tidak memiliki kolom identitas

  1. buat database kosong di server target
  2. buat server tertaut ke server sumber pada server target
  3. jalankan skrip di bawah ini pada basis data sumber untuk menghasilkan pernyataan * pilih ke ...
  4. jalankan skrip yang dihasilkan dari database target
  5. skrip kunci utama, indeks, pemicu, fungsi dan prosedur dari sumber database
  6. buat objek-objek ini dengan skrip yang dihasilkan

Sekarang T-SQL untuk menghasilkan pernyataan Select * into ...

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

Ini menghasilkan garis untuk setiap tabel untuk menyalin suka

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

Jika tabel berisi kolom identitas, saya skrip tabel termasuk properti identitas dan kunci utama.

Saya tidak menggunakan masukkan ke ... pilih ... menggunakan server yang terhubung dalam hal ini, karena ini bukan teknik massal. Saya sedang mengerjakan beberapa skrip PowerShell yang mirip dengan [this SO pertanyaan 1 , tapi saya masih mengerjakan penanganan kesalahan. Tabel yang sangat besar dapat menyebabkan kehabisan memori kesalahan, karena seluruh tabel dimuat ke dalam memori, sebelum dikirim melalui SQLBulkCopy ke database.

Rekreasi indeks dll. Mirip dengan kasus di atas. Kali ini saya dapat melewatkan rekreasi dari kunci utama.

4
bernd_k

Anda dapat menggunakan alat perbandingan yang membandingkan skema dan data basis data dan pertama-tama menyinkronkan skema database kosong dengan db asli, untuk membuat semua tabel.

Kemudian, sinkronkan data dari database asli dengan yang baru (semua tabel ada di sana, tetapi semuanya kosong) untuk menyisipkan rekaman ke dalam tabel

Saya menggunakan ApexSQL Diff dan ApexSQL Data Diff untuk ini, tetapi ada alat serupa lainnya.

Hal yang baik tentang proses ini adalah Anda tidak harus benar-benar menyinkronkan basis data menggunakan alat ini, karena ini bisa sangat menyakitkan bagi jutaan baris.

Anda bisa membuat skrip INSERT INTO SQL (jangan kaget jika ini beberapa gigs) dan jalankan.

Karena skrip yang begitu besar bahkan tidak dapat dibuka di SQL Server Management Studio, saya menggunakan sqlcmd atau osql

2
Carol Baker West

Seperti yang disebutkan @rdenny -

  1. skrip tabel pertama dengan semua Indeks, FK, dll dan buat tabel kosong di basis data tujuan.

Alih-alih menggunakan SSIS, gunakan BCP untuk memasukkan data

  1. bcp keluar data menggunakan skrip di bawah ini. atur SSMS dalam Mode Teks dan salin output yang dihasilkan oleh skrip di bawah ini dalam file 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. Jalankan file bat yang akan menghasilkan file dat di folder yang telah Anda tentukan.

  3. Jalankan skrip di bawah ini di

    --- 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. Jalankan output menggunakan SSMS untuk memasukkan kembali data dalam tabel.

Ini adalah metode bcp yang sangat cepat karena menggunakan mode Asli.

1
Kin Shah