Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 触发器中的异常处理(针对每行)_Sql_Database_Oracle - Fatal编程技术网

Sql 触发器中的异常处理(针对每行)

Sql 触发器中的异常处理(针对每行),sql,database,oracle,Sql,Database,Oracle,在触发器中引发异常时会发生什么 假设我们有一个表R(a,b,c,d,e),其值如下: 现在假设我们尝试执行updater SET b=2,c=3,其中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(a,b,c,d,e),其值如下:

现在假设我们尝试执行
updater SET b=2,c=3,其中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;
CREATE TRIGGER fd\u enforcer\u update
在R上更新之前
每行
声明计数器INT
开始
选择计数器中的计数(*)
从R
其中R.A=新的.A和R.B=新的.B和R.C新的.C
而不是(R.A=OLD.A,R.B=OLD.B,R.C=OLD.C,R.D=OLD.D,R.E=OLD.E);
如果(计数器>0)
然后引发_异常();
结束;
上面的代码被认为是为了强制执行函数依赖关系
AB->C

在上面的示例中,
UPDATE
语句影响四行。因为我们在触发器中为每一行指定了
,所以这4行中的每一行都将被检查

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


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

对不起,我不明白。你的触发器写错了。正确的代码如下所示:

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;
选择将看起来像

    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)
选择计数(*)
进入柜台
从R
其中R.A=1
R.B=2
及R.C.3
而不是(R.A=1
R.B=1
R.C=2
R.D=3
R.E=4)

在当前数据上,它返回4(可能是I wrong,但我确信它将大于0)。并为第一行调用raise_exception()触发器。整个交易将被回滚

update
中引发异常,因此
update
语句终止并回滚更改。这就是
raise\u exception()
所做的。请将数据作为格式化测试发布,当您尝试它时发生了什么?@GordonLinoff update语句是否仅在该特定行终止?例如,如果有一个
UPDATE
语句影响100行。。。假设只有当触发器检查第67行时才会引发异常。从第1行到第66行的更改是否会回滚?@JTJM。将回滚整个语句。这就是SQL的工作方式,语句对语句,或事务对事务。
    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)