2017-10-31 2 views
0

T.T1_IDがT1.IDを参照する2つの表(T1 & T2)があります。私はT2のT1行への参照がない場合、T1行が削除されるようなトリガを使用して、T1の行の削除操作を実行しようとしています。それ以外の場合は、単にT1行のHIDDEN列にフラグ値を設定します。私は一致する参照のT2をチェックしてこれを試みたが、もしそうなら、私は削除を取り消し、代わりにフラグを設定しようとする例外を発生させますが、動作していないようです。トリガーをコンパイルすると、私はOracleデータベースの割込みトリガーを使用した行の削除および更新

のエラーが出る

「ORA-04084:このトリガータイプの新しい値を変更することはできません」私はそれが事実と関係している推測している

そのI削除操作中にデータを変更しようとしています。私は同様の問題で "削除後"トリガと同様の何かをやってみました。ここで私が何をしようとしています何の簡単な例です:

create table "T1" (
    "ID" number not null enable, 
    "HIDDEN" number, 
    constraint "T1_PK" primary key ("ID") 
); 

create table "T2" (
    "T1_ID" number not null enable, 
    "VAL" number, 
    constraint "T2_FK1" foreign key ("T1_ID") references "T1" ("ID") enable 
); 

create or replace trigger "BD_T1" 
    before delete on "T1" 
    for each row 
declare 
    cnt NUMBER; 
    records_found EXCEPTION;  
begin 
    select count(*) into cnt from T2 where T1_ID = :OLD."ID"; 
    if cnt > 0 then 
    RAISE records_found; 
    end if; 
exception 
    when records_found then 
    :NEW."HIDDEN" := 1; -- set hidden flag and abort delete operation 
end; 

insert into T1 ("ID") values (1); 
insert into T1 ("ID") values (2); 

insert into T2 ("T1_ID", "VAL") values (1, 100); 
insert into T2 ("T1_ID", "VAL") values (1, 200); 

select * from T1; 
delete from T1 where ID = 2; --no references so row deleted 
select * from T2; 
delete from T1 where ID = 1; -- references found so abort delete and set  hidden flag` 
+0

子レコードが見つかった場合は、例外を発生させたり、トリガーをかけたりしたくないです。 Oracleは 'ORA-02292制約違反 - 子レコードが見つかりました 'を自動的に生成します。 –

答えて

1

基本的には、あなたのトリガーは、UPDATEステートメントに変更にDELETE文をしようとしています。あなたはこれをすることはできません!ただし、トリガーを完全に削除し、DELETE文をMERGE文でdeleteオプションに置き換えることで、必要な処理を実行できます。試してください:

merge into t1 
    using (select 1 t1id from dual 
     union all 
     select 2 t1id from dual) t 
    on (t1.id = t.t1id) 
    when matched then 
     update set t1.hidden = 1 
     delete where not exists 
      (select null from t2 where t2.t1_id = t1id); 
0

基本的にトリガーは、DELETEステートメントをUPDATEステートメントに変更しようとしています。あなたはこれをすることはできません!ただし、トリガーを完全に削除し、DELETE文をMERGE文でdeleteオプションに置き換えることで、必要な処理を実行できます。試してください:

merge into t1 
    using (select 1 t1id from dual 
     union all 
     select 2 t1id from dual) t 
    on (t1.id = t.t1id) 
    when matched then 
     update set t1.hidden = 1 
     delete where not exists 
      (select null from t2 where t2.t1_id = t1id); 
関連する問題