2012-03-27 79 views
1

我遇到触发器问题。我创建了一个触发器和一个函数来跟踪每个用户在我的数据库中使用了多少行。触发器和函数的INSERT部分正常工作,但DELETE不执行任何操作。当我在我的应用程序中插入行时,行数会增加,当我删除时,rowcount不会更改。Postgres触发器适用于INSERT,不适用于DELETE

这里就是我把行数表:

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(); 

这里是功能:

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; 

任何想法? 非常感谢, 牛油果

+2

触发似乎没给我。也许问题在别的地方?我猜想内部select会因为外键或其他触发器而返回任何内容?你可以给所有涉及的表的模式?或者只是尝试更改触发器以运行BEFORE DELETE。 – strkol 2012-03-27 21:27:43

+0

我同意strkol,需要一个BEFORE触发器 – 2012-03-27 21:33:45

+0

那么,这很容易尝试。我会给它一个镜头并报告结果。 – 2012-03-27 21:34:26

回答

0

返回NULL取消INSERT/DELETE操作。 (你可以用它为参照完整性太复杂,用一个简单的约束强制执行。)

你想从INSERTDELETENEW返回OLD

+1

错了。返回NULL将取消其余的触发器,但前提是触发器被声明为BEFORE TRIGGER(行级)。在这种情况下,触发器被声明为AFTER,所以你的声明是错误的。 – strkol 2012-03-29 08:01:41

+0

Still - 良好的信息(用于BEFORE触发器):) – jomofrodo 2016-04-16 01:34:04

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(); 

这里是我的新功能:

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; 

这触发现在工作,如果我卸下m_int表行。 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; 

*我是这么认为的

相关问题