web-dev-qa-db-ja.com

plpgsql関数内のトランザクション

いくつかのルールに基づいて他のいくつかの関数を呼び出す、以下で説明する自動化用の関数を作成しました。関数は私に望ましい結果を与えていますが、私が直面している問題は、各関数が内部で処理された後、データをコミットしないことです。 main関数が完了すると、データ全体がコミットされます。内部関数の実行が完了したときにデータをコミットする内部トランザクションを実行したいと思います。各PERFORMステートメントの後にCOMMITステートメントを指定しようとしましたが、「PL/pgSQLでトランザクションを開始/終了できません」というエラーが発生しました。

関数内でトランザクションを実行する方法を誰かが提案できますか?.

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;
8
Yousuf Sultan

PostgreSQLで自律型トランザクションを実行することはできません-その機能はそれをサポートしていません。

DBLinkを使用する必要があります。

見る:

(投稿を閉じたため、CWとマークされました)

10
Craig Ringer