2016-09-22 7 views
0

ブール型の列を追加したテーブルがありますdone この列がTrueの場合、その行の未処理のアクション(削除、更新)を防止したいと思います。テーブルの更新または削除を防止する

私はこのトリガーを書いた:

CREATE TRIGGER productstock_beforeupdate 
    BEFORE UPDATE OR DELETE 
    ON table 
    FOR EACH ROW 
    EXECUTE PROCEDURE trig() 

CREATE OR REPLACE FUNCTION trig() 
    RETURNS trigger AS 
$$ 
begin 
    if TG_OP='UPDATE' or TG_OP='DELETE' then 
     if old.done=true then 
        raise exception 'cant do that'; 
      return null; 
     end if; 
    end if; 
    return new; 
end; 
$$ 

autorizedトランザクションがデータを変更したい場合は、このトリガーを無効にする最初のを持っています。

私はそれは私が「0行が削除された」と、削除を実行しません返し

done=False 

で行を削除しようとすると、このアイデアは、しかし、動作するはずです。

私の引き金に何が間違っていますか?

+0

トリガーを削除すると、削除が機能します。 – ban

+0

@a_horse_with_no_name done = falseの場合、削除と更新の両方が機能しない – ban

+0

DML?私はこれがdoesntの仕事だと思っています。なぜなら、トリガーはbefore after – ban

答えて

1

これは、更新のためにあなたがNEWレコードを返す必要があるという事実によって引き起こされます。ただし、DELETEを実行するには、OLDレコードを返す必要があります。トリガ機能が返された行の値が、新しい(または値に等しいそれに)変更することなく正常に成功するトリガーアクションを望む場合

Quote from the manualしたがって

、[...]なおNEW DELETEトリガーではnullなので、それを返すのは通常は分かりません。通常、DELETEトリガーのイディオムはOLDを戻すことです。

だからあなたのトリガ関数は次のようになります。トリガーは、それがoldを返すべきDELETE可能にすると

CREATE OR REPLACE FUNCTION trig() 
    RETURNS trigger AS 
$$ 
begin 
    -- no need to check for the action here as the trigger 
    -- will only fire for UPDATE or DELETE 
    if old.done then 
    raise exception 'cant do that'; 
    return null; 
    end if; 

    if TG_OP='UPDATE' then 
    return new; 
    end if; 

    if TG_OP='DELETE' then 
    return old; 
    end if; 
end; 
$$ 
language plpgsql; 
1

UPDATEの場合はnewを返します。 例外が発生した場合は、何も返す必要はありません。

create or replace function trig() 
    returns trigger language plpgsql as 
$$ 
begin 
    if old.done then 
     raise exception 'cant do that'; 
    end if; 
    if tg_op = 'DELETE' then 
     return old; 
    else 
     return new; 
    end if; 
end $$; 
関連する問題