Postgresql事务块

ulydmbyx  于 2023-05-28  发布在  PostgreSQL
关注(0)|答案(1)|浏览(116)

我正在尝试理解如何在PostgreSQL中运行事务。下面是一个示例脚本:

DROP TABLE IF EXISTS test;
CREATE TABLE test (
    id INT PRIMARY KEY,
    value INT CHECK(value>=0),
    data VARCHAR(255)
);

START TRANSACTION;
    INSERT INTO test(id,value,data) VALUES (1,1,'apple');
    INSERT INTO test(id,value,data) VALUES (2,2,'banana');
    INSERT INTO test(id,value,data) VALUES (3,-1,'augh!');
COMMIT;

SELECT * FROM test;

当然,在第3个INSERT上有一个错误,它停止了。
当我突出显示从STARTSELECT语句的块并运行时,我得到一个错误。如果我尝试运行SELECT语句,我会得到:
错误:当前事务被中止,命令被忽略,直到事务块结束。
我理解这一点,如果我单独运行COMMIT,我可以继续。我发现事务已经回滚,并且表中没有行,正如我所期望的那样。
有没有一种方法可以做到这一点,而不必单独运行COMMIT?在Microsoft SQL中(是的,我知道,这是不一样的),如果我SET XACT_ABORT ON,它的行为就是这样:我可以突出显示该块,运行它,如果有错误,则提交或回滚事务。

0s0u357o

0s0u357o1#

感谢@AdrianKlaver的评论,我有一个使用匿名代码块的解决方案。

DO $$
BEGIN
    INSERT INTO test(id,value,data) VALUES (1,1,'apple');
    INSERT INTO test(id,value,data) VALUES (2,2,'banana');
    INSERT INTO test(id,value,data) VALUES (3,-1,'augh!');  --  error
EXCEPTION
    WHEN OTHERS THEN ROLLBACK;
END $$;
SELECT * FROM test;

由于如果成功,块将提交,因此其行为与我预期的一样。
如果使用过程,则可以向其提供一些参数,从而使该过程更有用。
在版本11之前,没有匿名代码块或过程语法,我还没有能够使这对函数起作用。

相关问题