BEGIN
之后的语法错误。如果我通过像这样的分号添加命令终止命令:
BEGIN;
它会告诉我近乎错误的错误。 我意识到,也许我正在混合控制结构和交易的语法,但是我找不到任何关于如何在文档中退缩的交易(也不是这样)。i还认为,也许交易会自动回滚,但似乎并非如此,因为以下脚本:
EXCEPTION
使我感到震惊:
BEGIN;
-- 1) Execute some valid actions;
-- 2) Execute some action that causes an error.
COMMIT;
我必须手动手动
ERROR: current transaction is aborted, commands ignored until end of transaction block
ROLLBACK;
,也喜欢:
DO
Pgadmin用A击中了我:DO $$
BEGIN
-- 1) Execute some valid actions;
-- 2) Execute some action that causes an error.
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END; $$
关于劳伦兹的评论:“您的SQL脚本将包含一个提交。这结束了交易并将其退回。” - 这是我观察到的行为。请考虑以下示例(这只是我原始问题中已经提供的示例的具体版本):
ERROR: cannot begin/end transactions in PL/pgSQL. HINT: Use a BEGIN block with an EXCEPTION clause instead.
当我执行上面的脚本时,我会受到:
BEGIN;
-- Just a simple, self-referencing table.
CREATE TABLE "Dummy" (
"Id" INT GENERATED ALWAYS AS IDENTITY,
"ParentId" INT NULL,
CONSTRAINT "PK_Dummy" PRIMARY KEY ("Id"),
CONSTRAINT "FK_Dummy_Dummy" FOREIGN KEY ("ParentId") REFERENCES "Dummy" ("Id")
);
-- Foreign key violation terminates the transaction.
INSERT INTO "Dummy" ("ParentId")
VALUES (99);
COMMIT;
是预期的。
但是,如果我尝试检查我的ERROR: insert or update on table "Dummy" violates foreign key constraint "FK_Dummy_Dummy". DETAIL: Key (ParentId)=(99) is not present in table "Dummy".
表是被创建还是回滚,则是这样的:
Dummy
启用一个简单的SELECT EXISTS (
SELECT FROM information_schema."tables"
WHERE "table_name" = 'Dummy');
,我得到的错误与已经提到两次的错误:false
。然后,我必须通过发行ERROR: current transaction is aborted, commands ignored until end of transaction block
。
对我来说,似乎上面提到的评论是错误的,或者至少我在这里误解了某些内容。
除了在某些有限的情况下,您不能在PL/PGSQL中使用
ROLLBACK;
您无需明确的卷回去您的PL/PGSQL代码。只需让异常从PL/PGSQL代码传播,它将导致错误,这将导致整个事务回滚。 您的评论表明,此代码是从SQL脚本调用的。然后,解决方案是在PL/PGSQL代码之后的某个位置将其在该SQL脚本中放置一个。那将结束交易并将其滚回去。
当我试图在脚本提出例外之后尝试运行脚本时,我也有这个错误:
error:当前事务被中止,命令被忽略到交易块结束之前
要修复它,我只是在脚本的开头添加了“回滚”,例如:
ROLLBACK
我认为您必须使用较旧的版本,因为问题的确切代码对我而言而没有错误:
这对我来说也很好,没有例外:
为每次注释
,您可以删除函数中的异常块,如果发生错误,则其中的事务运行将自动回滚。从我有限的测试中,情况似乎就是这种情况。