Wie gehe ich mit FK-Einschränkungen um, wenn ich Daten mit dem DTS-Import / Export-Assistenten importiere?


16

Ich versuche, den SQL Server-Import- und -Export-Assistenten zu verwenden, um Daten von meiner Produktionsdatenbank auf meine Entwicklungsdatenbank zu kopieren, aber wenn ich dies tue, schlägt der Fehler "Die INSERT-Anweisung ist mit der FOREIGN KEY-Einschränkung in Konflikt" fehl. Ich habe über 40 Tabellen mit Lots Gibt es eine einfache Möglichkeit, mit FK-Einschränkungen umzugehen, ohne ein Drop-Einschränkungs- / Add-Constrat-Skript schreiben zu müssen?

Bearbeiten: Ich habe gerade herausgefunden, dass in der Web-Edition von SQL Server, die ich ausführe, DTS nicht zulässt, dass Sie Pakete speichern.

Antworten:


28

Ich habe diese Lösung bei SQLTeam.com erhalten:

Verwenden:

 EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'

Dann importieren Sie Ihre Daten

EXEC sp_msforeachtable 'ALTER TABLE ? CHECK CONSTRAINT all'

Mit dieser Methode konnte ich alle Daten problemlos importieren.


1
sp_msforeachtable(und sp_MSForEachDb) ist undokumentiert und wird nicht unterstützt. Sie sollten es nicht / vermeiden. Es könnte die Tabellen überspringen !! Siehe diesen Beitrag von @AaronBertrand -> sqlblog.com/blogs/aaron_bertrand/archive/2010/12/29/… und dieses Verbindungselement - (MS zeigt an, dass es nicht behoben werden
Kin Shah

Arbeitete perfekt für mich, nachdem ich stundenlang versucht hatte, die FK-Einschränkungen für einen Datenexport zu umgehen.
Levininja

Unter Azure SQL V12 wird die Fehlermeldung "Die gespeicherte Prozedur 'sp_msforeachtable' konnte nicht gefunden werden."
Dai

Funktioniert sowieso nicht: /
Douglas Gaskell

Du bist der Lebensretter
Can Sahin

5

Ich habe auf meinem Computer eine exakte Kopie einer Datenbank von einem Server erstellt, den ich nicht kontrollierte.

Ich bin ein Trottel , aber das habe ich getan:

  1. Erstellt die Datenbank aus meinem Skript, das sich in der Quellcodeverwaltung befand (Hinweis, Hinweis!). Wenn Sie das Skript nicht haben, können Sie es immer aus der vorhandenen Datenbank über die TasksOption generieren .

  2. Wenn bei der Erstellung automatisch Daten in YourDB eingefügt wurden , führen Sie a DELETE FROM YourDB.dbo.tblYourTable.

    • Sie können keine Daten abschneiden, wenn Fremdschlüssel vorhanden sind, sodass Sie diese verwenden müssen DELETE.
  3. Führen Sie dies auf Ihrem Zielserver aus: USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all';

  4. Klicken Sie mit der rechten Maustaste auf YourDB in Object Explorer. Klicken Sie auf Tasks->Import Data...

  5. Die ersten Bildschirme des Assistenten sind selbsterklärend.

  6. Aktivieren Sie auf dem Select Source Table and ViewsBildschirm des Assistenten das Kontrollkästchen neben jeder Tabelle, die Sie kopieren möchten.

  7. Klicken Sie für jede Zeile (Tabelle) auf diesem Bildschirm darauf, damit sie hervorgehoben wird, und klicken Sie dann auf Edit Mappings.

  8. Klicken Sie für jede Zeile (Tabelle) auf / Häkchen Append rows to the destination tableund Enable identity insert.

    • Wenn Sie auf klicken Delete rows in destination table, schlägt dies fehl, da kein DELETEBefehl ausgegeben wird. Es wird ein Befehl TRUNCATEausgegeben, der immer noch mit unseren Fremdschlüsseln in Konflikt steht, da er TRUNCATEnicht von den NOCHECK CONSTRAINTfrüheren gesteuert wird .
  9. Klicken Sie sich durch den Rest des Assistenten und klicken Sie auf Finish.

  10. Achten Sie auf Fehler . Warnungen können wahrscheinlich ignoriert werden.

    • Wenn Fehler auftreten, klicken Sie auf die ReportSchaltfläche und zeigen Sie den Bericht an. Versuchen Sie, und abtasten , was war Success, Errorund Stopped. Möglicherweise müssen Sie die Ursache des Fehlers beheben, der in diesem Bericht enthalten ist. Dann müssen Sie wahrscheinlich eine DELETE FROM YourDB.dbo.theErrorTable. Klicken Sie nun im Import-Assistenten auf die Schaltfläche "Zurück" und deaktivieren Sie alle Tabellen, bei denen es sich um a handelte Success. Wiederholen Sie ad infinitum.
  11. Führen Sie dies auf Ihrem Zielserver aus: USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all';

    • Wenn es Fehler gibt, ... Ich weiß es nicht, aber behebe sie und versuche es erneut!
  12. Yay! :)

