2017-09-22 1:40 GMT+02:00 mike davis <mike.davi...@hotmail.com>:

> I’m trying to get dynamic version of the RAISE command working so that I
> can use a table of custom application error messages and codes for use by
> all developed plpgsql functions. In this way the customer error codes and
> message are not hard coded into code and are defined consistently in one
> place in the db.
>
>
> However, I cannot get a dynamic/parameterised version of the RAISE command
> working with the USING syntax - I want to do this so that i can catch the
> raised error in an EXCEPTION block.
>
>
> The following example shows a example of (working) hardcoded version:
>
>
> DO
>
> $$
>
> DECLARE
>
>
> BEGIN
>
>   RAISE EXCEPTION 'Something is wrong' USING errcode = 'E0001';
>
>
> EXCEPTION
>
>   WHEN SQLSTATE 'E0001' THEN
>
>      RAISE NOTICE '%','Error E0001 raised - going to do something about
> it';
>
>   WHEN OTHERS THEN
>
>      RAISE NOTICE 'OTHER ERRORS: %', sqlstate;
>
>
>
> END
>
> $$
>
>
> Which raises and catches the custom error E0001 and returns (as expected)
>
> NOTICE:  Error E0001 raised - going to do something about it.
>
>
> Now what I am trying to achieve is as above but for the msg text and
> errcode to be retrieved from a table before issuing the RAISE EXCEPTION
> statement.
>
>
> ie. Assume v_msg and v_sqlstate have been retrieved and contain:
>
> v_msg = 'Something is wrong’
>
> v_sqlstate =  ‘E0001’
>
>
> The what I want to raise dynamically is:
>
>
> RAISE EXCEPTION v_msg USING errcode = v_sqlstate;
>
>
> and be able to use the same exception block as above in the hard coded
> example.
>
>
> I searched and found a couple of similar examples where
>
> RAISE EXCEPTION ’%’, i_msg
>
> is used and works but this does not allow a custom SQLSTATE to be raised
> and trapped.
>
>
> ie. The following runs ok:
>
>
> DO
>
> $$
>
> DECLARE
>
>
> v1 TEXT ;
>
>
> BEGIN
>
>
>
>   v1 := 'SOMETHING IS WRONG';
>
>   RAISE NOTICE '%', v1;
>
>   RAISE EXCEPTION '%', v1;
>
>
> EXCEPTION
>
>   WHEN SQLSTATE 'E0001' THEN
>
>      RAISE NOTICE '%','Error E0001 raised - going to do something about
> it';
>
>   WHEN OTHERS THEN
>
>      RAISE NOTICE 'OTHER ERRORS: %', sqlstate;
>
>
>
> END
>
> $$
>
>
> and returns:
>
> NOTICE:  SOMETHING IS WRONG
>
> NOTICE:  OTHER ERRORS: P0001
>
>
> but obviously the WHEN OTHERS has caught the exception and the SQLSTATE is
> the default P0001.
>
>
> So, then what i really want is similar to the above but with the USING
> keyword of RAISE being dynamic/parameterised.
>
>
> So i tried the following:
>
>
> DO
>
> $$
>
> DECLARE
>
>
> v_msg TEXT := '''SOMETHING IS WRONG''';
>
> v_sqlstate TEXT := '''E0001''';
>
> v1 TEXT ;
>
>
> BEGIN
>
>   v1 := v_msg || ' USING errcode = ' || v_sqlstate;
>
>   RAISE NOTICE '%', v1;
>
>   RAISE EXCEPTION '%', v1;
>
>
> EXCEPTION
>
>   WHEN SQLSTATE 'E0001' THEN
>
>      RAISE NOTICE '%','Error E0001 raised - going to do something about
> it';
>
>   WHEN OTHERS THEN
>
>      RAISE NOTICE 'OTHER ERRORS: %,%', sqlstate,sqlerrm;
>
>
>
> END
>
> $$
>
>
> which returns:
>
> NOTICE:  'SOMETHING IS WRONG' USING errcode = 'E0001'
>
> NOTICE:  OTHER ERRORS: P0001,'SOMETHING IS WRONG' USING errcode = 'E0001'
>
>
> So clearly the whole of v1 (whilst syntatically correct) is treated as the
> message and the default sqlstate of P0001 is still raised and caught by
> WHEN OTHERS.
>
>
> Have tried a few other things but cannot find way to get a custom
> errcode/sqlstate to be raised except by hardcoding it ! I’m sure there must
> be a way to do this!
>

It is not allowed in PLpgSQL - it is based on origin PL/SQL and the master
origin ADA language - these languages are static to be possible do deep
static analyse.

If you need this, then you can use PLPythonu or some own C extension.

Regards

Pavel


> Any help or advice on how to achieve this very much appreciated !
>

Reply via email to