Jak radzić sobie z ograniczeniami FK podczas importowania danych za pomocą Kreatora importu / eksportu DTS?

16

Próbuję użyć Kreatora importu i eksportu programu SQL Server, aby skopiować dane z mojej produkcyjnej bazy danych do mojej bazy danych deweloperów, ale gdy to robię, kończy się niepowodzeniem z błędem „STATUS INSERT jest w konflikcie z ograniczeniem klucza OBCEGO” mam ponad 40 tabel z partiami z ograniczeniami FK, czy jest jakiś prosty sposób poradzić sobie z tym bez konieczności pisania ograniczenia upuszczania / dodawania skryptu constrat?

Edycja: Właśnie dowiedziałem się, że w internetowej wersji SQL Server, którą właśnie uruchamiam, DTS nie pozwoli ci zapisywać pakietów.


źródło

Odpowiedzi:

28

Dostałem to rozwiązanie na stronie SQLTeam.com:

Posługiwać się:

 EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'

Następnie zaimportuj dane

EXEC sp_msforeachtable 'ALTER TABLE ? CHECK CONSTRAINT all'

Dzięki tej metodzie bez problemu mogłem zaimportować wszystkie dane.

Paul White 9
źródło
1
sp_msforeachtable(i sp_MSForEachDb) jest nieudokumentowane i nie jest obsługiwane. Nie powinieneś / należy go używać. Może pominąć tabele !! Zobacz ten post z @AaronBertrand -> sqlblog.com/blogs/aaron_bertrand/archive/2010/12/29/... i ten element połączenia - (MS wskazujące, że go nie naprawią) -> connect.microsoft.com/SQLServer / feedback / details / 264677 /…
Kin Shah,
Działa dla mnie doskonale po wielu godzinach pracy nad mózgiem, próbując ominąć ograniczenia FK dotyczące eksportu danych.
levininja
Działając na Azure SQL 12, pojawia się błąd „Nie można znaleźć procedury przechowywanej„ sp_msforeachtachtable ”.”
Dai
W każdym razie nie działa: /
Douglas Gaskell,
Jesteś człowiekiem
ratującym
5

Stworzyłem dokładną kopię bazy danych na moim komputerze z serwera, którego nie kontrolowałem.

Jestem dupkiem , ale to właśnie zrobiłem:

  1. Utworzyłem DB z mojego skryptu, który był w kontroli źródła (podpowiedź, podpowiedź!) Jeśli nie masz skryptu, zawsze możesz wygenerować go z istniejącego DB za pomocą Tasksopcji.

  2. Jeśli jakieś dane zostały automatycznie wstawione do YourDB podczas tworzenia, uruchom DELETE FROM YourDB.dbo.tblYourTable.

    • Nie można obciąć danych, gdy istnieją klucze obce, więc musisz ich użyć DELETE.
  3. Uruchom to na serwerze docelowym: USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all';

  4. Kliknij prawym przyciskiem myszy YourDB w Object Explorer. Kliknij Tasks->Import Data...

  5. Kilka pierwszych ekranów kreatora jest zrozumiałych.

  6. Na Select Source Table and Viewsekranie kreatora kliknij pole wyboru obok każdej tabeli, którą chcesz skopiować.

  7. Dla każdego wiersza (tabeli) na tym ekranie kliknij go, aby był podświetlony, a następnie kliknij Edit Mappings.

  8. Dla każdego wiersza (tabeli) kliknij / sprawdź Append rows to the destination tablei Enable identity insert.

    • Jeśli klikniesz Delete rows in destination table, zakończy się niepowodzeniem, ponieważ nie wydaje DELETEpolecenia, wydaje TRUNCATEpolecenie, które nadal jest w konflikcie z naszymi kluczami obcymi, ponieważ TRUNCATEnie jest rządzone NOCHECK CONSTRAINTwcześniej.
  9. Kliknij resztę kreatora i kliknij Finish.

  10. Uważaj na błędy ; ostrzeżenia prawdopodobnie można zignorować.

    • Jeśli wystąpią błędy, kliknij Reportprzycisk i wyświetl raport. Spróbuj i rozpracować co było Success, Errori Stopped. Prawdopodobnie będziesz musiał naprawić przyczynę błędu, który został ukryty gdzieś w tym raporcie. Wtedy prawdopodobnie będziesz musiał zrobić DELETE FROM YourDB.dbo.theErrorTable. Teraz kliknij przycisk Wstecz w kreatorze importu i odznacz każdą tabelę, która była Success. Powtórz ad infinitum.
  11. Uruchom to na serwerze docelowym: USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all';

    • Jeśli wystąpią błędy ... Nie wiem, ale napraw je i spróbuj ponownie!
  12. Tak! :)

Dziękuję wszystkim, którzy odpowiedzieli na to pytanie i pytania podobne do tego w sieci SE za pomoc w zrozumieniu tego.

Zach Mierzejewski
źródło
Ratujesz życie
Tom Gullen
1
Poważnie dziękuję bardzo, miałem kopię zapasową na uszkodzonym dysku, nie mogłem skopiować bazy danych nigdzie (błąd we / wy). Importowanie danych kilka tabel jednocześnie w ten sposób pomogło mi odzyskać 99% z nich.
Tom Gullen,
1
Rządzisz! Kolejne polecenie, które mi pomogło: EXEC sp_msforeachtable 'usunąć z? „; Jeśli wystąpi błąd, usuń wszystko zgodnie z prawem. sp_msforeachtable skryptu jest tutaj gist.githubusercontent.com/metaskills/893599/raw/…
Sanchitos
4

