Angenommen, ich besitze Tabelle A und Tabelle B. Tabelle B verweist auf Tabelle A. Ich möchte eine Reihe von Zeilen in Tabelle A und Tabelle B tiefkopieren. Ich möchte, dass alle neuen Tabelle B-Zeilen auf die neuen Zeilen von Tabelle A verweisen .
Beachten Sie, dass ich die Zeilen nicht in andere Tabellen kopiere. Die Zeilen in Tabelle A werden in Tabelle A kopiert, und die Zeilen in Tabelle B werden in Tabelle B kopiert.
Wie kann ich sicherstellen, dass die Fremdschlüsselreferenzen als Teil der Kopie nachjustiert werden?
Um zu verdeutlichen, versuche ich einen generischen Weg zu finden, dies zu tun. Das Beispiel, das ich gebe, beinhaltet zwei Tabellen, aber in der Praxis kann das Abhängigkeitsdiagramm viel komplizierter sein. Selbst eine generische Art, SQL dynamisch zu generieren, um die Arbeit zu erledigen, wäre in Ordnung.
UPDATE:
Die Leute fragen, warum das nötig ist, also werde ich etwas Hintergrund geben. Es mag viel zu viel sein, aber hier geht es:
Ich arbeite mit einer alten Desktop-Anwendung, die auf ein Client-Server-Modell verschoben wurde. Aber die Anwendung verwendet immer noch ein rudimentäres internes Binärdateiformat zum Speichern von Daten für ihre Tabellen. Eine Datendatei ist nur eine Kopfzeile, gefolgt von einer Reihe von Zeilen, von denen jede nur die binären serialisierten Feldwerte darstellt, deren Reihenfolge durch eine Schemadatei bestimmt wird. Das einzig Gute daran ist, dass es sehr schnell ist. Es ist schrecklich in jeder anderen Hinsicht. Ich verschiebe die Anwendung zu SQL Server und versuche, die Leistung nicht zu sehr zu verschlechtern.
Dies ist eine Art von Zeitplanungsanwendung; Die Daten sind für niemanden kritisch, und es ist kein Audit-Tracking usw. erforderlich. Es ist keine supermassive Menge an Daten, und wir müssen nicht unbedingt sehr alte Daten herumtragen, wenn die Datenbank zu groß wird.
Eine Funktion, an die sie gewöhnt sind, ist die Fähigkeit, ganze Zeitpläne zu duplizieren, um "Was-wäre-wenn" -Szenarien zu erstellen, mit denen sie sich beschäftigen können. Jeder Benutzer kann das so oft machen, wie er möchte, so oft er möchte. In der alten Datenbank werden die Datendateien für jeden Zeitplan in einem eigenen Datenordner gespeichert, der durch den Namen identifiziert wird. Das Kopieren eines Zeitplans war also so einfach wie das Kopieren und Umbenennen des Datenordners.
Ich muss in der Lage sein, dasselbe mit SQL Server zu tun oder die Migration funktioniert nicht. Vielleicht denkst du, dass ich nur die Daten kopieren kann, die tatsächlich geändert werden, um Redundanz zu vermeiden; aber das klingt ehrlich zu kompliziert, um machbar zu sein.
Um einen weiteren Schraubenschlüssel in die Mischung zu werfen, kann es eine Hierarchie von Zeitplandatenordnern geben. Ein Datenordner kann also einen Datenordner enthalten, der einen Datenordner enthalten kann. Und das Kopieren kann auf jeder Ebene erfolgen.
In SQL Server implementiere ich eine geschachtelte Mengenhierarchie, um dies nachzuahmen. Ich habe eine DATA_SET-Tabelle wie folgt:
%Vor%Also, es gibt eine Baumstruktur von Datensätzen. Jeder Datensatz stellt einen Zeitplan dar und kann untergeordnete Datensätze enthalten. Jede Zeile in jeder Tabelle hat eine DATA_SET_ID FK-Referenz, die angibt, zu welchem Datensatz sie gehört. Wenn ich einen Datensatz kopiere, kopiere ich alle Zeilen in der Tabelle für diesen Datensatz und jeden zweiten Datensatz in die gleiche Tabelle, verweise aber auf neue Datensätze.
Also, hier ist ein einfaches konkretes Beispiel:
%Vor%Nehmen wir an, ich kopiere Datensatz 1 in einen neuen Datensatz von ID 2. Nach dem Kopieren sehen die Tabellen wie folgt aus:
%Vor%Wie Sie sehen können, verweisen die neuen BAR-Zeilen auf die neuen FOO-Zeilen. Es ist nicht die Umverdrahtung der DATA_SET_IDs, nach denen ich frage. Ich frage nach der Neuverschlüsselung der Fremdschlüssel im Allgemeinen.
Also, das war sicher zu viel Information, aber da gehst du.
Ich bin mir sicher, dass es bei der Idee, die Daten so zu kopieren, viele Bedenken gibt. Die Tische werden nicht riesig sein. Ich erwarte in keiner Tabelle mehr als 1000 Datensätze, und die meisten Tabellen werden viel kleiner sein. Alte Datensätze können sofort und ohne Auswirkungen gelöscht werden.
Danke, Tedderz
Ich musste kürzlich ein ähnliches Problem lösen. das heißt, ich musste eine Reihe von Zeilen in einer Tabelle (Tabelle A) sowie alle Zeilen in verknüpften Tabellen kopieren, deren Fremdschlüssel auf den Primärschlüssel von Tabelle A zeigen. Ich habe Postgres verwendet, so dass die genauen Abfragen abweichen können, aber der Gesamtansatz ist der gleiche. Der größte Vorteil dieses Ansatzes besteht darin, dass er rekursiv verwendet werden kann, um unendlich tief zu gehen
TLDR: Der Ansatz sieht so aus
%Vor%1) Der erste Schritt besteht darin, das Informationsschema abzufragen, um alle Tabellen und Spalten zu finden, die auf Tabelle A verweisen. In Postgres könnte dies wie folgt aussehen:
%Vor%2) Als nächstes müssen wir die Daten aus Tabelle A kopieren, und alle anderen Tabellen, die auf Tabelle A verweisen, können sagen, dass es eine Tabelle B gibt. Um diesen Prozess zu starten, erstellen wir eine temporäre Tabelle für jede dieser Tabellen und Wir werden es mit den Daten füllen, die wir kopieren müssen. Dies könnte wie folgt aussehen:
%Vor%3) Wir können jetzt eine Funktion definieren, die Primärschlüssel-Spaltenaktualisierungen auf verwandte Fremdschlüsselspalten kaskadiert und die bei jeder Änderung der Primärschlüsselspalte ausgelöst werden. Zum Beispiel:
%Vor%4) Jetzt aktualisieren wir einfach die Primärschlüsselspalte auf den nächsten Wert der Sequenz der Quelltabelle (). Dadurch wird der Trigger aktiviert und die Aktualisierungen werden in die Spalten des Fremdschlüssels in kaskadiert. In Postgres können Sie Folgendes tun:
%Vor%5) Fügen Sie die Daten aus den temporären Tabellen zurück in die Quellentabellen ein. Und dann die temporären Tabellen, Trigger und Funktionen löschen.
%Vor%Es ist möglich, diesen allgemeinen Ansatz zu verwenden und ihn in ein Skript umzuwandeln, das rekursiv aufgerufen werden kann, um unendlich tief zu gehen. Ich habe genau das mit Python gemacht (unsere Anwendung verwendete django, also war ich in der Lage, das django ORM zu benutzen, um das etwas einfacher zu machen)
Tags und Links sql sql-server database sql-server-2008