Que*_*tin 13 postgresql error-handling plpgsql
当 PostgreSQL 抛出异常时,有一行“CONTEXT”,如:
ERROR: INSERT has more target COLUMNS than expressions
LINE 3: ...
^
QUERY: INSERT INTO ...
CONTEXT: PL/pgSQL FUNCTION "XXXXX" line 4 at SQL statement
Run Code Online (Sandbox Code Playgroud)
但是当我抛出异常时,这条线不存在。我没有找到如何添加它。
RAISE EXCEPTION 'blablabla' USING HINT = 'blablablabla';
Run Code Online (Sandbox Code Playgroud)
是否可以将此行添加到我的异常中?
Erw*_*ter 15
没有直接的方法可以输出CONTEXT带有用户定义异常的行。这个选项在 PostgreSQL 9.1 中(还)没有实现。
然而,我发现了一个...
...应该完美无缺。调用另一个为您引发错误(警告、通知、..)的函数。可选择使用自定义消息和CONTEXT. 适用于PostgreSQL 9.0 或更高版本:
CREATE OR REPLACE FUNCTION f_raise(_lvl text = 'EXCEPTION'
, _msg text = 'Default error msg.')
RETURNS void
LANGUAGE plpgsql AS
$func$
BEGIN
CASE upper(_lvl)
WHEN 'EXCEPTION' THEN RAISE EXCEPTION '%', _msg;
WHEN 'WARNING' THEN RAISE WARNING '%', _msg;
WHEN 'NOTICE' THEN RAISE NOTICE '%', _msg;
WHEN 'DEBUG' THEN RAISE DEBUG '%', _msg;
WHEN 'LOG' THEN RAISE LOG '%', _msg;
WHEN 'INFO' THEN RAISE INFO '%', _msg;
ELSE RAISE EXCEPTION 'f_raise(): unexpected raise-level: "%"', _lvl;
END CASE;
END
$func$;
COMMENT ON FUNCTION f_raise(text, text) IS 'Raise error or given level with msg and context.
Call from inside another function instead of raising an error directly
to get plpgsql to add CONTEXT (with line number) to error message.
$1 .. error level: EXCEPTION | WARNING | NOTICE | DEBUG | LOG | INFO
$2 .. error message';
Run Code Online (Sandbox Code Playgroud)
使用该函数引发如下错误:
CREATE OR REPLACE FUNCTION test_err(text)
RETURNS void
LANGUAGE plpgsql AS
$func$
BEGIN
-- do stuff
IF TRUE THEN -- some condition here?
-- instead of raising error like this:
-- RAISE EXCEPTION 'unexpected parameter: "%"', $1;
PERFORM f_raise('EXCEPTION', 'My message "' || $1 || '"');
END IF;
END
$func$;
Run Code Online (Sandbox Code Playgroud)
称呼:
SELECT test_err('wrong parameter');
Run Code Online (Sandbox Code Playgroud)
该函数带有默认值,在调用中丢失时会启动。结合命名参数,您几乎可以做任何事情。例子:
SELECT f_raise();
SELECT f_raise('WARNING');
SELECT f_raise(_msg := 'boohoo');
SELECT f_raise(_lvl := 'WARNING');
Run Code Online (Sandbox Code Playgroud)