Vielen Dank an alle, die diese und ähnliche Fragen im SE-Netzwerk beantwortet haben, die mir dabei geholfen haben, dies herauszufinden.


Sie sind ein Lebensretter
Tom Gullen

1
Im Ernst, vielen Dank, hatte ein Backup auf einem beschädigten Laufwerk, konnte die DB nirgendwo kopieren (I / O-Fehler). Durch das gleichzeitige Importieren einiger Tabellen konnte ich 99% der Daten wiederherstellen.
Tom Gullen

1
Du rockst! Ein weiterer Befehl, der mir geholfen hat: EXEC sp_msforeachtable 'Löschen von? '; Wenn ein Fehler auftritt, löschen Sie alles, was dem Gesetz entspricht. Das sp_msforeachtable-Skript ist hier gist.githubusercontent.com/metaskills/893599/raw/…
Sanchitos

4

Im Importassistenten können Sie zuerst die Zeilen löschen. Wenn Sie über Identitätsfelder verfügen, können Sie das Einfügen von Identitäten wie folgt aktivieren

Bildbeschreibung hier eingeben

Wenn Sie die Prüfungseinschränkung deaktivieren möchten, speichern Sie das Paket, wenn Sie vom Assistenten aufgefordert werden, es zu speichern, und bearbeiten Sie den Verbindungsmanager wie folgt:

Bildbeschreibung hier eingeben

Hinweis: Sie können die Tabelle nicht TRUNCATE, wenn Fremdschlüssel definiert sind.


3

Lass die Einschränkungen nicht fallen.

Speichern Sie das vom Assistenten erstellte SSIS-Paket und bearbeiten Sie es in BIDS / SSDT. Wenn Sie das Paket bearbeiten, können Sie die Reihenfolge steuern, in der die Tabellen verarbeitet werden, sodass Sie die übergeordneten Tabellen verarbeiten können. Anschließend können Sie die untergeordneten Tabellen verarbeiten, wenn alle übergeordneten Tabellen fertig sind.


3
Das ist auch nicht wirklich effektiv, es würde jetzt fast eine Stunde dauern, um das Paket zu modifizieren, um sicherzustellen, dass alles in der richtigen Reihenfolge ist, und selbst dann kann ich nicht sicher sein. Dies würde umständlicher werden, wenn die DB wächst und dies jedes Mal tun würde, nein, danke. Es muss einen einfachen Weg geben, dies zu tun.

1

