如何动态执行PostgreSQL RAISE命令

And*_*rus 9 postgresql exception-handling plpgsql

如果满足某些条件,如何从PostgreSQL SQL语句中引发错误?
我试过下面的代码,但得到了错误.

CREATE OR REPLACE FUNCTION "exec"(text)
  RETURNS text AS
$BODY$ 
    BEGIN 
      EXECUTE $1; 
      RETURN $1; 
    END; 
$BODY$
  LANGUAGE plpgsql VOLATILE;

-- ERROR:  syntax error at or near "raise"
-- LINE 1: raise 'test' 

SELECT exec('raise ''test'' ') WHERE TRUE
Run Code Online (Sandbox Code Playgroud)

在实际应用TRUE中被某些条件所取代.

更新

我试图扩展答案以传递异常消息参数.尝试下面的代码,但语法错误.如何传递消息参数?

CREATE OR REPLACE FUNCTION exec(text, variadic ) 
  RETURNS void LANGUAGE plpgsql AS 
$BODY$  
BEGIN  
   RAISE EXCEPTION  $1, $2;  
END;  
$BODY$; 

SELECT exec('Exception Param1=% Param2=%', 'param1', 2 ); 
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 23

您无法在PL/pgSQL中RAISE动态调用(使用EXECUTE) - 仅适用于SQL语句,并且RAISE是PL/pgSQL命令.

使用这个简单的功能:

CREATE OR REPLACE FUNCTION f_exec(text)
  RETURNS void LANGUAGE plpgsql AS
$BODY$ 
BEGIN 
   RAISE EXCEPTION '%', $1; 
END; 
$BODY$;
Run Code Online (Sandbox Code Playgroud)

呼叫:

SELECT f_exec('My message is empty!');
Run Code Online (Sandbox Code Playgroud)

在dba.SE上的相关答案中写了更多:解释,链接,函数的更多选项,函数调用的上下文(包括行号)等.


评论的补充答案

CREATE OR REPLACE FUNCTION f_exec1(VARIADIC text[]) 
  RETURNS void LANGUAGE plpgsql AS 
$BODY$  
BEGIN  
   RAISE EXCEPTION 'Reading % % %!', $1[1], $1[2], $1[3];
END;  
$BODY$; 
Run Code Online (Sandbox Code Playgroud)

呼叫:

SELECT f_exec1('the','manual','educates');
Run Code Online (Sandbox Code Playgroud)
  • VARIADIC不是数据类型,而是参数模式.

  • 元素必须像任何其他数组元素一样处理.

  • 要在RAISE语句中使用多个变量,请将多个变量%放入消息文本中.

如果没有$ 3传递给调用,上面的示例将失败.您必须从可变数量的输入元素中组合一个字符串.例:

CREATE OR REPLACE FUNCTION f_exec2(VARIADIC _arr text[]) 
  RETURNS void LANGUAGE plpgsql AS 
$BODY$  
DECLARE
   _msg text := array_to_string(_arr, ' and '); -- simple string construction
BEGIN  
   RAISE EXCEPTION 'Reading %!', _msg;
END;  
$BODY$; 
Run Code Online (Sandbox Code Playgroud)

呼叫:

SELECT f_exec2('the','manual','educates');
Run Code Online (Sandbox Code Playgroud)

我怀疑你需要一个VARIADIC参数.请阅读此处的手册.
相反,定义所有参数,可能添加默认值:

CREATE OR REPLACE FUNCTION f_exec3(_param1 text = ''
                                  ,_param2 text = ''
                                  ,_param3 text = 'educates') 
  RETURNS void LANGUAGE plpgsql AS 
$BODY$  
BEGIN  
   RAISE EXCEPTION 'Reading % % %!', $1, $2, $3;
END;  
$BODY$; 
Run Code Online (Sandbox Code Playgroud)

呼叫:

SELECT f_exec3('the','manual','educates');
SELECT f_exec3();  -- defaults kick in
Run Code Online (Sandbox Code Playgroud)