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

要检查触发器中的约束以在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您希望强制执

我在表上有一个用于插入和更新的BEFORE触发器。我正在动态创建这个触发器的代码,其中包括检查约束的条件,比如

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仍然是记录的新版本,前提是用户没有为该列提供值?