我有以下postgres功能
CREATE OR REPLACE FUNCTION refresh_materialized_view(name)
RETURNS integer AS
$BODY$
DECLARE
_table_name ALIAS FOR $1;
_entry materialized_views%ROWTYPE;
_result INT;
BEGIN
SELECT * INTO _entry FROM materialized_views WHERE table_name = _table_name;
BEGIN;
EXECUTE 'CREATE TEMP TABLE new_materialized_view_rows ON COMMIT DROP AS SELECT * FROM ' || _entry.view_name;
EXECUTE 'TRUNCATE TABLE ' || _table_name;
EXECUTE 'INSERT INTO ' || _table_name || ' SELECT * FROM new_materialized_view_rows';
UPDATE materialized_views
SET last_refresh = CURRENT_TIMESTAMP
WHERE table_name = _table_name;
COMMIT;
EXECUTE 'ANALYZE ' || table_name;
RETURN 1;
END
$BODY$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER;
ALTER FUNCTION refresh_materialized_view(name) OWNER TO portal;
该函数是从非事务性上下文调用的,所以我附上了使用
更新数据的语句BEGIN;
COMMIT;
以便这些语句以原子方式执行。但是,当我执行上面的脚本时,我收到以下错误:
ERROR: syntax error at or near ";"
LINE 16: BEGIN;
答案 0 :(得分:1)
函数始终是调用事务的一部分。您无法在函数中提交事务。因此,您需要在调用代码中执行以下操作:
begin;
select efresh_materialized_view('foobar');
commit;
“从非交易环境调用该函数”
这是不可能的。如果没有PostgreSQL中的事务,您将无法工作。您可能是指“自动提交”模式,它隐含地提交每个语句 - 但这仍然是事务性的。
答案 1 :(得分:0)
您不能在函数中使用COMMIT。无论如何,这个函数都是事务性的,这就是为什么你不需要第二个BEGIN;同样。这也是你的错误,这是它失败的地方。