Postgres一直在抱怨关于EXCEPTION关键字的问题。

huangapple go评论55阅读模式
英文:

Postgres keeps complaining about the EXCEPTION keyword

问题

根据这个 PostgreSQL 文档中的 "43.6.8. 捕获错误" 主题,处理异常的正确语法是:

BEGIN;
-- SQL 语句
EXCEPTION WHEN Others THEN 
    -- 异常处理逻辑
END;

然而,当我在 pgAdmin 中使用这个语法时,它一直抱怨关键字 EXCEPTION

我的查询是:

BEGIN;
    INSERT INTO TestTable (id) VALUES(3);
    COMMIT;
    EXCEPTION WHEN Others THEN 
        ROLLBACK;
END;

错误是:

ERROR:  syntax error at or near "EXCEPTION"
LINE 4:  EXCEPTION WHEN Others THEN 
         ^ 

SQL state: 42601
Character: 57

我不明白这个 SQL 代码可能出了什么问题。如果这不是处理异常的正确方式,那么我应该如何实现类似的功能?

更新:这不是 Aurora PostgreSQL。我正在使用标准的 PostgreSQL。

英文:

According to the 43.6.8. Trapping Errors topic in this Postgres Documentation, the correct syntax for handling exceptions is:

BEGIN;
-- SQL Statement
EXCEPTION WHEN Others THEN 
	-- Exception Handling Logic
END;

This is while when I use this syntax in pgAdmin, it keeps complaining about the keyword EXCEPTION.

My Query is:

BEGIN;
	INSERT INTO TestTable (id) VALUES(3);
	COMMIT;
	EXCEPTION WHEN Others THEN 
		ROLLBACK;
END;

And the error is:

ERROR:  syntax error at or near "EXCEPTION"
LINE 4:  EXCEPTION WHEN Others THEN 
         ^ 

SQL state: 42601
Character: 57

I don't understand what could be possibly wrong with this SQL Code. If this is not the right way to handle exceptions, then how can I implement something similar?

UPDATE: This is NOT Aurora Postgres. I am using Standard Postgres.

答案1

得分: 2

你引用的是PL/pgSQL文档,但你必须在查询工具中输入SQL。这些是不同的语言,所以正确的PL/pgSQL会引发错误。

如果你想使用PL/pgSQL,你必须创建一个函数或存储过程,或者你可以在SQL中使用DO语句。

你的代码还有两个问题:

  • BEGIN后面不能有分号,所以你可能引用文档时出现了错误。

  • 不能在带有异常处理程序的块中使用像COMMIT这样的事务管理语句。

英文:

What you quote is the PL/pgSQL documentation, but you have to enter SQL in the query tool. These are different languages, so what would be correct PL/pgSQL causes an error.

If you want to use PL/pgSQL, you have to create a function or procedure, or you could use it in a DO statement in SQL.

There are two more problems with your code:

  • there cannot be a semicolon after BEGIN, so you must have mis-quoted the documentation

  • you cannot use a transaction management statement like COMMIT in a block with an exception handler

答案2

得分: 2

你说你正在使用PgAdmin,所以我假设你正在尝试在查询工具窗口中运行此代码?

在这种情况下,你需要将所有内容放在一个DO块中,像这样:

do $$
BEGIN
    INSERT INTO testtable (id) VALUES(1);
    INSERT INTO testtable (id) VALUES(2);
    INSERT INTO testtable (id) VALUES(1);
    EXCEPTION 
	WHEN Others THEN 
    RAISE NOTICE 'error occurred';
END; $$

请注意,不需要提交或回滚操作。如果尝试此代码,假设id是主键,你会发现没有任何插入操作。PostgreSQL会自动将所有语句视为一个事务,并在发生异常时将它们全部回滚。

英文:

You say that you are using PgAdmin, so i presume that you are trying to run this code using a query tool window?

In which case you need to place everything within a DO like this:

do $$
BEGIN
    INSERT INTO testtable (id) VALUES(1);
    INSERT INTO testtable (id) VALUES(2);
    INSERT INTO testtable (id) VALUES(1);
    EXCEPTION 
	WHEN Others THEN 
    RAISE NOTICE 'error occurred';
END; $$

Note that there is no need for a commit or a rollback. If you try this code, assuming id is a primary key, you will find that nothing has been inserted. PostgreSQL automatically treats all the statements as one transaction, and rolls them all back, when an exception occurs.

答案3

得分: -1

你可以参考这里来了解如何在 PostgreSQL 中处理异常。

以下是伪代码(来自同一链接),它可能会给你一个思路:

select version() as postgresql_version
$Body$
declare
begin
    -- statements;
exception
    when condition [or condition...] then
       handle_exception;
   [when others then
       handle_other_exceptions;
   ]
end;
$Body$
英文:

You can refer here to get an idea on how to handle exceptions in PostgreSQL.

Here's the pseudocode(from same link), it might give you an idea:

select version() as postgresql_version
$Body$
declare
begin
    -- statements;
exception
    when condition [or condition...] then
       handle_exception;
   [when others then
       handle_other_exceptions;
   ]
end;
$Body$

huangapple
  • 本文由 发表于 2023年6月12日 12:57:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76453745.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定