Postgres触发器适用于INSERT,而不适用于DELETE

时间:2012-03-27 21:15:40

标签: postgresql function triggers

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

这是我保留行数的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();

这是功能:

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;

有什么想法吗? 非常感谢, 乳木果

3 个答案:

答案 0 :(得分:2)

在我的原始帖子之后,我回去简化问题。我将TRIGGER和FUNCTION拆分为单独的INSERT和DELETE活动。 INSERT TRIGGER和FUNCTION都可以作为AFTER触发器继续正常工作。所以我把它排除在帖子之外。这是DELETE触发器的简化问题。

这是我的新TRIGGER:

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触发器的问题从未得到解决,但使用带有RETURN OLD的BEFORE似乎是一个不错的替代品。通过对某些变量进行硬编码,该问题与函数中OLD.result__id的使用有关。

答案 1 :(得分:0)

返回NULL取消INSERT / DELETE操作。 (您可以将它用于参照完整性太复杂,无法使用简单约束强制执行。)

您想从OLD返回DELETE,从NEW返回INSERT

答案 2 :(得分: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;

*我想是的