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