Postgres/plpgsql中如何报告出错的行?

9

我在Postgres中使用类似于以下内容的东西来仿效SQL Server中我使用Try/Catch块和可以在Catch中回滚事务的方法,以防错误发生:

do $$
begin
[SQL here]

exception when others then
    raise notice 'Error in insert statement ---> % %', SQLERRM, SQLSTATE LINE;
end;    

$$ language 'plpgsql';

有没有一种方法可以报告发生错误的行,比如“ERROR_LINE()”?
提前感谢。
2个回答

13
在一些现代的PostgreSQL中,你可以使用GET STACKED DIAGNOSTICS语句。虽然没有获取行号的可能性,但是你可以获取调用上下文,其中包括行号:

在一些现代的PostgreSQL中,你可以使用GET STACKED DIAGNOSTICS语句。虽然无法获取行号,但是可以获取调用上下文,其中包含行号:

postgres=> DO $$
DECLARE 
  a int DEFAULT 0;
  _c text;
BEGIN
  BEGIN
    PERFORM 10/a;
  EXCEPTION WHEN OTHERS THEN
    GET STACKED DIAGNOSTICS _c = PG_EXCEPTION_CONTEXT;
    RAISE NOTICE 'context: >>%<<', _c;
  END;
END;
$$;
NOTICE:  00000: context: >>SQL statement "SELECT 10/a"
PL/pgSQL function inline_code_block line 7 at PERFORM<<
LOCATION:  exec_stmt_raise, pl_exec.c:3041
DO

只是让大家知道,这仅适用于9.2及以上版本。我甚至确认它在9.1上无法工作。 - Daniel L. VanDenBosch

1
DO $$
DECLARE 
a int DEFAULT 0;
      m_sqlstate text;
      m_message text;
      m_context text;
      m_PG_EXCEPTION_HINT text;
BEGIN
      PERFORM 10/a;
      EXCEPTION WHEN OTHERS THEN
GET STACKED DIAGNOSTICS
      m_sqlstate = returned_sqlstate,
      m_message = message_text,
      m_context = pg_exception_context,
      m_PG_EXCEPTION_HINT = PG_EXCEPTION_HINT;
         RAISE NOTICE 'sqlstate: %', m_sqlstate; --show for error code .
         RAISE NOTICE 'message: %', m_message;
         RAISE NOTICE 'context: %', m_context;
         RAISE NOTICE 'The exception detail: %', m_PG_EXCEPTION_HINT;
END
$$;

Result:

NOTICE:  sqlstate: 22012
NOTICE:  message: division by zero
NOTICE:  context: SQL statement "SELECT 10/a"
PL/pgSQL function inline_code_block line 9 at PERFORM
NOTICE:  The exception detail:
DO
  • 获取诊断堆栈的手册参考,特别是检查表 43.2. 错误诊断项
  • PostgreSQL错误代码在手册的附录中,不易找到。

正如您所看到的:pg_exception_context将报告发生的行。在PostgreSQL版本:14上测试过。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接