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



我的触发器有问题。我创建了一个触发器和一个函数来跟踪数据库中每个用户使用的行数。触发器和函数的INSERT部分工作正常,但DELETE什么也不做。当我在应用程序中插入行时,行数会增加,当我删除时,行计数不会改变。

这是我保存行计数的表:

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

这是我的触发器:

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;

有什么想法吗?非常感谢,Shea

在我最初的帖子之后,我回去简化了这个问题。我将TRIGGER和FUNCTION分解为单独的INSERT和DELETE活动。INSERT触发器和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触发器的问题从未得到解决,但使用带有RETURN OLD的BEFORE似乎是一个不错的替代方法。通过对某些变量进行硬编码,问题与函数中OLD.result__id的使用有关。

返回NULL将取消INSERT/DELETE操作。(您可以将其用于过于复杂的引用完整性,而不能通过简单的约束来强制执行。)

您希望从DELETE返回OLD,从INSERT返回NEW

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;

*我想是的

最新更新