2012-04-17 5 views
1

属性の1つが負になると、行を削除するトリガーを作成したいと思います。これまで私はこれを持っていますが、それは有効なSQLのようには表示されません:属性が負の値になったときに行を削除するトリガーを作成する[oracle sql]?

CREATE OR REPLACE TRIGGER ZERO_COPIES_TRIGGER 
after 
update of counter_attribute 
on my_table 
referencing new as new 
for each row when(new.copies < 0) 
begin 
    delete from my_table where my_table.id = :new.id; 
end; 

答えて

5

これは動作しません。行レベル・トリガーによって操作されている表に対してDMLを実行することはできません。あなたは "変異テーブル"エラーが発生します。

結果を得るには、レコードがであることを識別するフラグまたはインジケータ列を使用することをお勧めします。次に、別のジョブまたはプロセス、または実際に削除を実行するものを持っています。完全を期すために

+1

行レベルのトリガーではなく文レベルのトリガーを使用すると、トリガー表に対してDMLを実行できます。 –

+0

はい、もちろんです。私は私の答えを更新しました。エラーを指摘してくれてありがとう。 –

3

:あなた本当には、いくつかの楽しみを持っているしたい場合は、

CREATE OR REPLACE TRIGGER ZERO_COPIES_TRIGGER 
     AFTER UPDATE OF COUNTER_ATTRIBUTE ON MY_TABLE 
BEGIN 
    FOR aROW IN (SELECT ID 
       FROM MY_TABLE 
       WHERE COPIES < 0) 
    LOOP 
    DELETE FROM MY_TABLE 
     WHERE ID = aROW.ID; 
    END LOOP; 
END ZERO_COPIES_TRIGGER; 

または:別のオプションは、のように、テーブルをスキャンして、削除を実行文トリガーを持つことです

CREATE OR REPLACE TRIGGER COMPOUND_ZERO_COPIES_TRIGGER 
    FOR UPDATE OF COUNTER_ATTRIBUTE ON MY_TABLE 
COMPOUND TRIGGER 
    TYPE NUMBER_TABLE IS TABLE OF NUMBER; 
    tblDELETE_IDS NUMBER_TABLE; 

    BEFORE STATEMENT IS 
    BEGIN 
    tblDELETE_IDS := NUMBER_TABLE(); 
    END BEFORE STATEMENT; 

    AFTER EACH ROW IS 
    BEGIN 
    IF :NEW.COPIES < 0 THEN 
     tblDELETE_IDS.EXTEND; 
     tblDELETE_IDS(tblDELETE_IDS.LAST) := :NEW.ID; 
    END IF; 
    END AFTER EACH ROW; 

    AFTER STATEMENT IS 
    BEGIN 
    IF tblDELETE_IDS.COUNT > 0 THEN 
     FOR I IN tblDELETE_IDS.FIRST..tblDELETE_IDS.LAST LOOP 
     DELETE FROM MY_TABLE 
      WHERE ID = tblDELETE_IDS(I); 
     END LOOP; 
    END IF; 
    END AFTER STATEMENT; 
END COMPOUND_ZERO_COPIES_TRIGGER; 

共有して楽しむ:、あなたはまだのように、恐ろしい「変異TABLE」のエラーを回避しながら、テーブルスキャンを必要とせずに、削除を処理するために、複合トリガーを使用することができます。

関連する問題