【実務・中級編】 PL/pgSQLの変数とデータ型 – PostgreSQL

PL/pgSQLの変数と型:コードを「堅牢」にするためのちょっとしたコツ

やあ。PostgreSQLの深淵へようこそ。

普段、SQLをゴリゴリ書いていると、たまに「あぁ、ここでループ処理がしたいな」とか「複雑な条件分岐をサーバーサイドで完結させたいな」って思うこと、あるよね。そんな時に頼りになるのが、PostgreSQLのプロシージャル言語「PL/pgSQL」だ。

でも、いざ書き始めると「変数の宣言ってどうやるんだっけ?」「型の管理が面倒くさいな」なんて悩むことも多いはず。今日は、現場で後輩によく教える、PL/pgSQLの変数とデータ型の「使いこなし術」を共有するよ。

—

1. 変数の基本:宣言と代入の作法

PL/pgSQLで変数を扱うときは、基本的にブロックの先頭(`DECLARE`セクション)で宣言するスタイルが鉄則だ。ここで注意してほしいのは、代入演算子が `=` ではなく `:=` だということ。

DO $$
DECLARE
user_name TEXT := ‘田中太郎’;
user_age INTEGER := 25;
BEGIN
— 代入は := を使う
user_age := user_age + 1;

RAISE NOTICE ‘名前: %, 年齢: %’, user_name, user_age;
END $$;

ここでのポイントは、「初期値を宣言と同時にセットできる」という点。書き忘れを防ぐためにも、可能な限り宣言時に初期化する癖をつけておこう。

—

2. 動的な型定義: `%TYPE` と `%ROWTYPE`

これが今回の本題と言ってもいい。初心者ほど、変数の型を「手動」で決め打ちしがちなんだけど、これは保守性の敵だ。

例えば、テーブルの列定義が変わったとき、それに対応するPL/pgSQL側の変数を全部書き換えるなんて、正気の沙汰じゃないよね。そこで使うのが `属性` という仕組みだ。

%TYPE:特定の列の型を拝借する

「この変数は `users` テーブルの `email` 列と同じ型であってほしい」というときはこう書く。

DECLARE
target_email users.email%TYPE;

これだけで、たとえ将来 `email` 列が `VARCHAR(255)` から `TEXT` に変わっても、このコードは修正不要だ。最高だろ?

%ROWTYPE:テーブルの「行」をまるごと受け取る

テーブルのレコードをそのまま変数に格納したいとき、列を一つずつ宣言するのはナンセンスだ。`%ROWTYPE` を使えば、テーブルの構造をそのまま持った「レコード変数」を作れる。

DECLARE
user_record users%ROWTYPE;
BEGIN
SELECT INTO user_record FROM users WHERE id = 1;
RAISE NOTICE ‘取得したユーザー名: %’, user_record.name;
END;

クエリの戻り値がテーブル構造と同じなら、これを使わない手はないね。

—

3. 「スコープ」を意識する:バグを生まないために

PL/pgSQLにはブロック構造(`BEGIN … END`)がある。ここで注意すべきは、内側のブロックで宣言した変数は、外側のブロックからは見えないという点だ。

また、一番やってしまいがちなのが「列名と変数名を同じにしてしまう」こと。

— 危険な例
DECLARE
user_id INTEGER := 10;
BEGIN
— この WHERE 句の user_id は、どっちを指してる?
— PostgreSQLは混乱して、テーブルの列名を優先しがちだ。
UPDATE users SET status = ‘active’ WHERE user_id = user_id;
END;

これを防ぐための僕の流儀は、「変数には必ず `v_` というプレフィックスを付ける」こと。`v_user_id` と書けば、列名と混同することはない。些細なことだけど、デバッグで頭を抱える時間を激減させてくれるよ。

—

まとめ:現場で意識してほしいこと

今日伝えたかったのは、以下の3点だ。

  • ハードコーディングを避ける: 可能なら `%TYPE` や `%ROWTYPE` を使って、テーブル定義とコードを同期させよう。
  • 変数名にプレフィックスを: チーム開発では必須のマナーだと思っていい。
  • 宣言と初期化はセットで: コードの可読性がグッと上がる。

PL/pgSQLは、ただの「SQLのオマケ」じゃない。正しく使えば、アプリケーション層のロジックを劇的に軽くできる強力なツールだ。ぜひ、次回の開発から意識してみてくれ。

それじゃ、また現場で会おう。良いコードを書いてくれよな!

コメント

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