2016-10-25 3 views
2

Was passiert, wenn eine Ausnahme in einem TRIGGER ausgelöst wird?Ausnahmebehandlung in TRIGGERS (für jede Zeile)

nehmen wir an einen Tisch R haben (a, b, c, d, e) mit den Werten unter:

5 rows of data in table R

Nehmen wir nun an versuchen wir UPDATE R SET b = 2, c = 3 WHERE a = 1 mit dem Auslöser unten in Wirkung aufgeführt auszuführen:

CREATE TRIGGER fd_enforcer_update 
BEFORE UPDATE on R 
FOR EACH ROW 
DECLARE counter INT 
BEGIN 
    SELECT COUNT(*) INTO counter 
    FROM R 
    WHERE R.A = NEW.A AND R.B = NEW.B AND R.C <> NEW.C 
    AND NOT (R.A = OLD.A AND R.B = OLD.B AND R.C = OLD.C AND R.D = OLD.D AND R.E = OLD.E); 
    IF (counter > 0) 
    THEN raise_exception(); 
END; 

Der obige Code geschrieben wird angeblich AB->C die funktionale Abhängigkeit zu erzwingen.

Im obigen Beispiel betrifft die UPDATE-Anweisung vier Zeilen. Da wir im Trigger FOR EACH ROW angegeben haben, wird jede dieser 4 Zeilen überprüft.

Der Trigger überprüft die erste der vier Zeilen [1,1,2,3,4] und löst eine Ausnahme aus. Was passiert jetzt? Wird der Trigger vollständig beendet? Oder überprüft es die anderen drei Zeilen noch?

Nachdem meine UPDATE Anweisung ausgeführt wurde, wie viele Zeilen werden tatsächlich aktualisiert?

+2

Eine Ausnahme wird im 'update' ausgelöst, so dass die 'update'-Anweisung beendet und Änderungen rückgängig gemacht werden. Das ist, was 'raise_exception()' tut. –

+0

Bitte Daten als formatierten Test, [keine Screenshots] (http://meta.stackoverflow.com/questions/285551/why-may-i-not-upload-images-of-code-on-so-when-asking) -a-question/285557 # 285557) – Aleksej

+1

Was ist passiert, als du es ausprobiert hast? –

Antwort

0

Es tut mir leid, aber ich verstehe nicht. Ihr Trigger wird mit Fehler geschrieben. Der richtige Code wird wie betrachtet werden:

CREATE TRIGGER fd_enforcer_update 
BEFORE UPDATE on R 
FOR EACH ROW 
DECLARE 
    counter INT 
BEGIN 
    SELECT COUNT(*) 
     INTO counter 
     FROM R 
    WHERE R.A = :NEW.A 
     AND R.B = :NEW.B 
     AND R.C <> :NEW.C 
    AND NOT (R.A = :OLD.A 
     AND R.B = :OLD.B 
     AND R.C = :OLD.C 
     AND R.D = :OLD.D 
     AND R.E = :OLD.E); 
    IF counter > 0 THEN 
     raise_exception(); 
    END IF; 
END; 

Und wenn wir UPDATE R SET b = 2, c = 3 WHERE a = 1 nennen. Ermöglicht das Update übernehmen wird von oben nach unten beginnen werden: Für die erste Reihe:

a | b | c | d | e 
1 | 1 | 2 | 3 | 4 

wählen wird es 4

SELECT COUNT(*) 
     INTO counter 
     FROM R 
    WHERE R.A = 1 
     AND R.B = 2 
     AND R.C <> 3 
    AND NOT (R.A = 1 
     AND R.B = 1 
     AND R.C = 2 
     AND R.D = 3 
     AND R.E = 4) 

Und auf aktuellen Daten wie

betrachtet werden zurückkehren (kann ich wriong, aber ich bin sicher, es wird mehr als 0). Und Auslöser namens raise_exception() für die erste Zeile. Und die gesamte Transaktion wird zurückgesetzt.