Probleme wie dieses zeigen uns, dass die Leute, die SQL Server herstellen, ihr Produkt noch nie benutzt haben. Dies ist eine so krasse Lücke, dass man sich fragen muss, was sie einfach vergessen haben, um es richtig zu machen (ich habe eine Liste von ungefähr 30 anderen verrückten Problemen wie diesen, die ich überwinden musste, um diese Arbeit so zu machen, wie andere DBs es tun) der Box, einschließlich der Tatsache, dass wir einen miesen Assistenten benötigen, um dies zu tun [wenn ich die Zeit hatte, die ich darauf gewartet habe, dass dieser Assistent jedes Mal die gleichen Tabellen für dieselbe DB verbindet und auflistet, zurück ... Ich hätte Zeit für einen schönen Urlaub]).

Ich bin sehr faul und möchte nicht tippen EXEC sp_msforeachtable ...zweimal jedes Mal, wenn ich das tue. Meine Aufgabe bestand darin, die Einschränkungen auf dem Produktionsserver zu belassen und sie vom Entwicklungsserver zu entfernen. Dies verhindert den Fehler, aber diese Methode hat einige SEHR GROSSE Nebenwirkungen. Erstens können Sie nicht mehr nur eine vollständige Sicherung auf Ihrem Entwicklungsserver wiederherstellen (es sei denn, Sie sind in der Lage, sie alle wieder zu entfernen). Zweitens funktioniert dies am besten, wenn Sie sicher sind, dass die Konsumenten Ihrer Daten diese Einschränkungen auch durchsetzen (oder sich nicht darum kümmern). In meinem Fall haben wir nur einen Verbraucher (unsere Website), daher haben wir diese Einschränkungen auch in den Site-Code integriert (dh bevor wir einen Benutzerdatensatz löschen, löschen wir zuerst alle Telefondatensätze für diesen Benutzer). Ja, Dies macht Einschränkungen in erster Linie überflüssig und verdoppelt die Arbeit, die ich zu erledigen habe, gibt mir aber auch die Möglichkeit zu überprüfen, ob mein Code mit oder ohne DBMS-basierte Einschränkungen funktioniert (Tatsache ist, dass sie sich noch auf dem Produkt befinden) Server nur als Notfallplan). Sie könnten dies als einen Fehler in meinem Design bezeichnen, aber ich würde es lieber als Problemumgehung für ein fehlerhaftes DBMS bezeichnen. In jedem Fall ist dies immer noch schneller und einfacher als in MSSQL, da es nicht in der Lage ist, mit seinem eigenen Design fertig zu werden.


0

Ich denke, Sie können keine Sicherung und Wiederherstellung vom Produktionsserver durchführen, da es sich um wichtige Daten handelt. Nun, ohne die richtigen Rechte wird es wirklich komplizierter. Aber wenn Sie db backup n restore richtig haben, können Sie es ausführen.

Eine Möglichkeit, die ich jedoch empfehlen würde, besteht darin, alle Ihre Einschränkungen und Indizes zu löschen und sie dann erneut hinzuzufügen, sobald die Daten importiert oder exportiert wurden.

Keine genaue Antwort, wird aber schnell verarbeitet.


Danke, aber ich habe ausdrücklich gesagt, dass ich kein Drop / Create-Constraint-Skript ausführen möchte.

0

Lies einfach dieses Thema. Es ist ein alter Beitrag, aber hier ist, was ich getan habe, um zukünftigen Leuten beim Lesen zu helfen.

In meinem Fall wollte ich in eine leere identische Tabelle importieren. Beim Bearbeiten des Mappings wähle ich <ignore>als Primärschlüssel. Alle meine Inhalte werden automatisch hinzugefügt.

Hoffe es hilft jemandem


1
Primärschlüssel ignorieren würde bei Fremdschlüsseln helfen?
Dezso

In meinem Fall ja, da ich tatsächlich eine Tabelle dupliziert habe. Also endete ich mit denselben Primärschlüsseln. Aus diesem Grund entsprechen Fremdschlüssel, die auf meinen Tisch zeigen, immer noch dem korrekten Eintrag
Greg
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.