2017-12-29 40 views
0

Ich versuche, mehrere Trigger zu erstellen. Ein Trigger aktualisiert das Feld 'ysnAcknowledged', wenn das (verborgene) Feld 'Reprint' im selben Formular von Crystal Reports aktualisiert wird. Der zweite Trigger muss das Feld "Reprint" aktualisieren, wenn das Feld "ysnAcknowledged" vom Benutzer manuell aktualisiert wird (Kontrollkästchen "Formular"). Ich habe den ersten Auslöser, mein Problem ist, wenn ich das 'ysnAcknowledged'-Feld aktualisiere, wird es meinen zweiten Auslöser auslösen, den ersten Auslöser effektiv reversierend, bevor ich es will.Erstellen Sie einen SQL-Trigger, um einen vorherigen Trigger umzukehren

1. Auslöser:

CREATE TRIGGER SOPickListReprint 
ON dbo.SalesOrder 
AFTER UPDATE 
AS 

IF UPDATE(Reprint) 
UPDATE dbo.SalesOrder 
SET ysnAcknowledged = 1 

2. Trigger:

CREATE TRIGGER SOPickListUpdate 
ON dbo.SalesOrder 
AFTER UPDATE 
AS 

IF UPDATE(ysnAcknowledged) 
UPDATE dbo.SalesOrder 
SET Reprint = 0 
+0

es in einem einzigen Trigger tun? * (Denken Sie daran, dass mehr als eine Zeile geändert werden kann, dieser Trigger gibt nur eine Zeile vor und aktualisiert dann jede Zeile in der Tabelle?) * – MatBailie

+0

Trigger sind ** sehr herstellerspezifisch ** - fügen Sie also ein Tag hinzu um anzugeben, ob Sie 'mysql',' postgresql', 'sql-server',' oracle' oder 'db2' verwenden - oder etwas ganz anderes. –

+0

Sie haben Recht! Das ist MSSQL. –

Antwort

0

Meine Lösung:

CREATE TRIGGER SOPickListReprint 
ON dbo.SalesOrder 
AFTER UPDATE 
AS 

UPDATE dbo.SalesOrder 
SET ysnAcknowledged = CASE WHEN deleted.Reprint = 0 AND inserted.Reprint = 1 THEN 1 ELSE inserted.ysnAcknowledged END, 
Reprint = CASE WHEN deleted.ysnAcknowledged = 1 AND inserted.ysnAcknowledged = 0 THEN 0 ELSE inserted.Reprint END 
FROM SalesOrder 
INNER JOIN 
inserted 
    ON inserted.SalesOrderID = SalesOrder.SalesOrderID 
INNER JOIN 
deleted 
    ON deleted.SalesOrderID = SalesOrder.SalesOrderID 
+0

Ohne die 'WHERE'-Klausel werden Sie unnötigerweise verarbeiten * (und neu schreiben) * Zeilen, wo ein anderes Feld geändert. – MatBailie

+0

@ MatBailie, Sie haben Recht. Ich werde das jetzt reparieren, danke! –

1
CREATE TRIGGER SOPickListUpdate 
    ON dbo.SalesOrder 
    AFTER UPDATE 
AS 

-- Update only rows where Reprint changed or ysnAcknowledged changed 
-- > If ysnAcknowledged changed, force Reprint to 0, otherwise leave it as it is 
-- > If Reprint changed, force ysnAcknowledged to 1, otherwise leave it as it is 
UPDATE 
    SalesOrder 
SET 
    Reprint   = CASE WHEN inserted.ysnAcknowledged <> deleted.ysnAcknowledged THEN 1 ELSE inserted.Reprint END, 
    ysnAcknowledged = CASE WHEN inserted.Reprint   <> deleted.Reprint   THEN 0 ELSE inserted.ysnAcknowledged END 
FROM 
    SalesOrder 
INNER JOIN 
    inserted 
     ON inserted.<primary_key> = SalesOrder.<primary_key> 
INNER JOIN 
    deleted 
     ON deleted.<primary_key> = SalesOrder.<primary_key> 
WHERE 
     inserted.ysnAcknowledged <> deleted.ysnAcknowledged 
    OR inserted.Reprint   <> deleted.Reprint 
+0

@ MatBailie, ich arbeite mit nur einem Tisch. Eingefügt und gelöscht wurden nicht definiert. Ich verstehe nicht, wie das funktionieren soll. –

+0

'insert' und' deleted' sind Meta-Tabellen, die Ihnen SQL Server zur Verwendung in Triggern zur Verfügung stellt. Ich empfehle dringend, dass Sie das Handbuch und/oder einige Tutorials zu SQL Server Triggern lesen. https://docs.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql * ('[insert]' enthält jede Zeile INSERTED oder UPDATED, '[deleted]' enthält alle row DELETED oder UPDATED; Ein 'UPDATE' wird als' DELETE' dargestellt und dann und 'INSERT' ... * – MatBailie

+0

Vielen Dank für Ihre Hilfe! Dies ist, was ich am Ende getan habe: –

Verwandte Themen