【実務・中級編】 PL/pgSQLの基本構造 – PostgreSQL

こんにちは!データベースエンジニアの現場からお届けします。

さて、今回はPostgreSQLにおける「PL/pgSQL」の基本構造について深掘りしていこうと思います。

正直、SQLだけでバリバリやりたい気持ちはわかります。でもね、複雑な業務ロジックをSQLのクエリだけで解決しようとして、気がついたら「メンテナンス不能な巨大なJOIN地獄」になっていた……なんて経験、誰しも一度はあるはずです。

そんな時に頼れるのが、PostgreSQLの手続き型言語「PL/pgSQL」です。ただの構文暗記じゃなくて、「なぜこう書くのか」という設計の心構えを交えて解説しますね。

—

PL/pgSQLの基本形は「ブロック」にある

PL/pgSQLの最大の特徴は、「ブロック構造」です。これ、プログラミング言語で言うところの「関数」や「メソッド」の単位だと思ってください。

基本の型はこんな感じです。

[ <<ラベル>> ]
[ DECLARE
— 変数宣言エリア ]
BEGIN
— 処理実行エリア
EXCEPTION
— 例外処理エリア
END [ ラベル ];

この「DECLARE」「BEGIN」「EXCEPTION」という3つのセクションを使いこなせるようになると、DB内でのロジック構築がグッと楽になります。

1. DECLARE:変数の「置き場所」を確保する

ここは、そのブロック内で使う変数や定数を定義する場所です。
実務のコツですが、「変数名は型がわかるように」しておくのが鉄則です。例えば `user_id` と書くより、`v_user_id`(variableのv)や `c_limit`(constantのc)のようにプレフィックスをつけると、後から読んだ時に「あ、これは変数だな」と直感的にわかります。

DECLARE
v_user_name TEXT;
v_record_count INTEGER := 0; — 初期値もここで代入できるのが便利!

2. BEGIN – END:ここが「戦場」

実際にデータを操作するメインのエリアです。SQLのSELECTやINSERTはもちろん、IF文やLOOP処理なんかもここに書きます。

気をつけたいのは、「ここでやりすぎないこと」。PL/pgSQLは強力ですが、ロジックを詰め込みすぎるとデバッグが地獄になります。「複雑な計算はアプリ側に任せる」という引き算の美学も忘れないでくださいね。

3. EXCEPTION:転ばぬ先の杖

ここが一番重要かもしれません。実務で一番怖いのは「処理の途中でエラーが起きて、中途半端なデータが残ること」です。

BEGIN
INSERT INTO logs (message) VALUES (‘処理開始’);
— ここで何かが起きるかもしれない
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE ‘エラーが発生しました: %’, SQLERRM;
— 必要ならここでロールバックの挙動を調整する
END;

`EXCEPTION`を書いておくと、予期せぬエラーで処理が全停止するのを防げます。「とりあえずエラーをキャッチしてログに出す」だけでも、トラブルシューティングの時間は劇的に短縮されますよ。

—

実践例:こんな風に使ってみよう

例えば、「特定のユーザーのステータスを更新し、履歴テーブルにレコードを追加する」という処理。これを一つのブロックにまとめると、トランザクションの整合性が保証されるので非常に安全です。

CREATE OR REPLACE FUNCTION update_user_status(p_user_id INT, p_status TEXT)
RETURNS VOID AS $$
DECLARE
v_old_status TEXT;
BEGIN
— 現在のステータスを退避
SELECT status INTO v_old_status FROM users WHERE id = p_user_id;

— 更新実行
UPDATE users SET status = p_status WHERE id = p_user_id;

— 履歴保存
INSERT INTO user_history (user_id, old_status, new_status, updated_at)
VALUES (p_user_id, v_old_status, p_status, NOW());

EXCEPTION
WHEN OTHERS THEN
RAISE EXCEPTION ‘ユーザー更新失敗 (ID: %): %’, p_user_id, SQLERRM;
END;
$$ LANGUAGE plpgsql;

—

先輩エンジニアからのアドバイス

PL/pgSQLを書き始めると、楽しくて何でもかんでもDBにロジックを詰め込みたくなる時期が来ます。でも、ちょっと立ち止まって考えてみてください。

  • 「そのロジック、DBの中でやる必要ある?」
  • 「アプリ側で書いたほうがテストしやすくない?」

DBにロジックを置くのは、あくまで「データの整合性を担保するため」や「ネットワーク往復回数を減らしてパフォーマンスを稼ぐため」といった明確な理由がある時だけにしましょう。

基本構造をマスターすれば、DBはただの入れ物から、自律的に動く「賢いエンジン」へと進化します。ぜひ、まずは小さなプロシージャから書いて試してみてくださいね!

何か詰まったら、いつでも聞いてください。応援しています!

コメント

タイトルとURLをコピーしました