如何在postgresql/timescaledb中以编程方式调用“刷新物化视图”
我有一个并发运行的测试套件。在我的测试中,我有一个名为refresh\u aggregates的方法,它从根本上对我的视图调用刷新物化视图 我有一个问题,当它们并行发生时,我得到一些奇怪的元组同时更新错误 为了解决这个问题,我设想创建一个过程或函数,该过程或函数将获得一个刷新,然后调用刷新,这样调用就不会中断自身 注意:我在pg服务器12时标1.7上:也在11.6时标1.6上测试 但当我尝试这样做时,我得到了:刷新不能从函数执行 ^--有办法解决这个问题吗?使用sql/plpgsql 我目前的职能如何在postgresql/timescaledb中以编程方式调用“刷新物化视图”,sql,postgresql,timescaledb,Sql,Postgresql,Timescaledb,我有一个并发运行的测试套件。在我的测试中,我有一个名为refresh\u aggregates的方法,它从根本上对我的视图调用刷新物化视图 我有一个问题,当它们并行发生时,我得到一些奇怪的元组同时更新错误 为了解决这个问题,我设想创建一个过程或函数,该过程或函数将获得一个刷新,然后调用刷新,这样调用就不会中断自身 注意:我在pg服务器12时标1.7上:也在11.6时标1.6上测试 但当我尝试这样做时,我得到了:刷新不能从函数执行 ^--有办法解决这个问题吗?使用sql/plpgsql 我目前的职
create or replace procedure refresh_aggregates()
language plpgsql
as $$
begin
perform pg_advisory_lock(124);
execute 'REFRESH MATERIALIZED VIEW daily_events_view';
execute 'REFRESH MATERIALIZED VIEW weekly_events_view';
execute 'REFRESH MATERIALIZED VIEW daily_customer_user_events';
execute 'REFRESH MATERIALIZED VIEW weekly_customer_user_events';
execute 'REFRESH MATERIALIZED VIEW daily_assessments_view';
execute 'REFRESH MATERIALIZED VIEW weekly_assessments_view';
execute 'REFRESH MATERIALIZED VIEW active_user_metrics_by_day';
execute 'REFRESH MATERIALIZED VIEW wau_mau_weekly_customer_insights';
perform pg_advisory_unlock(124);
end;
$$;
call refresh_aggregates();
结果
success.public> call refresh_aggregates()
[2020-05-14 15:54:34] [25001] ERROR: REFRESH cannot be executed from a function
[2020-05-14 15:54:34] Where: SQL statement "REFRESH MATERIALIZED VIEW daily_events_view"
[2020-05-14 15:54:34] PL/pgSQL function refresh_aggregates() line 4 at EXECUTE
如果使用PostgreSQL 11或12,则可以使用存储过程 例如:
create or replace procedure rmv()
language plpgsql
as
$$
begin
execute 'refresh materialized view my_mv';
end;
$$;
我还测试了以下功能:
create or replace function frmv()
returns boolean
language plpgsql
as
$$
begin
refresh materialized view mv;
return true;
end;
$$;
它不会抛出任何错误,并且可以工作:
select frmv();
frmv
------
t
(1 row)
奇怪的是,为什么它可以与execute一起工作而不是正常语法实际上它也可以在第12页的过程中不使用execute。在我的环境中,我也可以使用一个函数:我不明白为什么会出现错误。YIKES-我尝试了这个方法,但它对我不起作用。用更多细节更新问题即使在事务中调用函数,我也无法用第12.2页重现。我在源代码中找到了src/backend/access/transam/xact.c函数PreventInTransactionBlock中错误消息的来源:但仍然不清楚。