想要检查触发器中的约束以在Oracle中记录自定义消息

时间:2017-03-18 12:21:17

标签: oracle triggers

我在INSERT和UPDATE的表上有一个BEFORE TRIGGER。我正在动态创建此触发器的代码,其中包括检查约束的条件,例如

if colA = 1 then colB must be 0 and colC must be 1 

如果是insert,我会检查所有3列的:NEW值,没有问题。但是在更新的情况下这种情况应该如何?用户可以更新这3列中的一个或两个或全部。所以我应该如何使用:NEW或:在UPDATE操作的情况下为OLD。

寻找一些指示。如果需要任何进一步的信息,请告诉我。

此致 萨钦

1 个答案:

答案 0 :(得分:1)

您希望强制执行最终值的状态。因此,您应该使用: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;

或者,您应该考虑在表上使用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)进行条件检查。"

Fnord。 :NEW值表示记录的新版本,而不是更改的值。通过简单的测试来检查这种行为非常容易:

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值是在事务结束时将持久保存到表中的值。如果更新语句没有设置列值,则:new.whatever = :old.whatever