Bagaimana cara saya menangani batasan FK saat mengimpor data menggunakan DTS Import / Export Wizard?

16

Saya mencoba menggunakan SQL Server Import and Export Wizard untuk menyalin data dari db produksi saya ke dev db saya tetapi ketika saya gagal dengan kesalahan "Statemen INSERT bertentangan dengan batasan KUNCI ASING" saya punya lebih dari 40 tabel dengan banyak kendala FK, adakah cara mudah untuk menghadapinya tanpa harus menulis drop constraint / menambahkan skrip constrat?

Sunting: Saya baru tahu bahwa di SQL Server edisi Web, yang saya jalankan, DTS tidak akan membiarkan Anda menyimpan paket.


sumber

Jawaban:

28

Saya diberi solusi ini di SQLTeam.com:

Menggunakan:

 EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'

Kemudian impor data Anda

EXEC sp_msforeachtable 'ALTER TABLE ? CHECK CONSTRAINT all'

Dengan menggunakan metode itu saya dapat mengimpor semua data tanpa masalah.

Paul White 9
sumber
1
sp_msforeachtable(dan sp_MSForEachDb) tidak berdokumen dan tidak didukung. Anda seharusnya tidak / menghindari menggunakannya. Mungkin melewatkan tabel !! Lihat posting ini dari @AaronBertrand -> sqlblog.com/blogs/aaron_bertrand/archive/2010/12/29/… dan item hubungkan ini - (MS menunjukkan bahwa mereka tidak akan memperbaikinya) -> connect.microsoft.com/SQLServer / feedback / details / 264677 / ...
Kin Shah
Berfungsi sempurna untuk saya setelah berjam-jam mengalahkan otak saya berusaha mengatasi kendala FK untuk ekspor data.
levininja
Berjalan di Azure SQL V12, saya mendapatkan kesalahan "Tidak dapat menemukan prosedur tersimpan 'sp_msforeachtable'."
Dai
Tidak berfungsi lagi: /
Douglas Gaskell
Anda adalah penyelamat hidup
Dapatkah Şahin Bakır
5

Saya menghasilkan salinan tepat database di mesin saya dari server yang saya tidak kontrol.

Saya bodoh , tapi inilah yang saya lakukan:

  1. Membuat DB dari skrip saya yang ada di kontrol sumber (petunjuk, petunjuk!) Jika Anda tidak memiliki skrip, Anda selalu dapat membuatnya dari DB yang ada melalui Tasksopsi.

  2. Jika ada data yang dimasukkan secara otomatis ke dalam YourDB saat pembuatan, jalankan a DELETE FROM YourDB.dbo.tblYourTable.

    • Anda tidak dapat memotong data ketika kunci asing ada sehingga Anda harus menggunakan DELETE.
  3. Jalankan ini di server tujuan Anda: USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all';

  4. Klik kanan pada YourDB di Object Explorer. Klik Tasks->Import Data...

  5. Beberapa layar pertama dari wizard cukup jelas.

  6. Pada Select Source Table and Viewslayar wizard, klik kotak centang di sebelah setiap tabel yang ingin Anda salin.

  7. Untuk setiap baris (tabel) pada layar itu, klik di atasnya sehingga itu disorot lalu klik Edit Mappings.

  8. Untuk setiap baris (tabel), klik / centang Append rows to the destination tabledan Enable identity insert.

    • Jika Anda mengkliknya Delete rows in destination tableakan gagal karena itu tidak mengeluarkan DELETEperintah, itu mengeluarkan TRUNCATEperintah yang masih bertentangan dengan kunci asing kami karena TRUNCATEtidak diatur oleh NOCHECK CONSTRAINTdari sebelumnya.
  9. Klik melalui sisa wizard dan klik Finish.

  10. Perhatikan kesalahan ; peringatan mungkin ok untuk diabaikan.

    • Jika ada kesalahan, klik Reporttombol dan lihat laporan. Cobalah dan memcahkan apa adalah Success, Error, dan Stopped. Anda mungkin harus memperbaiki apa pun yang menjadi akar penyebab kesalahan yang terkubur dalam laporan itu di suatu tempat. Maka, Anda mungkin perlu melakukan DELETE FROM YourDB.dbo.theErrorTable. Sekarang klik tombol kembali pada panduan impor dan hapus centang setiap tabel yang a Success. Ulangi tak terhingga iklan.
  11. Jalankan ini di server tujuan Anda: USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all';

    • Jika ada kesalahan, ... Saya tidak tahu, tetapi perbaiki dan coba lagi!
  12. Yay! :)

Terima kasih kepada semua orang yang menjawab pertanyaan ini dan pertanyaan yang serupa dengan ini di jaringan SE untuk membantu saya mencari tahu ini.

Zach Mierzejewski
sumber
Anda adalah penyelamat hidup
Tom Gullen
1
Terima kasih banyak, punya cadangan di drive yang rusak, tidak bisa menyalin DB di mana saja (kesalahan i / o). Mengimpor data beberapa tabel sekaligus dengan cara ini membantu saya memulihkan 99% dari itu.
Tom Gullen
1
Kamu keren! Perintah lain yang membantu saya: EXEC sp_msforeachtable 'delete from? '; Jika kesalahan terjadi hapus semuanya adalah hukum. Skrip sp_msforeachtable ada di sini gist.githubusercontent.com/metaskills/893599/raw/…
Sanchitos
4