W kreatorze importu możesz najpierw usunąć wiersze, a jeśli masz pola tożsamości, możesz włączyć wstawianie tożsamości jak poniżej

wprowadź opis zdjęcia tutaj

Jeśli chcesz wyłączyć ograniczenie sprawdzania, wtedy gdy kreator poprosi o zapisanie pakietu, zapisz go, a następnie edytuj menedżera połączeń, jak poniżej:

wprowadź opis zdjęcia tutaj

Uwaga: Nie można TRUNCATE tabeli, jeśli zdefiniowano klucze obce.

Kin Shah
źródło
3

Nie usuwaj ograniczeń.

Co należy zrobić, to zapisać pakiet SSIS utworzony przez kreatora, a następnie edytować go w BIDS / SSDT. Podczas edycji pakietu będziesz mógł kontrolować kolejność przetwarzania tabel, dzięki czemu możesz przetwarzać tabele nadrzędne, a następnie przetwarzać tabele podrzędne, gdy wszystkie tabele nadrzędne są gotowe.

mrdenny
źródło
3
To też nie jest naprawdę skuteczne, modyfikacja pakietu zajęłaby teraz prawie godzinę, aby upewnić się, że wszystko jest w odpowiedniej kolejności, a nawet wtedy nie mogę być pewien. Byłoby to bardziej kłopotliwe, gdy DB rośnie i robienie tego za każdym razem, nie, dziękuję. Musi istnieć prosty sposób na zrobienie tego.
1

Problemy takie jak ten pokazują nam, że ludzie tworzący serwer SQL nigdy tak naprawdę nie używali swojego produktu. Jest to tak rażące pominięcie, że trzeba się zastanawiać, co jeszcze po prostu zapomnieli zrobić poprawnie (mam listę około 30 innych irytujących problemów takich jak ten, które musiałem przezwyciężyć, aby działały tak, jak robią to inni DB pudełka; w tym fakt, że potrzebujemy kiepskiego kreatora, aby to zrobić w pierwszej kolejności [gdybym miał czas, który czekałem, aż ten kreator połączy się i wyliczy te same tabele dla tego samego DB, za każdym razem, z powrotem ... miałbym czas na fajne wakacje]).

Jestem bardzo leniwy i nie chcę pisać EXEC sp_msforeachtable ...dwa razy za każdym razem, gdy to robię. Moje zadanie polegało na pozostawieniu ograniczeń na serwerze produkcyjnym i usunięciu ich z serwera deweloperskiego. Zapobiegnie to błędowi, ale ta metoda ma kilka BARDZO DUŻYCH skutków ubocznych. Po pierwsze, nie będziesz już mógł przywrócić pełnej kopii zapasowej do serwera programistów (chyba że wszystko w porządku, aby usunąć je wszystkie ponownie). Po drugie, działa to najlepiej, gdy masz pewność, że konsumenci twoich danych również egzekwują te ograniczenia (lub nie przejmują się nimi). W moim przypadku mamy tylko jednego konsumenta (naszą stronę internetową), więc wbudowaliśmy te ograniczenia również w kod witryny (tj. Przed usunięciem rekordu użytkownika najpierw usuwamy wszystkie rekordy telefonu dla tego użytkownika). Tak, to przede wszystkim neguje potrzebę ograniczeń i podwaja pracę, którą muszę wykonać, ale daje mi również szansę sprawdzenia, czy mój kod działa z ograniczeniami opartymi na DBMS lub bez nich (faktem jest, że nadal są one w wersji pro serwer tylko jako plan awaryjny). Można to nazwać wadą w moim projekcie, ale wolę nazwać to obejściem wadliwego DBMS. W każdym razie nadal jest to szybsze i łatwiejsze do zrobienia w dowolnym miejscu niż z poziomu MSSQL, ponieważ nie jest w stanie poradzić sobie z własnym projektem.

krowe2
źródło
0

Myślę, że nie można wykonać kopii zapasowej i przywracania z serwera produkcyjnego, ponieważ są to kluczowe dane. Cóż, bez odpowiednich praw, to naprawdę staje się bardziej skomplikowane. Ale jeśli masz kopię zapasową bazy danych n przywracania, możesz ją wykonać.

Innym sposobem, który zaleciłbym, jest usunięcie wszystkich ograniczeń i indeksów, a następnie dodanie ich ponownie po zaimportowaniu lub wyeksportowaniu danych.

Nie jest to dokładna odpowiedź, ale szybko się przetworzy.

użytkownik2404431
źródło
Dzięki, ale konkretnie powiedziałem, że nie chcę tworzyć skryptów upuszczania / tworzenia skryptów ograniczających.
0

Po prostu przeczytaj ten temat. To stary post, ale oto, co zrobiłem, aby pomóc przyszłym ludziom w czytaniu tego.

W moim przypadku chciałem zaimportować do pustej identycznej tabeli. Podczas edycji mapowania wybieram <ignore>klucz podstawowy. Cała moja treść jest automatycznie ładnie dodawana.

Mam nadzieję, że to komuś pomoże

Greg
źródło
1
Zignorować klucz podstawowy pomógłby z kluczami obcymi?
dezso,
W moim przypadku tak, ponieważ w rzeczywistości kopiowałem stół. Więc skończyłem z tymi samymi kluczami podstawowymi. Tak więc klucze obce wskazujące na mój stół nadal odpowiadają poprawnemu wpisowi
Greg