Eigentlich ist das recht einfach mit den Triggern, man muss nur immer genau überlegen was eigentlich passiert.
Bei einem INSERT, UPDATE Trigger wie oben passiert folgendes:
Du schreibst ein oder mehrere Datensätze in die Tabelle oder du aktualisierst einen oder mehrere Datensätze in der Tabelle. Danach feuert der Trigger einmal. Du führst also den Code aus der zwischen AS BEGIN und END steht.
Als Besonderheit hast du in diesem Kontext Zugriff auf zwei Tabellen. In INSERTED stehen die Datensätze, die du eingefügt hast bzw. das, was durch UPDATE in die Tabelle geschrieben wurde. In DELETED das was vorher in der Tabelle stand. Hier ist eventuell schon dein Fehler zu suchen, mehr dazu gleich.
Der Code joint jetzt in einem UPDATE-Statement die eigentliche Tabelle, die ja schon verändert wurde, per INNER JOIN mit dem was verändert wurde. Betroffen sind also nur Datensätze die auch vorher verändert oder neu geschrieben wurden. Jetzt machst du noch einen INNER JOIN mit DELETED, es sind also nur Datensätze betroffen, die vorher schon da waren. Das ist natürlich schlecht, denn: Der Trigger würde auf einen INSERT vermutlich unerwartet reagieren, daher würde ich es an der Stelle erstmal mit einem LEFT JOIN versuchen und testen, ob dein Fehler bei INSERT oder bei UPDATE noch auftritt:
Code:
CREATE TRIGGER Tr_Produkte
ON Produkte
FOR INSERT, UPDATE
AS
BEGIN
UPDATE Produkte
SET Produkte.ShopDatum = getdate()
FROM Produkte
INNER JOIN INSERTED i
ON i.ID= Produkte.ID
LEFT JOIN DELETED d
ON d.ID= Produkte.ID
WHERE i.ImShop = 1
AND ( d.ImShop = 0
OR d.ImShop IS NULL )
END
Der Trigger setzt ShopDatum = getdate() bei neuen Datensätzen (INSERT) wenn ImShop = 1 ist (d.ImShop ist dann übrigens nicht existent aber aufgrund des LEFT JOINs NULL) oder bei einem alten Datensatz wenn ImShop vorder 0 oder NULL war (hier existiert ein Eintrag in DELETED und wird unter d.ImShop auch geprüft).
Du solltest nicht beliebig Trigger auf eine Tabelle legen, du kannst die Reihenfolge nur schwer bis gar nicht beeinflussen. Jeder Trigger der wie hier die Daten der Tabelle nachträglich ändert, würde sich und andere Trigger bei diesem Änderungsvorgang erneut auslösen. Das führt zu Cascaden die per Default bei 30 Auslösern von der DB gestoppt werden. In diesem Fall würde ich alles in den selben Trigger packen, entscheidend ist ja der Auslöser.
Code:
CREATE TRIGGER Tr_Produkte
ON Produkte
FOR INSERT, UPDATE
AS
BEGIN
UPDATE Produkte
SET Produkte.ShopDatum = getdate()
FROM Produkte
INNER JOIN INSERTED i
ON i.ID= Produkte.ID
LEFT JOIN DELETED d
ON d.ID= Produkte.ID
WHERE i.ImShop = 1
AND ( d.ImShop = 0
OR d.ImShop IS NULL )
UPDATE Produkte
SET Produkte.ShopDatumRaus = getdate()
FROM Produkte
INNER JOIN INSERTED i
ON i.ID= Produkte.ID
INNER JOIN DELETED d
ON d.ID= Produkte.ID
WHERE ( i.ImShop = 0
OR i.ImShop IS NULL )
AND d.ImShop = 1
END
Man beachte: Im zweiten Teil nehme ich wieder INNER JOIN. Das heißt wird hier ein Datensatz per INSERT geschrieben mit ImShop = 0 oder NULL wird ShopDatumRaus nicht gesetzt, das UPDATE-Statement betrifft keine Datensätze. Das kann man natürlich auch wieder mit LEFT JOIN machen, je nachdem was gewollt ist.
Eigentlich einfach aber immer wieder Knoten im Hirn.