Di panduan impor, Anda dapat menghapus baris terlebih dahulu dan jika Anda memiliki bidang identitas, maka Anda dapat mengaktifkan sisipan identitas seperti di bawah ini

masukkan deskripsi gambar di sini

Jika Anda ingin menonaktifkan periksa kendala, maka ketika wisaya meminta Anda untuk menyimpan paket, simpan paket lalu edit koneksi manajer seperti di bawah ini:

masukkan deskripsi gambar di sini

Catatan: Anda tidak dapat TRUNCATE tabel ketika ada Kunci Asing yang ditentukan.

Kin Shah
sumber
3

Jangan jatuhkan kendala.

Yang harus Anda lakukan adalah menyimpan paket SSIS yang dibuat oleh wizard, lalu mengeditnya di BIDS / SSDT. Ketika Anda mengedit paket Anda akan dapat mengontrol urutan tabel diproses sehingga Anda dapat memproses tabel induk kemudian memproses tabel anak ketika semua tabel induk selesai.

mrdenny
sumber
3
Itu tidak benar-benar efisien juga, itu akan memakan waktu hampir satu jam sekarang untuk memodifikasi paket untuk memastikan semuanya dalam urutan yang benar, dan bahkan kemudian saya tidak bisa memastikan. Ini akan mendapatkan lebih banyak kesulitan karena DB tumbuh dan melakukannya setiap saat, tidak, terima kasih. Harus ada cara sederhana untuk melakukan ini.
1

Masalah seperti ini menunjukkan kepada kita bahwa orang-orang yang membuat SQL server tidak pernah benar-benar menggunakan produk mereka. Ini adalah kelalaian yang mencolok sehingga orang harus bertanya-tanya apa lagi yang mereka lupa lakukan dengan benar (saya punya daftar sekitar 30 masalah menjengkelkan lainnya seperti ini yang harus saya atasi untuk membuat pekerjaan ini seperti yang dilakukan oleh DB lainnya. kotak, termasuk fakta bahwa kita memerlukan penyihir yang buruk untuk melakukan ini di tempat pertama [jika saya punya waktu saya menghabiskan menunggu penyihir ini untuk menghubungkan dan menghitung tabel yang sama untuk DB yang sama, setiap kali, kembali ... Saya punya waktu untuk liburan yang menyenangkan]).

Saya sangat malas dan tidak mau mengetik EXEC sp_msforeachtable ...dua kali setiap kali saya melakukan ini. Pekerjaan saya adalah meninggalkan kendala pada server produksi dan menghapusnya dari server dev. Ini akan mencegah kesalahan tetapi metode ini memiliki beberapa efek samping SANGAT BESAR. Pertama, Anda tidak akan lagi bisa mengembalikan cadangan penuh ke server dev Anda (kecuali Anda tidak perlu menghapus semuanya lagi). Kedua, ini bekerja paling baik ketika Anda yakin bahwa konsumen data Anda juga menegakkan batasan-batasan ini (atau tidak peduli dengan mereka). Dalam kasus saya, kami hanya memiliki satu konsumen (situs web kami) sehingga kami telah membuat batasan ini ke dalam kode situs juga (yaitu sebelum kami menghapus catatan pengguna, kami menghapus semua catatan telepon untuk pengguna itu terlebih dahulu). Iya, ini pada dasarnya meniadakan perlunya kendala di tempat pertama dan menggandakan pekerjaan yang harus saya lakukan tetapi juga memberi saya kesempatan untuk memverifikasi bahwa kode saya bekerja dengan atau tanpa kendala berbasis DBMS (kenyataannya adalah bahwa mereka masih di prod server hanya sebagai rencana kontingensi). Anda bisa menyebutnya cacat dalam desain saya, tetapi saya lebih suka menyebutnya solusi untuk DBMS yang cacat. Bagaimanapun, itu masih lebih cepat dan lebih mudah untuk melakukan ini di tempat lain daripada dari dalam MSSQL karena tidak dapat mengatasi desain itu sendiri.

krowe2
sumber
0

Saya pikir Anda tidak dapat melakukan backup dan restore dari server produksi karena ini adalah data penting. Yah tanpa hak yang tepat itu benar-benar menjadi lebih rumit. Tetapi jika Anda memiliki cadangan db dan mengembalikan tepat maka Anda dapat melakukannya.

Atau yang lain, Salah satu cara yang saya sarankan adalah untuk menghapus semua kendala dan indeks Anda dan kemudian menambahkannya lagi setelah data telah diimpor atau diekspor.

Bukan jawaban yang pasti tetapi akan diproses dengan cepat.

pengguna2404431
sumber
Terima kasih, tetapi saya secara khusus mengatakan saya tidak ingin skrip drop / buat skrip kendala.
0

Baca saja topik itu. Ini adalah posting lama tetapi di sini adalah apa yang saya lakukan untuk membantu orang-orang di masa depan membaca ini.

Dalam kasus saya, saya ingin mengimpor ke tabel identik yang kosong. Saat mengedit pemetaan, saya memilih <ignore>untuk kunci utama. Semua konten saya ditambahkan secara otomatis dengan baik.

Semoga ini bisa membantu seseorang

Greg
sumber
1
Abaikan kunci utama akan membantu dengan kunci asing?
dezso
Dalam kasus saya ya karena saya benar-benar menduplikasi tabel. Jadi saya akhiri dengan kunci primer yang sama. Jadi kunci asing yang menunjuk ke meja saya masih sesuai dengan entri yang benar
Greg