CodeGym /コース /SQL SELF /PL/pgSQLでのループの使い方: LOOP, FOR, WHILE

PL/pgSQLでのループの使い方: LOOP, FOR, WHILE

SQL SELF
レベル 51, レッスン 1
使用可能

ループを使うと、特定の条件が満たされている間や、データセットをイテレートしている間、同じコードブロックを何度も実行できるんだ。これはタスクの自動化や大量データの処理、繰り返し作業にめっちゃ便利!

例えば、グループの子供たち全員に手作業でキャンディーを配るとしたら、カオスだよね!でも、子供たちのリストを順番に回って一人ずつキャンディーを渡せばOK。この「リストを回る」ってのがループなんだ。

PostgreSQLではいくつかのループが使えるよ:

  1. LOOP — 明示的に止めるまでずっと実行される汎用ループ。
  2. FOR — 数値の範囲やクエリ結果を指定回数イテレートするループ。
  3. WHILE — 条件がtrueの間だけ実行されるループ。

それぞれのループを詳しく見ていこう!

無限ループ:LOOP

LOOPはPL/pgSQLの基本的なループで、コードブロックを繰り返し実行するよ。このループは無限に動き続けるから、EXITコマンドで手動で抜ける必要がある。

構文:

LOOP
    -- ここに自分のコードを書く
END LOOP;

例を見てみよう。LOOPで1から10までの合計を計算するよ:

DO $$
DECLARE
    counter INT := 1;
    sum INT := 0;
BEGIN
    LOOP
        sum := sum + counter; -- 現在のカウンター値を足す
        counter := counter + 1; -- カウンターを増やす

        -- カウンターが10を超えたらループ終了
        IF counter > 10 THEN
            EXIT;
        END IF;
    END LOOP;

    RAISE NOTICE '1から10までの合計: %', sum;
END $$;
  1. counter変数は毎回増える。
  2. IF counter > 10 THEN EXIT;の条件でカウンターが10を超えたらループ終了。
  3. 最後に合計を表示するよ。

範囲やデータセットのループ: FOR

2つ目のループ、FORは次の用途で使えるよ:

  1. 数値の範囲をイテレートする。
  2. SQLクエリの結果をイテレートする。

数値範囲のループ

構文:

FOR variable IN [REVERSE] start..end LOOP
    -- ここに自分のコードを書く
END LOOP;

1から5までの数字を表示してみよう:

DO $$
BEGIN
    FOR i IN 1..5 LOOP
        RAISE NOTICE '現在の値: %', i;
    END LOOP;
END $$;

逆順の例:

DO $$
BEGIN
    FOR i IN REVERSE 5..1 LOOP
        RAISE NOTICE '逆順: %', i;
    END LOOP;
END $$;

SQLクエリ結果のループ

このパターンはテーブルの行を処理したいときに便利!

構文:

FOR variable IN QUERY (SELECT ...) LOOP
    -- ここに自分のコードを書く
END LOOP;

テーブルstudentsの行をイテレートする例:

DO $$
DECLARE
    student_name TEXT;
BEGIN
    FOR student_name IN QUERY (SELECT name FROM students) LOOP
        RAISE NOTICE 'やあ、%!', student_name;
    END LOOP;
END $$;

条件付きループ:WHILE

WHILEは指定した条件がtrueの間だけ実行されるループだよ。

構文:

WHILE 条件 LOOP
    -- ここに自分のコードを書く
END LOOP;

WHILEで1から10までの合計を計算してみよう:

DO $$
DECLARE
    counter INT := 1;
    sum INT := 0;
BEGIN
    WHILE counter <= 10 LOOP
        sum := sum + counter;
        counter := counter + 1;
    END LOOP;

    RAISE NOTICE '1から10までの合計: %', sum;
END $$;

リアルな例

ループの基本がわかったところで、実際の使い方を見てみよう!

例1: 掛け算表の生成

DO $$
DECLARE
    i INT;
    j INT;
BEGIN
    FOR i IN 1..5 LOOP
        FOR j IN 1..5 LOOP
            RAISE NOTICE '% x % = %', i, j, i * j;
        END LOOP;
    END LOOP;
END $$;

例2: クエリ結果のイテレーション。 例えば、productsテーブルにidpriceカラムがあるとする。全商品の価格を10%アップデートしよう。

DO $$
DECLARE
    prod RECORD;
BEGIN
    FOR prod IN QUERY (SELECT id, price FROM products) LOOP
        UPDATE products
        SET price = prod.price * 1.1
        WHERE id = prod.id;
    END LOOP;
END $$;

よくあるミスとその回避法

LOOPWHILEでの無限ループ。 抜ける条件(EXITWHILEの正しい条件)を忘れると、ループが永遠に終わらない。ブレーキなしで車を運転するようなもんだね。

クエリ結果のイテレーション時のエラー。 期待したデータ構造と違うと、FOR IN QUERYループでエラーになることがあるよ。

ループ内の非効率なクエリ。 例えば、毎回UPDATEを実行するとめっちゃ遅くなる。こういう場合はループじゃなくて1つのSQLクエリでまとめて処理した方がいいよ。

2
タスク
SQL SELF, レベル 51, レッスン 1
ロック未解除
クエリのイテレーションに `FOR` を使う
クエリのイテレーションに `FOR` を使う
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION