CodeGym /コース /SQL SELF /ループの中断と継続:EXIT、CONTINUE

ループの中断と継続:EXIT、CONTINUE

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

たまにループは順調に進むけど、「あ、ここで止めたい!」ってタイミングが出てくるよね。ラッキーなことに、PL/pgSQLにはそれを簡単にコントロールできる便利なツールがあるんだ。

EXITでループを中断する

ループが最後まで行く前に終わらせたい時があるよね。例えば、欲しい値を見つけた時とか、エラーを検知した時、ある条件でイテレーションを終わらせたい時とか。そんな時に使うのがEXIT

EXITはループに「もう十分やったから、ここで終わろうぜ」って伝える感じ。

EXITのシンタックスはめっちゃシンプル:

EXIT WHEN 条件;

ここでWHENは、どんな条件でループを終わらせるかを指定するよ。条件を書かないと、EXITはその場でループを即終了させる。

例:指定した値を見つけたらループを終わらせる

例えば、学生番号のカラムがあって、特定のIDの学生を探したいとする。見つけたらループを終わらせたいよね。

DO $$
DECLARE
    student_id INT;
BEGIN
    FOR student_id IN 1..100 LOOP
        RAISE NOTICE '学生IDをチェック中: %', student_id;

        -- 欲しい学生を見つけたらループを終了
        IF student_id = 42 THEN
            RAISE NOTICE 'ID 42の学生が見つかった!';
            EXIT;
        END IF;
    END LOOP;
END $$;

この例では、1から100までの数字をループして「学生」をチェックしてる。ID42を見つけたら、メッセージを出してループを終了するよ。

CONTINUEでイテレーションをスキップする

ループの中で特定のイテレーションだけスキップして、次のイテレーションに進みたい時もあるよね。いらないデータを無視したい時や、特定の条件だけ飛ばしたい時に便利。

CONTINUEは「この条件はパス、次いこ!」って感じ。

CONTINUEEXITと似てるけど、ループ自体を終わらせるんじゃなくて、今のイテレーションだけスキップする:

CONTINUE WHEN 条件;

条件が成立したら、そのイテレーションは終わって、次のイテレーションに進むよ。

例:偶数をスキップする

この例では、1から10までの数字をループして、偶数はスキップして奇数だけ出力するよ。

DO $$
DECLARE
    num INT;
BEGIN
    FOR num IN 1..10 LOOP
        -- 偶数はスキップ
        IF num % 2 = 0 THEN
            CONTINUE;
        END IF;

        RAISE NOTICE '奇数: %', num;
    END LOOP;
END $$;

ここでCONTINUEnum % 2 = 0(つまり偶数)の時にイテレーションをスキップする。結果としてログには奇数だけが出力されるよ。

EXITCONTINUEの組み合わせ

EXITCONTINUEは一緒に使うこともできて、ループをもっと柔軟にコントロールできる。例えば、いらないイテレーションはCONTINUEでスキップして、大事なものを見つけたらEXITでループを終わらせるとか。

例えば、3の倍数は全部スキップして、15になったらループを終了する例を見てみよう。

DO $$
DECLARE
    num INT;
BEGIN
    FOR num IN 1..20 LOOP
        -- 3の倍数はスキップ
        IF num % 3 = 0 THEN
            CONTINUE;
        END IF;

        -- 15になったらループ終了
        IF num = 15 THEN
            RAISE NOTICE '番号%でストップ', num;
            EXIT;
        END IF;

        RAISE NOTICE '現在の番号: %', num;
    END LOOP;
END $$;

このループの流れはこんな感じ:

  • 3の倍数はスキップ(CONTINUE)。
  • 15になったらループ終了(EXIT)。
  • それ以外の数字は出力される。

応用例:不正なデータをスキップ&クリティカルエラーで終了

今度はもうちょっとリアルな課題を考えてみよう。学生リストを処理して、データをチェックする。不正なレコードはスキップして、「クリティカルエラー」があったら処理をやめる、みたいな感じ。

DO $$
DECLARE
    student RECORD;
BEGIN
    FOR student IN
        SELECT * FROM students
    LOOP
        -- 名前がない学生はスキップ
        IF student.name IS NULL THEN
            RAISE NOTICE 'ID%の学生をスキップ: 名前がない', student.id;
            CONTINUE;
        END IF;

        -- クリティカルエラーならループ終了
        IF student.status = 'ERROR' THEN
            RAISE EXCEPTION 'ID%の学生でクリティカルエラー', student.id;
            EXIT; -- この行は実際には不要、RAISE EXCEPTIONで実行が終わるから。
        END IF;

        -- レコードの処理
        RAISE NOTICE '学生を処理中: %', student.name;
    END LOOP;
END $$;

この例では、CONTINUEで名前がない学生をスキップして、EXIT(とRAISE EXCEPTION)で重大なエラーがあったらループを終わらせてる。

実践アドバイス&よくあるミス

条件のロジックに注意しよう。 EXIT WHENCONTINUE WHENの条件式を間違えると、思わぬ動作になることがある。例えば、ループが早く終わりすぎたり、大事なデータをスキップしちゃったり。

CONTINUEの使いすぎに注意。 コードがCONTINUEだらけになってたら、ループのロジックを見直した方がいいかも。もっとシンプルにできるかもよ。

EXITRETURNを混同しないで。 EXITは今のループだけを終わらせるけど、RETURNは関数全体の実行を終わらせる。

無限ループには気をつけて。 LOOPで終了条件を書かずにEXITを忘れると、ループが永遠に回り続けることもあるよ。

2
タスク
SQL SELF, レベル 51, レッスン 2
ロック未解除
リスト内の学生を処理するためのループのスキップと終了
リスト内の学生を処理するためのループのスキップと終了
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION