Dam*_*yer 3 postgresql plpgsql
我正在尝试学习 PostgreSQL 存储过程。具体在 PSQL 中创建以下过程。
CREATE OR REPLACE PROCEDURE BUILD_AND_POPULATE(INOUT cresults refcursor)
LANGUAGE PLPGSQL
AS $$
BEGIN
BEGIN; -- I've tried removing this but the behaviour is the same
cresults:= 'cur';
DROP TABLE IF EXISTS procsampledata;
CREATE TABLE procsampledata as select x,1 as c2,2 as c3, md5(random()::text) from generate_series(1,10) x;
COMMIT;
OPEN cresults FOR SELECT * FROM procsampledata;
END;
$$;
Run Code Online (Sandbox Code Playgroud)
然后我像这样执行它,但收到一个错误:
postgres=# call build_and_populate(null);
ERROR: invalid transaction termination
CONTEXT: PL/pgSQL function build_and_populate(refcursor) line 6 at COMMIT
Run Code Online (Sandbox Code Playgroud)
我试过将 AUTOCOMMIT 设置为打开和关闭。
这是我的 Postgres 版本
PostgreSQL 11.5 on x86_64-pc-linux-musl, compiled by gcc (Alpine 8.3.0) 8.3.0, 64-bit
Run Code Online (Sandbox Code Playgroud)
谁能看到我做错了什么?谢谢!
这
BEGIN;
Run Code Online (Sandbox Code Playgroud)
是错误的,会导致错误。您不能在过程中启动事务,因为已经有一个活动事务。
您可以结束一个事务,这意味着立即开始一个新事务。
如果没有BEGIN;,您的程序就可以正常工作。
问题一定出在你调用它的方式上。正如文档所说:
事务控制只能在
CALL或DO来自顶层的调用或嵌套的 CALL 或 DO 调用中进行,而没有任何其他干预命令。例如,如果调用堆栈是CALL proc1()→CALL proc2()→CALL proc3(),那么第二个和第三个过程可以执行事务控制动作。但是如果调用栈是CALL proc1()→SELECT func2()→CALL proc3(),那么最后一个过程不能做事务控制,因为SELECT中间。
SELECT您的调用堆栈中可能有一个。
另一种可能性是您BEGIN 在调用存储过程之前显式启动了一个事务。
这也不起作用,这是一个未记录的实现限制,将来可能会修复。请参阅此线程以供参考。
| 归档时间: |
|
| 查看次数: |
7492 次 |
| 最近记录: |