Anmelden

View Full Version : Problem mit Triggern



marcel84
31-10-08, 10:51
Ich benötige euer Fachwissen bei folgender Aufgabestellung:

Beispiel:
Kundendaten von Mandant 1 sollen bei jeder änderung/neuanlage/löschung auch in Mandant 2 übertragen werden.

Mein erster Versuch war dies über einen externen RPG Trigger, der aufgrund der nötigen Rekursion mit ACTGRP(*new) erstellt wurde, zu realisieren. Im RPG Programm habe ich geprüft ob die Änderung aus Mandant 1 stammt um dann die Änderung auch in Mandant 2 zu übertragen.
Da ganze hat die Performance aber leider stark negativ beeinflusst. Ich vermute weil er ständig mit einer neuen Aktivierungsgruppe aufgerufen wurde und ich ja erst im Programm selbst prüfen kann ob die Änderung aus Mandant 1 oder 2 kommt was ja dann leider zu rekursiven Aufrufen führt.

Nun würde ich das Ganze gern mit einem SQL Trigger lösen, da ich bei diesem ja bereits bei der Definition bestimmen kann, dass es nur bei Änderungen in Mandant 1 aktiv werden soll.

Wie wird so ein Trigger denn nun am besten definiert?

Es muss ja bei einer Neuanlage oder Änderung im Prinzip nur der komplette Datensatz von Mandant 1 mit einem einzigen geänderten Feld (die Mandantennummer) in Mandant 2 angelegt werden.

Wenn ich das nun in etwa so umsetzen will:



CREATE TRIGGER TEST AFTER UPDATE ON KUNDENSTAMM
REFERENCING OLD OROW NEW NROW FOR EACH ROW MODE DB2ROW WHEN (OROW.MANDANT = '1')
BEGIN ATOMIC

DELETE FROM KUNDENSTAMM WHERE MANDANT = '2' AND KUNDE = OROW.KUNDE;
INSERT INTO KUNDENSTAMM (MANDANT, KUNDENNUMER,...... 100 weitere Felder) VALUES('2', NROW.KUNDENUMMER, ...... 100 weitere Felder);

END;

müsste ich ja alle meine Datenbankfelder angeben, was bei den Wartungsaufwand solcher Lösungen natürlich erhöht.

Wie geht man dann bei solch einer Anforderung am besten vor?

Danke für eure Hilfe!

Fuerchau
31-10-08, 12:32
Der SQL-Trigger wird da auch nicht performanter.
Definiere für deinen Trigger einfach eine benannte ACTGRP und beende das Programm mit *LR=*OFF.

marcel84
31-10-08, 13:03
Danke für die Antwort.
Dann bekomme ich allerdings einen RNX8888 wegen rekursivem Aufruf, da der Trigger sich ja wieder selbst aufruft, sobald er die Änderung in Mandant 2 schreibt.

Fuerchau
31-10-08, 13:16
Stimmt!
Bei SQL-Triggern musst du halt jedes Feld explizit benennen, da kommst du nicht drum herum.

BenderD
31-10-08, 13:58
seltsam, seltsam, was soll denn passieren, wenn ein Satz für Mandant 2 gelöscht, geändert, oder eingefügt wird? Für mich hört sich das nach einem krummen Datenbankdesign an, aber seis drum.
Wenn es nur darum geht für Mandant 2 immer die Sätze von Mandant 1 zu bekommen, dann tuts da schon eine View mit case.
Wenn man da schon unbedingt mit Triggern rumspielen will, dann sollte man beim update auch einen update machen und kein delete insert, das halbiert schon mal die Aufrufe auf die Hälfte.
Wenn man zu faul zum tippen ist und einem cut und paste noch zu mühsam ist, dann schreibt man sich halt einen Generator, wenn man da hunderte von Triggern braucht.

die Aufrufe für Mandant2 bekommt man auch mit einer View und einem instead Trigger weg, der dann aber wohl auch in SQL geschrieben werden muss.

D*B




Ich benötige euer Fachwissen bei folgender Aufgabestellung:

Beispiel:
Kundendaten von Mandant 1 sollen bei jeder änderung/neuanlage/löschung auch in Mandant 2 übertragen werden.

Mein erster Versuch war dies über einen externen RPG Trigger, der aufgrund der nötigen Rekursion mit ACTGRP(*new) erstellt wurde, zu realisieren. Im RPG Programm habe ich geprüft ob die Änderung aus Mandant 1 stammt um dann die Änderung auch in Mandant 2 zu übertragen.
Da ganze hat die Performance aber leider stark negativ beeinflusst. Ich vermute weil er ständig mit einer neuen Aktivierungsgruppe aufgerufen wurde und ich ja erst im Programm selbst prüfen kann ob die Änderung aus Mandant 1 oder 2 kommt was ja dann leider zu rekursiven Aufrufen führt.

Nun würde ich das Ganze gern mit einem SQL Trigger lösen, da ich bei diesem ja bereits bei der Definition bestimmen kann, dass es nur bei Änderungen in Mandant 1 aktiv werden soll.

Wie wird so ein Trigger denn nun am besten definiert?

Es muss ja bei einer Neuanlage oder Änderung im Prinzip nur der komplette Datensatz von Mandant 1 mit einem einzigen geänderten Feld (die Mandantennummer) in Mandant 2 angelegt werden.

Wenn ich das nun in etwa so umsetzen will:



CREATE TRIGGER TEST AFTER UPDATE ON KUNDENSTAMM
REFERENCING OLD OROW NEW NROW FOR EACH ROW MODE DB2ROW WHEN (OROW.MANDANT = '1')
BEGIN ATOMIC

DELETE FROM KUNDENSTAMM WHERE MANDANT = '2' AND KUNDE = OROW.KUNDE;
INSERT INTO KUNDENSTAMM (MANDANT, KUNDENNUMER,...... 100 weitere Felder) VALUES('2', NROW.KUNDENUMMER, ...... 100 weitere Felder);

END;

müsste ich ja alle meine Datenbankfelder angeben, was bei den Wartungsaufwand solcher Lösungen natürlich erhöht.

Wie geht man dann bei solch einer Anforderung am besten vor?

Danke für eure Hilfe!