2016-10-25 4 views
2

TRIGGERで例外が発生した場合はどうなりますか?私たちは以下の値を持つテーブルR(A、B、C、D、E)があるとしTRIGGERSでの例外処理(各行用)

5 rows of data in table R

を今、私たちは実際には、下記のトリガとUPDATE R SET b = 2, c = 3 WHERE a = 1を実行しようとします

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; 

上記のコードは、おそらく機能的依存AB->Cを強制するために書かれています。

上記の例では、UPDATEステートメントは4行に影響します。トリガーにFOR EACH ROWと指定したので、これらの4つの行のそれぞれがチェックされます。

トリガーは、4行のうちの最初の行をチェックして例外を発生させます。今、何が起こるのですか?トリガーは完全に終了しますか?それとも他の3つの行をチェックしていますか?

私のUPDATEステートメントが実行された後、実際に更新される行の数はいくつですか?

+2

'update'で例外が発生するので、' update'文は終了し、変更はロールバックされます。これが 'raise_exception()'の動​​作です。 –

+0

フォーマットされたテストとして[スクリーンショットではなく]データを投稿してください(http://meta.stackoverflow.com/questions/285551/why-may-i-not-upload-images-of-code-on-so-when-asking -a-question/285557#285557) – Aleksej

+1

試したときに何が起こったのですか? –

答えて

0

申し訳ありませんが、わかりません。あなたのトリガーはエラーで書かれています。正しいコードは次のように検索されます:

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; 

そして、我々はUPDATE R SET b = 2, c = 3 WHERE a = 1を呼び出す場合。最初の行について :

a | b | c | d | e 
1 | 1 | 2 | 3 | 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) 

ように見えたし、現在のデータに、それが(私はwriongてもよい4を返すであろう は、その更新が上から下に開始すると仮定しますしかし、私はそれが0以上になると確信しています)。また、最初の行にraise_exception()というトリガーがあります。そして、全体のトランザクションはロールバックされます。