TRIGGERS中的异常处理(每行)

时间:2016-10-25 11:16:00

标签: sql database oracle

在TRIGGER中引发异常时会发生什么?

假设我们有一个表R(a,b,c,d,e),其值如下:

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语句会影响四行。由于我们在触发器中指定了FOR EACH ROW,因此将检查这4行中的每一行。

触发器检查四行中的第一行[1,1,2,3,4]并引发异常。现在,会发生什么?触发器是否完全终止?还是继续检查其他三行?

执行UPDATE语句后,实际更新了多少行?

1 个答案:

答案 0 :(得分: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)

根据当前数据,它返回4(可能是我,但我确定它会超过0)。并触发第一行调用raise_exception()。整个交易将被回滚。