Situation:
2 Tabellen einer DB sollen abgegelichen werden, wozu sich ein UPDATE-Trigger anbietet. Die beiden Tabellen besitzen teilweise gleichartige Spalten. Dieser ungünstige Umstand kommt durch die Kopplung zweier verschiedenartiger Systeme zustande, deren Tabellen in einer MS SQL-DB enthalten sind.
Besagte Tabellen können jedoch nicht zu einer verschmolzen werden, so daß gewisse Spaltenwerte beim Update in Tabelle A auch in Tabelle B übernommen werden müssen. Dies könnte durch einen Trigger in Tabelle A geleistet werden. Aber auch umgekehrt müßte ein Trigger in Tabelle B auf Änderungen reagieren und diese in Tabelle A nachziehen. Hier sehe ich eine Endlosschleife beider Trigger…
Wie kann man dieses Problem lösen?
Hallo Frank,
ich habe dieses Problem zwar selbst noch nicht gehabt, aber vielleicht könnte folgendes als Lösungsansatz dienen:
Im Trigger von Tabelle A muß ja ein Update in Tabelle B ausgeführt werden. Dieses würde wiederum den Trigger in Tabelle B auslösen. Wenn du, bevor du den Update-Befehl ausführst, erst überprüfst, ob die Werte in beiden Tabelle schon gleich sind, dann kannst du den Update-Befehl überspringen, wenn nötig.
Für den Trigger von Tabelle B analog.
Daraus würde sich folgender Ablauf ergeben:
Änderung in A -> Trigger A prüft B ->
AB -> B:=A -> Trigger B prüft A
-> B=A -> stop
Lass mich wissen, wenn es dir weitergeholfen hat.
CU
Markus
[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]
Für Oracle hätte ich zwei Ansätze:
- In einer Package-Variable (eine statische Variable) könnte man die ID des zu ändernden Datensatzes festhalten, vor dem Update müßte dieses überprüft werden.
- Der Trigger auf Tabelle A könnte als allererstes den Trigger auf B disablen; nach Update wieder enablen (ALTER TRIGGER TRIGGERB DISABLE); das müßte, da es ein DDL-Statement ist, über die Package DBMS_DDL erfolgen.
gruß
J.
Hallo Markus,
Deine Idee funktioniert. Der Trigger muß ungefähr so aussehen, damit es funktioniert:
IF UPDATE (name\_short) OR UPDATE (code)
BEGIN
/\*
Die in Tabelle1 geänderten Felder sollen in Tabelle2 nur geändert
werden, wenn sie wirklich verschieden sind:
\*/
SELECT @tab2\_nr=[Nr.], @tab2\_suchbegriff=Suchbegriff, @tab2\_name=[Name]
FROM Tabelle2
WHERE Tabelle2.[Nr.] like @tab1\_id
IF ((@tab2\_suchbegriff not like @tab1\_code) OR (@tab2\_name not like @tab1\_name\_short))
BEGIN
UPDATE Tabelle2
SET Tabelle2.[Suchbegriff] = @tab1\_code, Tabelle2.[Name] = @tab1\_name\_short
WHERE (Tabelle2.[Nr.] like @tab1\_id)
END
END
Auf vorher deklarierte und definierte Variablen habe ich hier verzichtet.
Läßt man die IF-Anweisung weg, so wird der Trigger der anderen Tabelle trotz WHERE-Klausel in UPDATE angesprungen, wodurch ein Ping-Pong-Spiel erzeugt wird, das der MS SQL-Server 32 Mal mitmacht und danach mit einer Fehlermeldung den ursprüglich geänderten Datensatz unverändert läßt.
Vielen Dank also für Deinen Tipp - er war fruchtbar.
Frank