2

I have a table and 3 functions fntrans-calls->fntrans2-calls->fntrans3

In this example I have removed call of fntrans3();

After this call

SELECT public.fntrans2();

the table t2 contains records, ok, it is clear, rollback works to the savepoint inside of function

But when I do call SELECT public.fntrans();

the table does not contain any rows and output shows notice about exception in fntrans;

Why in the 2nd case exception throwed to the 1st function but when I call fntrans2 only it caught inside this function.

create table t2(ID SERIAL PRIMARY KEY, f1 INTeger);

CREATE OR REPLACE FUNCTION "public"."fntrans" (
)
RETURNS integer AS
$body$
declare d double precision;
BEGIN
raise notice 'fntrans';
  INSERT INTO t2 (f1) VALUES (1);
  INSERT INTO t2 (f1) VALUES (2);
  INSERT INTO t2 (f1) VALUES (3);
  select fntrans2();
  INSERT INTO t2 (f1) VALUES (4);
  RETURN 1;
EXCEPTION  
  WHEN OTHERS THEN 
  BEGIN 
    raise notice 'fntrans exception';
    RETURN 0;
  END;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;


CREATE OR REPLACE FUNCTION public.fntrans2 (
)
RETURNS integer AS
$body$
declare d double precision;
BEGIN
    raise notice 'fntrans2';
    INSERT INTO t2 (f1) VALUES (10);
    INSERT INTO t2 (f1) VALUES (22);
    INSERT INTO t2 (f1) VALUES (30);

    BEGIN
            raise exception 'Oooooppsss 2!';
            INSERT INTO t2 (f1) VALUES (40);
            RETURN 1;
    EXCEPTION   
    WHEN OTHERS THEN RETURN 0;
    END;
END;
$body$
LANGUAGE 'plpgsql' VOLATILE;


CREATE OR REPLACE FUNCTION public.fntrans3 (
)
RETURNS integer AS
$body$
declare d double precision;
BEGIN
   raise notice 'fntrans3';

  INSERT INTO t2 (f1) VALUES (100);
  INSERT INTO t2 (f1) VALUES (200);
  INSERT INTO t2 (f1) VALUES (300);
  raise exception 'Oooooppsss 3!';
  INSERT INTO t2 (f1) VALUES (400);
  RETURN 1;
EXCEPTION  
  WHEN OTHERS THEN RETURN 0;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

1 Answer 1

5

Your problem is the line

select fntrans2();

in fntrans. You cannot use SELECT without an INTO clause in PL/pgSQL.

Without the EXCEPTION block you'll get the following message:

CONTEXT:  SQL statement "select fntrans2()"
PL/pgSQL function fntrans() line 8 at SQL statement
ERROR:  query has no destination for result data
HINT:  If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT:  PL/pgSQL function fntrans() line 8 at SQL statement

That is pretty self-explanatory.
It also explains why you don't see any results from the function fntrans2 – it doesn't get called.

You could change the offending line to

PERFORM fntrans2();
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, you are right, it is 2 different exceptions, thnx!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.