【入門編】 PL/pgSQLのカーソル – PostgreSQL

こんにちは!データベースエンジニアとして日々PostgreSQLと格闘している私ですが、今日は「PL/pgSQLのカーソル」という、ちょっと玄人っぽく聞こえるテーマについてお話ししたいと思います。

「カーソル」って聞くと難しそうですよね。でも、大丈夫。実は私たちの日常にある「ある行動」と全く同じ考え方なんです。

そもそも「カーソル」って何?

データベースからデータを取り出すとき、通常は `SELECT FROM …` のように一気に結果を受け取りますよね。でも、もしその結果が100万行もあったらどうでしょう? メモリがパンクしてしまいますし、何より人間が一度に処理するのは不可能です。

ここで登場するのが「カーソル」です。

これを「レストランの注文伝票」に例えてみましょう。
キッチン(データベース)から料理(データ)が出てくるとき、ホールスタッフ(カーソル)が伝票を片手に、「次は1番テーブルのハンバーグ、次は2番テーブルのパスタ…」と、一品ずつ丁寧にお客さんに運んでいく様子をイメージしてください。

全部一気にテーブルに叩きつけるのではなく、状況を見ながら「次の一皿」を運ぶ。これがカーソルの本質です。

—

カーソルの基本的な使い方

PL/pgSQLでカーソルを使うには、大きく分けて4つのステップがあります。おまじないだと思って見てみてください。

1. 宣言(準備をする)

まずは、「どのデータを扱うか」という伝票を準備します。

DECLARE
my_cursor CURSOR FOR SELECT name FROM users;

「これからユーザーの名前リストを取り扱うよ」という宣言です。まだ何も動いていません。

2. OPEN(伝票を開く)

さあ、いよいよ仕事開始です。

OPEN my_cursor;

これでデータベースに対して「さっきのリスト、準備して!」と合図を送ります。

3. FETCH(一品ずつ運ぶ)

ここが一番のポイント。`FETCH`を使って、データを一行ずつ取り出します。

FETCH my_cursor INTO user_name;

これで「次の一行」を`user_name`という変数に詰め込むことができます。

4. CLOSE(伝票を閉じる)

仕事が終わったら、忘れずに片付けましょう。

CLOSE my_cursor;

これでメモリも解放されてスッキリです。

—

ループで回すのが「実戦」のコツ

実際には、一行ずつFETCHしては処理する…という動作を、データがなくなるまで繰り返すことが多いです。そんな時は `LOOP` 文と組み合わせるのが定石です。

OPEN my_cursor;

LOOP
FETCH my_cursor INTO user_name;
— データがなくなったらループを抜ける(EXIT WHEN NOT FOUND)
EXIT WHEN NOT FOUND;

— ここで何かしらの処理をする
RAISE NOTICE ‘処理中のユーザー: %’, user_name;
END LOOP;

CLOSE my_cursor;

こうすることで、「100万行あっても、一気に読み込まずに安全に処理する」という、プロの現場でもよく使われる堅実なコードが書けるようになります。

—

最後のアドバイス

カーソルは便利ですが、「なんでもかんでもカーソルで回せばいい」というわけではありません。実は、SQLは「集合」で処理するのが一番速いように設計されています。

「どうしても一行ずつ順番に複雑な処理をしないといけない!」という時にこそ、このカーソルという秘密兵器を思い出してください。

最初は難しく感じるかもしれませんが、まずは小さなテーブルで試してみてくださいね。「おっ、一行ずつ取れてる!」という実感が湧いてくれば、もうあなたはPostgreSQLの扱いを一つマスターしたも同然です。

また次回の記事でも、現場の小ネタをシェアしていきますね。データベースライフを一緒に楽しみましょう!

コメント

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