我有一个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;