Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transaction inside a plpgsql function [duplicate]

I have written a function for automation, mentioned below, which calls some other functions based on some rules. The function is giving me the desired results, but the problem that I am facing is that it does not commit the data after each of the function is processed internally. Once the main function gets completed only then it commits the entire data. I want to do a internal transaction which should commit the data as and when the internal function execution get completed. I tried giving a COMMIT statement after each of the PERFORM statements, but I got an error saying 'cannot begin/end transactions in PL/pgSQL'.

Can anyone suggest how do I go about doing a transaction inside a function.

CREATE OR REPLACE FUNCTION ccdb.fn_automation_for_updation()
  RETURNS void AS
$BODY$

DECLARE 
sec_col refcursor;
cnt integer;
sec_code ccdb.update_qtable%ROWTYPE;
new_cnt integer;

BEGIN

SELECT COUNT(*)
INTO cnt
FROM ccdb.update_qtable
WHERE status_flag IN (-1,1);

OPEN sec_col FOR
    SELECT * FROM ccdb.update_qtable WHERE status_flag IN (-1,1);

FOR i IN 1..cnt
LOOP

    FETCH sec_col INTO sec_code;

        PERFORM ccdb.o_dtr_update(sec_code.section_code);

        PERFORM ccdb.o_consumer_update_for_update(sec_code.section_code);

        PERFORM ccdb.o_consumer_update_for_insert(sec_code.section_code);

        PERFORM ccdb.o_bills_update_for_update(sec_code.section_code);

        PERFORM ccdb.o_bills_update_for_insert(sec_code.section_code);

        PERFORM ccdb.o_payments_update_for_update_new(sec_code.section_code);

        PERFORM ccdb.o_payments_update_for_insert(sec_code.section_code);

        PERFORM ccdb.o_payments_map_update_for_update(sec_code.section_code);

        PERFORM ccdb.o_payments_map_update_for_insert(sec_code.section_code);

        SELECT COUNT(*) INTO new_cnt FROM ccdb.update_qtable WHERE status_flag IN (-1,1);

        IF new_cnt > cnt
        THEN
            CLOSE sec_col;

            OPEN sec_col FOR
                SELECT * FROM ccdb.update_table WHERE status_flag IN (-1,1);

        cnt := new_cnt;

        END IF;

END LOOP;

CLOSE sec_col;

END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
like image 511
Yousuf Sultan Avatar asked Jul 02 '14 05:07

Yousuf Sultan


People also ask

Can we commit inside a function in PostgreSQL?

Basically, PostgreSQL version 11 allows users to perform autonomous transactions like COMMIT or ROLLBACK inside a procedural code that can be invoked using the CALL keyword.

What is Plpgsql function?

With PL/pgSQL you can group a block of computation and a series of SQL queries inside the database server, thus having the power of a procedural language and the ease of use of SQL. Also, with PL/pgSQL you can use all the data types, operators and functions of Greenplum Database SQL.

What does return next do in Plpgsql?

RETURN NEXT and RETURN QUERY do not actually return from the function — they simply append zero or more rows to the function's result set. Execution then continues with the next statement in the PL/pgSQL function. As successive RETURN NEXT or RETURN QUERY commands are executed, the result set is built up.

Is Postgres function transactional?

Yes, functions are transactional, even if written in LANGUAGE SQL .


1 Answers

You cannot perform autonomous transactions in PostgreSQL - its functions don't support it.

You must use DBLink.

See:

  • Committing Records into the table while executing a postgreql Function
  • Are PostgreSQL functions transactional?
  • COMMIT in PostgreSQL stored procedure

(Marked CW because I closed the post)

like image 58
2 revs Avatar answered Nov 13 '22 16:11

2 revs