2

ユーザー定義関数で以前の操作をキャンセルすることはできますか?

例えば:

CREATE OR REPLACE FUNCTION transact_test () RETURNS BOOLEAN
AS $$
    BEGIN

        UPDATE table1 SET ...

        UPDATE table2 SET ...

        IF some_condition THEN
            --Here is  possible to cancel  all above operations?
            RETURN FALSE; 
        END IF;

        RETURN TRUE;
    END;
$$
LANGUAGE plpgsql;
4

1 に答える 1

3

これまでの両方の答えは正しくありません。
トランザクションを開始しようとしたりSAVEPOINT、plpgsql 関数内で使用しようとすると、次のようなエラー メッセージが表示されます。

ERROR:  cannot begin/end transactions in PL/pgSQL
HINT:  Use a BEGIN block with an EXCEPTION clause instead.
CONTEXT:  PL/pgSQL function "f_savepoint" line 6 at SQL statement

SAVEPOINTプレーン SQL 関数内で試してみると、次のようになります。

ERROR:  SAVEPOINT is not allowed in a SQL function
CONTEXT:  SQL function "f_savepoint2" during startup

エラー メッセージに示されているように、代わりに plpgsql 関数内でBEGINブロックを使用してください。デモは次のようになります。

CREATE OR REPLACE FUNCTION transact_test(boolean)
  RETURNS boolean AS
$func$
BEGIN -- start a nested BEGIN block
    UPDATE t SET i = i+1 WHERE i = 1;
    UPDATE t SET i = i+1 WHERE i = 3;
    IF $1 THEN
        RAISE EXCEPTION 'foo';  -- cancels all of the above
    END IF;

    RETURN TRUE;

EXCEPTION WHEN OTHERS THEN
    RETURN FALSE; 
    -- do nothing
END
$func$ LANGUAGE plpgsql;

-> SQLfiddleがすべてを示しています。

于 2013-05-22T22:31:15.530 に答える