これまでの両方の答えは正しくありません。
トランザクションを開始しようとしたり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がすべてを示しています。