0

更新後に子レコードを更新するトリガーを作成して、外部キーの 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)コミットできます。どうすればこれを回避できますか?

4

1 に答える 1

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> 
于 2013-06-28T12:25:32.350 に答える