2016-05-17 12 views
2

私はすべての票の合計が100を通過していないことを確認するために、このトリガーを持っている:実行トリガ - PostgreSQLの9.4

CREATE FUNCTION limit_votes() RETURNS TRIGGER AS $limit_votes$ 
    DECLARE 
     votes_total int; 
    BEGIN 
     votes_total := NEW.vote + (SELECT SUM(vote) FROM cars WHERE portfolio_id = NEW.portfolio_id AND car != NEW.car); 
     IF votes_total > 100 THEN 
      RAISE EXCEPTION 'votes_limit_exceeded'; 
     END IF; 
     RETURN NEW; 
    END; 
$limit_votes$ LANGUAGE plpgsql; 
CREATE TRIGGER limit_votes BEFORE INSERT OR UPDATE ON cars FOR EACH ROW EXECUTE PROCEDURE limit_votes(); 

それは「投票」ができることを言及しなければなりません更新されるので、INSERTだけではありません。 これは私の問題が発生した場所です.1人のユーザーが車の投票を変更し、1行の更新が100を超える可能性があるため、他の更新が他の投票を減らす前にトリガーが発行されます。

私はそれが意味をなさないと思います。

私は、BEGIN ... COMMITの後にトリガーを呼びたいので、すべてを順番にチェックする前に複数の行を更新できますが、ユーザーが例外を更新しようとすると結果が保存されません。

答えて

7

トリガーは、制約条件と「後」トリガーでなければなりません。その後、DEFERRABLEを使用することができます。

CREATE CONSTRAINT TRIGGER limit_votes 
AFTER INSERT OR UPDATE ON cars 
DEFERRABLE 
FOR EACH ROW EXECUTE PROCEDURE limit_votes(); 

は、ドキュメントを参照してください:

http://www.postgresql.org/docs/9.1/static/sql-createtrigger.html

+0

がするの変更 ")(PROCEDUREのlimit_votesをEXECUTE EACH ROW、車のDEFERRABLE ON INSERT OR UPDATE BEFOREトリガーのlimit_votesを作成します。" "DEFERRABLE"またはその近くの構文エラーで失敗します。 –

+0

@MichaelNielsen私は答えを更新しました。 – freakish

+0

AFTERトリガーの場合、「不正」なものが更新されたらどうなりますか?それはまだ捨てられますか? –

関連する問題