CodeGym /コース /SQL SELF /PL/pgSQLの基本構文

PL/pgSQLの基本構文

SQL SELF
レベル 49, レッスン 3
使用可能

じゃあ、PL/pgSQLをもうちょい深く掘って、実際にガンガン使ってみよう!

コードブロック

PL/pgSQLのコードブロックは、言語の基本的なビルディングブロックだよ。いわば、関数やプロシージャとか、いろんな魔法が乗っかってる骨組みみたいなもん。ブロックはロジックの実行、データ処理、エラー制御とか全部ひとつの「コンテナ」でやってくれる。

PL/pgSQLのブロックは構造化されてて、主に3つのパートがある:

  1. DECLARE: 変数の宣言(オプション)。
  2. BEGIN ... END: メインの実行ブロック。ここでロジックを実行する。
  3. EXCEPTION: エラー処理(オプション)。

たとえば料理のレシピで例えると、材料リストから始まるけど、本当の魔法は調理プロセスで起きるよね。PL/pgSQLで言うと:

  • DECLARE — 材料リスト(変数)。
  • BEGIN ... END — 混ぜたり焼いたり煮たりする場所。
  • EXCEPTION — もし焦げたらどうするかのプラン。

PL/pgSQLブロックの構文

まずは全体の「骨組み」を見てみよう。あとで肉付け(ベジチーズでもOK!)=具体的なロジックを追加するよ。

DO $$
DECLARE
    -- ここで変数を宣言する
    student_count INT;
BEGIN
    -- ここでロジックを実行する
    SELECT COUNT(*) INTO student_count FROM students;
    RAISE NOTICE '学生の合計数: %', student_count;
EXCEPTION
    -- ここでエラーを処理する
    WHEN OTHERS THEN
        RAISE NOTICE 'エラーが発生したよ。';
END;
$$;

これをステップごとに分解してみよう。

  1. DECLARE — ここで変数を宣言する。PL/pgSQLはPostgreSQLで使えるほぼ全てのデータ型をサポートしてるから、INTEGERからちょっと変わったJSONBまでOK。変数を宣言するには、名前・型・必要なら初期値を指定するだけ。

例:

DECLARE
    student_name TEXT;    -- 学生の名前用の変数
    course_count INT := 0; -- 初期値を0にする
    is_graduated BOOLEAN; -- 論理型の変数

変数は初期化してもいいし(course_countみたいに)、しなくてもOK。

  1. BEGIN ... END — メインの実行ブロック。

このパートがロジックの実行担当。ここで:

  • SQLクエリを実行する(SELECT、INSERTなど)。
  • データを操作する。
  • 制御構造を使う(IF、LOOPなど)。
  • RAISEでデバッグメッセージを出す。

例:

BEGIN
    SELECT COUNT(*) INTO student_count FROM students;
    IF student_count > 0 THEN
        RAISE NOTICE '学生がいるよ!';
    ELSE
        RAISE NOTICE '学生が見つからなかった。';
    END IF;
END;
  1. EXCEPTION — エラー処理(オプション)。

もしブロックの実行中にエラーが起きたら、EXCEPTIONセクションでキャッチして、メッセージを出したり別のコードを実行できる。

例:

BEGIN
    SELECT COUNT(*) INTO student_count FROM non_existing_table; -- エラー!
EXCEPTION
    WHEN OTHERS THEN
        RAISE NOTICE 'おっと、何かうまくいかなかった!';
END;

実例:学生のカウント

じゃあ全部まとめて、実際に役立つ例を作ってみよう。studentsテーブルの学生数をカウントして、メッセージを出すPL/pgSQLブロックを書いてみる。

DO $$
DECLARE
    total_students INT; -- 学生数を保存する変数
BEGIN
    -- 学生数をカウント
    SELECT COUNT(*) INTO total_students FROM students;

    -- 結果をメッセージで出す
    RAISE NOTICE '学生数: %', total_students;
EXCEPTION
    -- 例えばテーブルが存在しない場合などのエラーを処理
    WHEN OTHERS THEN
        RAISE NOTICE '学生数カウント中にエラーが発生したよ。';
END;
$$;

このブロックを実行すると、コンソールにメッセージが出る。例:学生数: 42

変数の使い方のポイント

いくつか大事なポイントを見てみよう:

変数への値の代入。 変数に値を入れるには、SELECT INTOを使う:

SELECT COUNT(*) INTO total_students FROM students;

変数の初期化。 宣言時に値を入れなかったら、デフォルト値はNULLになるよ。

例:

DECLARE
    my_var INT; -- 値はNULL

RECORD型の変数。 これはテーブルの行をまるごと入れられる便利な型。例:

DECLARE
    student RECORD;
BEGIN
    SELECT * INTO student FROM students WHERE id = 1;
    RAISE NOTICE '学生名: %, 年齢: %', student.name, student.age;
END;

例:学生のコース数をカウント

今度は実践的な課題:学生が登録してるコース数をカウントして、結果を出そう。

DO $$
DECLARE
    student_id INT := 1;   -- 学生ID
    course_count INT;      -- コース数用の変数
BEGIN
    -- コース数をカウント
    SELECT COUNT(*) INTO course_count
    FROM enrollments
    WHERE student_id = student_id;

    -- メッセージを出す
    RAISE NOTICE '学生ID % は % 個のコースに登録してるよ。', student_id, course_count;
EXCEPTION
    WHEN OTHERS THEN
        RAISE NOTICE '学生ID % の処理中にエラーが発生したよ', student_id;
END;
$$;

このブロックは柔軟で、student_idを変えればいろんな学生のコース数をチェックできるよ。

エラーとその回避法

PL/pgSQLに慣れてないと、ホットドッグが電子レンジで暴れてるみたいに感じるかも。でも大丈夫、最初は「ありがち」なミスにぶつかるもん。いくつか例を挙げるね:

変数の宣言忘れ。 DECLAREで変数を宣言し忘れると、「変数が存在しない」ってエラーになる。

NULLを値として使うミス。 変数を宣言しただけで値を入れてないと、デフォルトはNULL。これが予想外の動作を引き起こすことも。例:

IF my_var = NULL THEN -- 動かない!

IS NULLを使おう:

IF my_var IS NULL THEN

EXCEPTIONセクションの使い方ミス。 たまに全部のエラー(WHEN OTHERS)をキャッチして何もしない人がいるけど、これだと本当の問題が隠れちゃう。エラーメッセージはちゃんと出そう:

RAISE NOTICE 'エラー: %', SQLERRM;
2
タスク
SQL SELF, レベル 49, レッスン 3
ロック未解除
テーブル内のレコード数をカウントする
テーブル内のレコード数をカウントする
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION