Hallo,
ich möchte in einer unbekannten Tabelle temporär einen Datensatz kopieren und dabei die Schlüsselfelder ändern.
Hintergrund:
Wir haben in unserer
DB eine Tabelle in der Keys für alle Einrichtungen hinterlegt sind. In allen anderen Tabellen, in denen Einrichtungen vorkommen, ist dieser Key als Foreign Key referenziert, teils mehrstufig. Nun kommt es vor, dass eine neue Einrichtung mit Key 2 angelegt wird, die es eigentlich bereits gibt (mit Key 1), weil vorher schlecht gesucht wurde. Dann müssen diese 2 Einrichtungen zusammengelegt werden. Nach dem Abgleich der Daten zu den IDs müssen alle Referenzen auf Key 2 auf Key 1 umgebogen/geändert werden, um anschließend Key 2 löschen zu können. Das Umbiegen einer mehrstufigen Abhängigkeit ist nicht ganz trivial:
- Tab0 enthält die Schlüssel
- Tab1 ist die 1. Abhängigkeit (enthält einen FK auf Tab0)
- Tab2 ist die 2. Abhängigkeit (enthält einen FK auf Tab1)
Der Algorithmus startet auf Tab0, dort existieren Key1 und Key 2 bereits, alle bestehenden Keys 2 sollen auf Key 1 umgebogen/geändert werden. Tab1 und Tab2 enthalten jeweils nur Key 2. Wird nun Tab1 zuerst geändert, schlägt das fehl, weil in Tab2 der Foreign-Key-Constraint sofort anschlägt (Key 2 ist dort immernoch referenziert). Wird Tab2 zuerst geändert, schlägt der Foreign-Key-Constraint ebenso an, weil in Tab1 Key 1 noch nicht existiert. Also müssen in Tab1 übergangsweise beide Keys existieren.
Der Algorithmus arbeitet potentiell auf allen Tabellen in der
DB. Welche davon einen FK auf die Basistabelle (Tab0) haben, bekomme ich in den Systemtabellen heraus. Wenn eine andere Tabelle einen Foreign Key auf die aktuelle Tabelle hat, dann ist das aktuelle Feld in der aktuellen Tabelle unique. Die restliche Struktur kenne ich nicht. Mein Vorgehen im oben skizzierten Fall ist wie folgt:
- Ich erzeuge in Tab1 eine Kopie des Datensatzes mit dem Key. Dabei müssen alle Felder kopiert werden, für den Fall dass weitere Abhängigkeiten existieren, und alle Felder mit einem Unique-Index (in Systemtabellen zu finden) geändert werden.
- Dann rufe ich meine Procedure rekursiv auf Tab1 auf und ändere den Key auf den temporären Key.
- Daraufhin ist der ursprünglichen Datensatz mit Key 2 frei und kann auf Key 1 geändert werden.
- Nun rufe ich meine Procedure nochmals rekursiv auf, um den temporären Key in den abhängigen Tabellen (ab Tab2) auf den Key 1 zu ändern.
- Schlussendlich kann der temporäre Datensatz gelöscht werden.
Da das Ganze in einer Transaktion abläuft, ist die einzige Differenz zwischen vorher und nachher der geänderte Key. ich brauche mir also keine Gedanken um Generatoren zu machen, die zwischenzeitlich den selben Wert wie in dem temporären Datensatz geliefert hätten. Dieser Wert ist nach der Transaktion wieder valide.
Das Problem ist also das Kopieren aller Werte eines Datensatzes mit Ausnahme der Felder mit einem Unique Key. In
MySQL kann ich hier mit temporären Tabellen arbeiten, die offenbar nur im Speicher angelegt werden. Wie ist das mit diesen Global Temporary Tables? Werden die bis zum committen auch erstmal im Speicher gehalten, oder wird da sofort eine Datei angelegt? Das würde natürlich zu erheblichen Performance-Einbußen führen, so dass ich lieber aus den Systemtabellen alle Felder von Tab1 ermittle und mir ein
SQL zusammenschustere, das alle Felder enthält, die ich kopieren möchte. Aber das ergibt eben mehr
SQL-Abfragen als die temporäre Tabelle und es ist weniger gut lesbar was da passiert.
Vielleicht gibt es aber auch noch eine ganz andere Lösung, ich bin gespannt auf jede Art von Response.
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."