TRIGGER模拟约束ON UPDATE选项

时间:2013-06-28 10:57:47

标签: oracle oracle10g

我正在尝试通过在更新后更新子记录的触发器来模拟外键中的ON UPDATE选项。

触发器如下所示:

CREATE OR REPLACE TRIGGER SOMETABLE_AU_ID_TRG
  AFTER UPDATE OF ID ON SOMETABLE
  FOR EACH ROW
BEGIN
  UPDATE SOMECHILDTABLE SET SOMETABLE_ID = :NEW.ID WHERE ID = :OLD.ID;
END;

我正在使子表约束像这样延迟:

set constraint 
SOMECHILDTABLE_FK_SOMETABLE deferred;

但它在提交时仍然给我ORA-02292 (child record found)。我怎么能避免这个?

1 个答案:

答案 0 :(得分:2)

感谢@BrianCamire发现错误:

让我们从创建触发器开始......

SQL> CREATE OR REPLACE TRIGGER SOMETABLE_AU_ID_TRG
  AFTER UPDATE OF ID ON SOMETABLE
  FOR EACH ROW
BEGIN
  UPDATE SOMECHILDTABLE SET SOMETABLE_ID = :NEW.ID WHERE ID = :OLD.ID;
END;  2    3    4    5    6  
  7  /

Trigger created.

SQL> alter table somechildtable add constraint some_fk foreign key (sometable_id)
  2  references sometable (id) deferrable initially deferred;

Table altered.

SQL>  

这是数据......

SQL> select * from somechildtable;

        ID SOMETABLE_ID
---------- ------------
        11            1
        12            2
        13            6
        14            4
        15            5

SQL>

所以,让我们搞乱父数据......

SQL> update sometable set id = 3 where id = 6
  2  /

1 row updated.

SQL> commit;
commit
*
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-02292: integrity constraint (APC.SOME_FK) violated - child record found


SQL> 

啊哈!所以,正如Brian所说,我们需要更改触发器代码:

SQL> CREATE OR REPLACE TRIGGER SOMETABLE_AU_ID_TRG
      AFTER UPDATE OF ID ON SOMETABLE
      FOR EACH ROW
    BEGIN
      UPDATE SOMECHILDTABLE SET SOMETABLE_ID = :NEW.ID WHERE SOMETABLE_ID = :OLD.ID;
    END; 
/

  2    3    4    5    6    7  
Trigger created.

SQL> SQL> update sometable set id = 3 where id = 6;

1 row updated.

SQL> commit;

Commit complete.

SQL> select * from somechildtable
  2  /

        ID SOMETABLE_ID
---------- ------------
        11            1
        12            2
        13            3
        14            4
        15            5

SQL>