要检查触发器中的约束以在Oracle中记录自定义消息吗
我在表上有一个用于插入和更新的BEFORE触发器。我正在动态创建这个触发器的代码,其中包括检查约束的条件,比如要检查触发器中的约束以在Oracle中记录自定义消息吗,oracle,triggers,Oracle,Triggers,我在表上有一个用于插入和更新的BEFORE触发器。我正在动态创建这个触发器的代码,其中包括检查约束的条件,比如 if colA = 1 then colB must be 0 and colC must be 1 在insert的情况下,我检查所有3列的:新值,没有问题。但在更新的情况下,这种情况应该是什么样子?用户可以更新这3列中的一列、两列或全部。那么,在进行更新操作时,我应该如何使用:NEW或:OLD 正在寻找一些指针。如果需要进一步的信息,请告诉我 问候,, Sachin您希望强制执
if colA = 1 then colB must be 0 and colC must be 1
在insert的情况下,我检查所有3列的:新值,没有问题。但在更新的情况下,这种情况应该是什么样子?用户可以更新这3列中的一列、两列或全部。那么,在进行更新操作时,我应该如何使用:NEW或:OLD
正在寻找一些指针。如果需要进一步的信息,请告诉我
问候,,
Sachin您希望强制执行最终值的状态。因此,插入和更新都应该使用
:NEW
if :new.colA = 1
and (:new.colB != 0 or :new.colC != 1 )
then
-- or whatever you want to happen ....
raise_application_error(-20000, 'your message here');
end if;
P>可选地,您应该考虑在表上使用CHECK约束。约束比触发器更有效,并且是执行此类业务规则的行业标准方法
SQL> alter table t23 add constraint t23ck
2 check ((cola=1 and colb=0 and colc=1)
3 or cola != 1)
4 /
Table altered.
SQL> insert into t23 (cola, colb, colc) values (1, 0 , 1);
1 row created.
SQL> insert into t23 (cola, colb, colc) values (1, 0 , 2);
insert into t23 (cola, colb, colc) values (1, 0 , 2)
*
ERROR at line 1:
ORA-02290: check constraint (FOX.T23CK) violated
SQL> insert into t23 (cola, colb, colc) values (0, 0 , 2);
1 row created.
SQL>
“如果用户仅为一列提供值,则其他列的:NEW将没有任何内容。因此,我需要现有值(:OLD)进行条件检查。” 弗诺德。:新值表示记录的新版本,而不是更改的值。通过一个简单的测试很容易检查这种行为:
SQL> create or replace trigger t23_upd_trg
2 before update on t23 for each row
3 begin
4 dbms_output.put_line ('new colA ='||:new.colA);
5 dbms_output.put_line ('new colB ='||:new.colB);
6 dbms_output.put_line ('new colC ='||:new.colC);
7 end;
8 /
Trigger created.
SQL> set serveroutput on
SQL> select * from t23
2 where cola = 9
3 /
COLA COLB COLC
---------- ---------- ----------
9 4 4
SQL> update t23
2 set cola = 1
3 where cola = 9
4 /
new colA =1
new colB =4
new colC =4
update t23
*
ERROR at line 1:
ORA-02290: check constraint (FOX.T23CK) violated
看到了吗:NEW.colb
和:NEW.colc
返回原始值,因为它们仍然是当前值
如果在检查条件中显式提供了:OLD值,那么:NEW仍将是记录的新版本,以防用户没有为该列提供值
:old
和:new
是用于引用不同版本记录的命名空间。:new
值是事务结束时将保留到表中的值。如果update语句未设置列值,则:new.whatever=:old.whatever
感谢您的回复。我确实在使用约束。当触发代码生成时(通过代码生成器逻辑),约束检查成为触发逻辑的一部分。所以,若约束被打破,我必须在日志表(触发器本身)中创建一个条目。嗨,关于您的解决方案有一个问题。如果用户只为一列提供值,那么:其他列的NEW将不会有任何内容。因此,我需要现有值(:OLD)进行条件检查。如何处理这种情况?感谢您的详细解释。还有一个问题。如果在检查条件中显式提供了:OLD值,那么:NEW仍然是记录的新版本,前提是用户没有为该列提供值?