はじめに
この実験(Lab)では、PL/pgSQL を使用して PostgreSQL のエラー処理テクニックを探求します。通知(notice)の発生、例外(exception)の捕捉、エラーのログ記録、およびエラー処理ロジックのテスト方法を学びます。この実験(Lab)は初心者向けに設計されており、各ステップをガイドします。
この実験(Lab)では、PL/pgSQL を使用して PostgreSQL のエラー処理テクニックを探求します。通知(notice)の発生、例外(exception)の捕捉、エラーのログ記録、およびエラー処理ロジックのテスト方法を学びます。この実験(Lab)は初心者向けに設計されており、各ステップをガイドします。
このステップでは、PL/pgSQL 関数内で通知(notice)を発生させる方法を学びます。通知(notice)は、デバッグやフィードバックの提供に役立つ情報メッセージです。エラーよりも重大度が低く、関数の実行を停止しません。
まず、postgres
ユーザーとして PostgreSQL データベースに接続します。
sudo -u postgres psql
次に、greet
という名前の関数を作成します。この関数は名前を入力として受け取り、挨拶メッセージとともに通知(notice)を発生させます。psql
シェルで次の SQL コマンドを実行します。
CREATE OR REPLACE FUNCTION greet(name TEXT)
RETURNS TEXT AS $$
BEGIN
RAISE NOTICE 'Hello, %!', name;
RETURN 'Greeting sent!';
END;
$$ LANGUAGE plpgsql;
この関数は、TEXT
型の name
引数を受け取ります。RAISE NOTICE 'Hello, %!', name;
の行は、通知(notice)メッセージを表示します。%
はプレースホルダーであり、name
変数の値に置き換えられます。その後、関数は文字列 'Greeting sent!'
を返します。
'LabEx'
という名前で関数を呼び出してみましょう。
SELECT greet('LabEx');
次のような出力が表示されるはずです。
NOTICE: Hello, LabEx!
greet
-----------
Greeting sent!
(1 row)
NOTICE
メッセージ "Hello, LabEx!" が表示され、RAISE NOTICE
ステートメントが実行されたことがわかります。
RAISE WARNING
や RAISE INFO
など、さまざまなレベルの通知(notice)を使用することもできます。RAISE WARNING
は潜在的な問題を示し、RAISE INFO
は重要度の低い情報を提供します。
名前が空の場合に警告(warning)を発生させるように関数を変更してみましょう。
CREATE OR REPLACE FUNCTION greet(name TEXT)
RETURNS TEXT AS $$
BEGIN
IF name = '' THEN
RAISE WARNING 'Name is empty!';
ELSE
RAISE NOTICE 'Hello, %!', name;
END IF;
RETURN 'Greeting sent!';
END;
$$ LANGUAGE plpgsql;
ここで、空の文字列で関数を呼び出すと:
SELECT greet('');
警告(warning)メッセージが表示されます。
WARNING: Name is empty!
greet
-----------
Greeting sent!
(1 row)
これは、PL/pgSQL 関数内で RAISE NOTICE
および RAISE WARNING
を使用してフィードバックを提供する方法を示しています。
このステップでは、EXCEPTION
ブロックを使用して PL/pgSQL で例外(exception)を捕捉する方法を学びます。例外処理(exception handling)を使用すると、エラーを適切に処理し、関数がクラッシュするのを防ぎ、有益なエラーメッセージを提供できます。
例外(exception)ブロックの基本的な構造は次のとおりです。
BEGIN
-- 例外が発生する可能性のあるコード
EXCEPTION
WHEN exception_name THEN
-- 例外を処理するコード
END;
BEGIN
および END
キーワードは、例外が発生する可能性のあるコードのブロックを定義します。EXCEPTION
キーワードは、例外処理(exception handling)セクションを導入します。WHEN
句は捕捉する例外(exception)のタイプを指定し、THEN
に続くコードは、その例外が発生したときに実行されます。
0 で除算しようとし、結果として発生する例外(exception)を捕捉する関数を作成しましょう。safe_divide
という名前を付けます。
CREATE OR REPLACE FUNCTION safe_divide(numerator INTEGER, denominator INTEGER)
RETURNS INTEGER AS $$
BEGIN
RETURN numerator / denominator;
EXCEPTION
WHEN division_by_zero THEN
RAISE NOTICE 'Division by zero occurred!';
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
この関数は、2 つの整数引数 numerator
と denominator
を取ります。BEGIN
ブロック内で、numerator
を denominator
で除算しようとします。denominator
が 0 の場合、division_by_zero
例外(exception)が発生します。EXCEPTION
ブロックはこの例外(exception)を捕捉し、通知(notice)を発生させ、NULL
を返します。
次に、除数が 0 の関数を呼び出してみましょう。
SELECT safe_divide(10, 0);
次のような出力が表示されるはずです。
NOTICE: Division by zero occurred!
safe_divide
-------------
NULL
(1 row)
NOTICE
メッセージ "Division by zero occurred!" が表示され、関数は NULL
を返します。これは、例外(exception)が捕捉され、処理されたことを示しています。
次に、有効な入力で関数を呼び出してみましょう。
SELECT safe_divide(10, 2);
次のような出力が表示されるはずです。
safe_divide
-------------
5
(1 row)
関数は、例外(exception)を発生させることなく、正しい商である 5 を返します。
numeric_value_out_of_range
、null_value_not_allowed
、others
など、他のタイプの例外(exception)を捕捉することもできます。others
例外ハンドラーは、前の WHEN
句で明示的に処理されていない例外(exception)を捕捉します。
関数を変更して、例外(exception)を捕捉し、-1 を返すようにしましょう。
CREATE OR REPLACE FUNCTION safe_divide(numerator INTEGER, denominator INTEGER)
RETURNS INTEGER AS $$
BEGIN
RETURN numerator / denominator;
EXCEPTION
WHEN division_by_zero THEN
RAISE NOTICE 'Division by zero occurred!';
RETURN NULL;
WHEN OTHERS THEN
RAISE NOTICE 'An unexpected error occurred: %', SQLERRM;
RETURN -1;
END;
$$ LANGUAGE plpgsql;
この変更された関数では、division_by_zero
以外の例外(exception)が発生した場合、OTHERS
例外ハンドラーが実行されます。SQLERRM
は、例外(exception)に関連付けられたエラーメッセージを含む組み込み変数です。
この実験(Lab)では、PL/pgSQL を使用して PostgreSQL のエラー処理テクニックを探求しました。情報メッセージを提供するために、RAISE NOTICE
、RAISE WARNING
、および RAISE INFO
を使用して関数内で通知(notice)を発生させる方法を学びました。また、BEGIN...EXCEPTION...END
ブロックを使用して例外(exception)を捕捉し、監査とデバッグのためにエラーの詳細をテーブルに記録する方法も学びました。最後に、堅牢性を確保するために、エラー処理ロジックのテストを練習しました。