Ich will eine PSQL-Procedure schreiben, die für eine Tabelle einen Wert ändert, der in vielen weiteren Tabellen als Foreign Key "verlinkt" ist. Deshalb ist der Ansatz, den shmia verlinkt hat, nicht umsetzbar.
Beispiel:
Tab0:
Tab1 (FK: ID references Tab0.ID):
Code:
ID Wert
1 bla
2 foo
5 foo
Tab2 (FK: ID references Tab1.ID):
Code:
ID Zusatzwert
2 zweiundvierzig
5 foobar
OT: Wie kann man hier Tabellen ordentlich formatieren?
Tab0.ID = 5 ist der doppelte Datensatz zum Original Tab0.ID = 3. Tab0.ID = 5 soll also gelöscht werden, alle Referenzen auf Tab0.ID = 5 sollen umgebogen werden auf Tab0.ID = 3. Tab0.ID = 3 hat in weiteren hier nicht dargestellten Tabellen Referenzen/Abhängigkeiten, so dass Tab0.ID = 3 nicht gelöscht werden kann, um Tab0.ID = 5 einfach zu ändern in Tab0.ID = 3. Ergebnis soll folgendes sein:
Tab0:
Tab1 (FK: ID references Tab0.ID):
Code:
ID Wert
1 bla
2 foo
3 foo
Tab2 (FK: ID references Tab1.ID):
Code:
ID Zusatzwert
2 zweiundvierzig
3 foobar
Um dieses Ergebnis zu erreichen müssen in Tab1 und Tab2 Datensätze geändert werden, die abhängig voneinander sind, das geht nur über den Zwischenschritt eines temporären Datensatzes (Erklärung siehe erster Post).
Meine Prozedur: ChangeForeignKeys(Tabelle, Feld, WertAlt, WertNeu);
Eingabe im Beispiel für meine Prozedur: ChangeForeignKeys(Tab0, ID, 5, 3);
Die Prozedur iteriert über alle Foreign Keys anderer Tabellen in der
DB, die auf Tab0.ID referenzieren (auch über mehrere Schritte).
Es geht um das Kopieren eines Datensatzes in einer Tabelle, dessen Struktur ich nicht näher kenne. Was ich über die Struktur herausfinden muss, kann ich in den Systemtabellen herausfinden, das Prinzip muss aber dynamisch sein, damit es auf andere Strukturen/andere Tabellen ebenso angewendet werden kann. Der Datensatz muss also komplett kopiert werden, dabei muss genau der Primary Key und das zu ändernde Feld (im Beispiel ID) geändert werden.
Mein aktueller (vielversprechender) Ansatz sieht so aus:
SQL-Code:
/*
str1, str2: temporäre strings
fkrel1: entspricht im Beispiel Tab1
fkfield1: entspricht im Beispiel ID
*/
str1 = '';
for select rdb$field_name
from rdb$relation_fields
where rdb$relation_name = :fkrel1
order by -- unfertig - Ordnung ist wichtig!
into str2 do
begin
if (str1 <> '') then
str1 = str1 || ', ';
-- Eine Änderung aller uniques muss noch umgesetzt werden
if (str2 = fkfield1) then
str1 = str1 || '2'; -- hier muss ein sinniger temporärer Wert rein
else
str1 = str1 || str2;
end
execute statement 'insert into ' || fkrel1 ||
' select ' || str1 ||
' from ' || fkrel1 ||
' where ' || fkfield1 || ' = ' || oldvalue;
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."