複数の例外ブロック
ROLLBACK TO と SAVEPOINT は、例外ハンドラーを含む関数内では使用できないため、入れ子のブロックを使って同様の動作を擬似的に実現します。これらの入れ子ブロックは、相互依存するステートメントを依存順にグループ化・整列させるために使います。ここでは、SAVEPOINT を模倣する例外ハンドラー付きのレコード挿入ブロックを作成し、その後に例外ハンドラー付きでレコードを更新します。その更新ステートメントはエラーになり、例外ハンドラーがそのブロックだけを自動的にロールバックします。
この演習はコースの一部です
PostgreSQL におけるトランザクションとエラー処理
演習の手順
- 最初のブロックでは、
patientsに次のレコードをEXCEPTIONハンドラー付きで挿入します。a1c=5.6,glucose=93,fasting=TRUE、(6.3, 111, TRUE)、(4.7, 65, TRUE)。失敗時はerrorsにmsgとして'failed to insert'を挿入します。 - 2つ目の入れ子ブロックを開き、ID が 1 の患者の
fasting値を'true'に更新します。例外発生時は、errorsテーブルにmsgとして'Inserted string into boolean.'を記録します。 - 両方のブロックを
ENDします。
実践的なインタラクティブ演習
このサンプルコードを完成させて、この演習に挑戦してみましょう。
-- Make a DO function
DO $$
-- Open a transaction block
BEGIN
-- Open a nested block
BEGIN
INSERT INTO ___ (___, ___, ___)
VALUES (5.6, 93, TRUE), ___, ___;
-- Catch all exception types
EXCEPTION WHEN others THEN
INSERT INTO ___ (msg) VALUES ('failed to insert');
-- End nested block
END;
-- Begin the second nested block
BEGIN
UPDATE patients SET ___ = '___' WHERE id=1;
-- Catch all exception types
EXCEPTION WHEN others THEN
INSERT INTO errors (msg) VALUES ('Inserted ___ into ___.');
-- End the second nested block
END;
-- END the outer block
END;
$$ language 'plpgsql';
SELECT * FROM errors;