2012-03-27 9 views
1

トリガに問題があります。 DB内の各ユーザーが使用している行の数を追跡するためのトリガーと関数を作成しました。トリガと関数のINSERT部分は正常に機能しますが、DELETEは何も行いません。私のアプリケーションに行を挿入すると、行数が上がります。削除すると、行数は変更されません。ここでPostgresトリガはINSERTでは機能し、DELETEでは機能しません

は、私が数えた行を保つTABLEである:ここでは

Table "public.rowcount" 
    Column | Type | Modifiers 
------------+---------+----------- 
user__id | integer | not null 
table_name | text | not null 
total_rows | bigint | 

は私TRIGGERです:

CREATE TRIGGER countrows_m_time 
    AFTER INSERT OR DELETE on m_time 
    FOR EACH ROW EXECUTE PROCEDURE count_rows_m_time(); 

そして、ここでは、FUNCTIONです:

CREATE OR REPLACE FUNCTION count_rows_m_time() 
RETURNS TRIGGER AS 
' 
    BEGIN 
     IF TG_OP = ''INSERT'' THEN 
     UPDATE rowcount 
      SET total_rows = total_rows + 1 
      WHERE table_name = TG_RELNAME 
      AND user__id = (SELECT user__id from vi_m_time_users where m_value_id = NEW.m_value_id); 
     ELSIF TG_OP = ''DELETE'' THEN 
     UPDATE rowcount 
      SET total_rows = total_rows - 1 
      WHERE table_name = TG_RELNAME 
      AND user__id = (SELECT user__id from vi_m_time_users where m_value_id = OLD.m_value_id); 
     END IF; 
     RETURN NULL; 
    END; 
' LANGUAGE plpgsql; 

任意のアイデア? 多くのおかげで、NULLを返す シェイ

+2

トリガが私にはOKと思われると思います。おそらく問題はどこか他の場所ですか?私はいくつかの外部キーまたは他のトリガーのために内部選択が何も返さないと思いますか?関係するすべてのテーブルのスキーマを教えてください。または、トリガーを変更して、BEFORE DELETEを実行してみてください。 – strkol

+0

私はstrkolに同意します.BEFOREトリガーが必要です –

+0

これは簡単に試すことができます。私はそれにショットを与え、結果を報告します。 –

答えて

0

は、INSERTは/ DELETE操作がキャンセルされます。 (あなたは、単純な制約で施行されるにはあまりにも複雑な参照整合性のためにそれを使用することができます。)あなたはINSERTからDELETENEWからOLDを返したい

+1

間違っています。 NULLを戻すと、残りのトリガーは取り消されますが、トリガーがBEFORE TRIGGER(行レベル)として宣言されている場合のみです。この場合、トリガはAFTERとして宣言されているため、文は間違っています。 – strkol

+0

まだ - 良い情報(BEFOREトリガーの場合):) – jomofrodo

1

私の元の投稿の後、私は問題を簡素化するために戻った。私は、TRIGGERとFUNCTIONを別々のINSERTとDELETEアクティビティに分割しました。 INSERT TRIGGERとFUNCTIONの両方がAFTERトリガーとして正常に機能し続けます。だから、私はそれを投稿から除外しました。ここでは、DELETEトリガーの単純な問題があります。ここ

CREATE TRIGGER remrows_m_int 
    BEFORE DELETE on m_int 
    FOR EACH ROW EXECUTE PROCEDURE rem_rows_m_int(); 

そして、私の新しい関数です::私はm_intテーブルに行を削除する場合は、このトリガーは、現在取り組んでいる

CREATE OR REPLACE FUNCTION rem_rows_m_int() 
RETURNS TRIGGER AS 
' 
    BEGIN 
     IF TG_OP = ''DELETE'' THEN 
     UPDATE rowcount 
      SET total_rows = total_rows - 1 
      WHERE table_name = TG_RELNAME 
      AND user__id = (SELECT user__id from vi_m_int_users where result_id = OLD.result__id); 
     END IF; 
     RETURN OLD; 
    END; 
' LANGUAGE plpgsql; 

は、ここに私の新しいTRIGGERです。 AFTERトリガーの問題は決して解決されませんでしたが、BEFOREをRETURN OLDで使用することは大丈夫です。特定の変数をハードコーディングすることにより、問題はOLD.result__idの関数内での使用に関連していました。

0
CREATE OR REPLACE FUNCTION count_rows_m_time() 
RETURNS TRIGGER AS $count_rows_m_time$ 
DECLARE 
    BEGIN 
     IF (TG_OP = 'INSERT') THEN 
     UPDATE rowcount 
      SET total_rows = (total_rows + 1) 
      WHERE table_name = TG_RELNAME 
      AND user_id = (SELECT user_id FROM vi_m_time_users WHERE m_value_id = NEW.m_value_id); 
     ELSIF (TG_OP = 'DELETE') THEN 
     UPDATE rowcount 
      SET total_rows = (total_rows - 1) 
      WHERE table_name = TG_RELNAME 
      AND user_id = (SELECT user_id FROM vi_m_time_users WHERE m_value_id = OLD.m_value_id); 
     END IF; 
     RETURN NULL; 
    END; 
$count_rows_m_time$ LANGUAGE plpgsql; 

*私はそう