PostgreSQL AFTER INSERT触发器可防止插入

时间:2016-07-29 09:15:37

标签: postgresql triggers

我有一个PostgreSQL 9.3数据库。我使用log4net配置在表中插入错误:log_messages。 我有一个网页,以图表等方式很好地显示错误。 因为我使用相当复杂的视图,这个网页非常慢,所以我转到了物化视图。我的页面又快了。

现在我需要保持物化视图与我的表/视图同步。所以我在桌面上创建了一个AFTER INSERT触发器:

CREATE TRIGGER refresh_mv_insert
  AFTER INSERT
  ON log_messages
  FOR EACH ROW
  EXECUTE PROCEDURE refresh_mv();

我的refresh_mv()更复杂,但即使这个简化版本也不起作用:

CREATE OR REPLACE FUNCTION refresh_mv()
  RETURNS trigger AS
$BODY$
DECLARE
 l_view_name character varying := 'mv_log_messages';
begin

  EXECUTE 'REFRESH MATERIALIZED VIEW ' || l_view_name;  

  RETURN NEW;
end;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

当我将其更改为匿名过程时,完整版和简化版可以正常工作。所以看起来我在Trigger部分有一个错误。

我已经阅读了两天的文档和类似的Q& A但是我无法让它工作。 非常感谢任何帮助。

修改:澄清

在我的完整触发程序中,我使用配置表来存储刷新时间戳,并且我不会在一小时内刷新。

当我启用触发器时,记录不会保存到log_messages表中。

我不知道如何阅读任何触发错误。我在哪里可以找到它们?

这是我的完整代码:

CREATE OR REPLACE FUNCTION refresh_mv()
  RETURNS trigger AS
$BODY$
DECLARE
 l_last_refresh timestamp;
 l_view_name character varying := 'mv_log_messages';
 l_num_new smallint;
 l_refresh boolean := false;
begin
  l_refresh := false;
  -- check the last time:
  select last_refresh, num_new into l_last_refresh, l_num_new from config where view_name = l_view_name;

  -- refresh every hour
  if (l_last_refresh  + interval '1 hour' < current_timestamp) then
    l_refresh := true;
  end if;

  -- refresh every 10 inserts, but not more often than every 10 minutes:
  if (l_num_new > 9 and l_last_refresh  + interval '10 minutes' < current_timestamp) then
    l_refresh := true;
  end if;

  if l_refresh then
    -- Reset config and do refresh:
    update config set last_refresh = current_timestamp, num_new = 0 where view_name = l_view_name;
    -- this line prevents the insertion of the record EXECUTE 'REFRESH MATERIALIZED VIEW ' || l_view_name;  
  else
    -- Update counter:
    update config set num_new = l_num_new + 1 where view_name = l_view_name;
  end if;

  RETURN NULL;
end;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

此触发器有效,因为我评论了行EXECUTE 'REFRESH MATERIALIZED VIEW ' || l_view_name;

0 个答案:

没有答案