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.Wie kann ich eine Datenmenge tief kopieren und FK-Referenzen so ändern, dass sie auf alle Kopien zeigen?
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 neu ausgerichtet werden?
Um zu klären, ich versuche, eine generische Möglichkeit 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 dies notwendig ist, also werde ich einige Hintergrundinformationen geben. Es kann viel zu viel sein, aber hier geht:
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 ist, 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 Scheduling-Anwendung; 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, die sie gewohnt sind, ist die Fähigkeit, komplette 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 anhand seines Namens identifiziert wird. Das Kopieren eines Zeitplans war also so einfach wie das Kopieren des Datenordners und das Umbenennen.
I muss in der Lage, die gleiche Sache mit SQL Server effektiv zu tun oder die Migration wird nicht funktionieren. 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 den Mix 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:
CREATE TABLE dbo.DATA_SET
(
DATA_SET_ID UNIQUEIDENTIFIER PRIMARY KEY,
NAME NVARCHAR(128) NOT NULL,
LFT INT NOT NULL,
RGT INT NOT NULL
)
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, aber referenziere neue Datensätze.
So, hier ist ein einfaches konkretes Beispiel:
CREATE TABLE FOO
(
FOO_ID BIGINT PRIMARY KEY,
DATA_SET_ID BIGINT FOREIGN KEY REFERENCES DATA_SET(DATA_SET_ID) NOT NULL
)
CREATE TABLE BAR
(
BAR_ID BIGINT PRIMARY KEY,
DATA_SET_ID BIGINT FOREIGN KEY REFERENCES DATA_SET(DATA_SET_ID) NOT NULL,
FOO_ID UNIQUEIDENTIFIER PRIMARY KEY
)
INSERT INTO FOO
SELECT 1, 1 UNION ALL
SELECT 2, 1 UNION ALL
SELECT 3, 1 UNION ALL
INSERT INTO BAR
SELECT 1, 1, 1
SELECT 2, 1, 2
SELECT 3, 1, 3
So lassen Sie uns sagen, dass ich Daten 1 in einen neuen Datensatz von ID gesetzt kopieren 2. Nachdem ich kopieren, werden die Tabellen wie folgt aussehen:
FOO
FOO_ID, DATA_SET_ID
1 1
2 1
3 1
4 2
5 2
6 2
BAR
BAR_ID, DATA_SET_ID, FOO_ID
1 1 1
2 1 2
3 1 3
4 2 4
5 2 5
6 2 6
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 gehts los.
Ich bin sicher, es gibt viele Bedenken hinsichtlich der Leistung mit der Idee der Massenkopie der Daten so. 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
Können Sie ein Beispiel für die Daten und was Sie erwarten? –
Sie haben also 2 Tabellen A & B, die sich gegenseitig referenzieren, und Sie möchten eine Teilmenge davon in die Tabellen C & D kopieren (die referentielle Integrität bleibt dabei erhalten). Warum ändern sich die Fremdschlüssel überhaupt? Ich denke, es geht dir gut, es sei denn, es gibt eine Eigenschaft von Schlüsseln, die mir nicht bekannt ist. – PowerUser
Ihr Entwurf ist vermutlich nicht normalisiert? Wenn ich es richtig verstehe, möchte ich einige Zeilen extrahieren und sie unverändert mit neuen Primärschlüsseln in Tabelle A zurückschreiben. Dann extrahiere die Zeilen aus tableB, die auf die alten von tableA extrahierten Zeilen verweisen, und schreibe sie zurück in tableB, die auf die neuen Zeilen in tableA verweisen (Ich bin mir bewusst, dass ich nur wiederhole, was du gesagt hast, aber ich möchte bestätigen, dass ich es verstehe). Können Sie vielleicht Ihre Daten beschreiben, weil ich mir keinen Anwendungsfall vorstellen kann, der mit einem normalisierten Design nicht besser bedient werden könnte? –