Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute PostgreSQL RAISE command dynamically

How to raise error from PostgreSQL SQL statement if some condition is met?
I tried code below but got error.

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

In real application TRUE is replaced by some condition.

Update

I tried to extend answer to pass exception message parameters. Tried code below but got syntax error. How to pass message parameters ?

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 ); 
like image 873
Andrus Avatar asked Aug 11 '12 19:08

Andrus


People also ask

What is := in PostgreSQL?

= is for comparison. := is for assignment.

What is raise notice in PostgreSQL?

RAISE is used to raise errors and report messages, PostgreSQL provides various parameters to report an error, warning, and information at a detailed level.

How do you pass parameters in PostgreSQL query?

The get_sum() function accepts two parameters: a, and b, and returns a numeric. The data types of the two parameters are NUMERIC. By default, the parameter's type of any parameter in PostgreSQL is IN parameter. You can pass the IN parameters to the function but you cannot get them back as a part of the result.


1 Answers

You cannot call RAISE dynamically (with EXECUTE) in PL/pgSQL - that only works for SQL statements, and RAISE is a PL/pgSQL command.

Use this simple function instead:

CREATE OR REPLACE FUNCTION f_raise(text)
  RETURNS void
  LANGUAGE plpgsql AS
$func$
BEGIN
   RAISE EXCEPTION '%', $1;
END
$func$;

Call:

SELECT f_raise('My message is empty!');

Related:

  • Generate an exception with a Context

Additional answer to comment

CREATE OR REPLACE FUNCTION f_raise1(VARIADIC text[])
  RETURNS void
  LANGUAGE plpgsql AS
$func$
BEGIN 
   RAISE EXCEPTION 'Reading % % %!', $1[1], $1[2], $1[3];
END
$func$;

Call:

SELECT f_raise1('the','manual','educates');
  • VARIADIC is not a data type, but an argument mode.

  • Elements have to be handled like any other array element.

  • To use multiple variables in a RAISE statement, put multiple % into the message text.

The above example will fail if no $3 is passed. You'd have to assemble a string from the variable number of input elements. Example:

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

Call:

SELECT f_raise2('the','manual','educates');

I doubt you need a VARIADIC parameter for this at all. Read the manual here.
Instead, define all parameters, maybe add defaults:

CREATE OR REPLACE FUNCTION f_raise3(_param1 text = ''
                                  , _param2 text = ''
                                  , _param3 text = 'educates')
  RETURNS void
  LANGUAGE plpgsql AS
$func$
BEGIN
   RAISE EXCEPTION 'Reading % % %!', $1, $2, $3;
END 
$func$;

Call:

SELECT f_raise3('the','manual','educates');

Or:

SELECT f_raise3();  -- defaults kick in
like image 114
Erwin Brandstetter Avatar answered Oct 08 '22 08:10

Erwin Brandstetter