CodeGym /コース /SQL SELF /制御構造とロギングの扱いでよくあるミスの分析

制御構造とロギングの扱いでよくあるミスの分析

SQL SELF
レベル 52 , レッスン 4
使用可能

本題に入る前に、みんながよくハマるミスや抜けをちょっと見てみよう。SQLのミスって、エンジニアなら誰でも痛い思いしたことあるよね。しかも、だいたい一番困るタイミングで起きるんだよな。

1. シンタックスエラー: 「IFの閉じ忘れ」

シンタックスエラーは一番基本的な問題だけど、思ったよりよく出る。たとえば、IFの条件ブロックをEND IF;で閉じるのを忘れると、コンパイラにすぐ怒られる。

ミスの例:

CREATE OR REPLACE FUNCTION check_number(num INTEGER)
RETURNS TEXT AS $$
BEGIN
    IF num > 0 THEN
        RETURN 'ポジティブ';
    ELSE
        RETURN 'ネガティブ';
-- どこかでEND IF;が消えた
END;
$$ LANGUAGE plpgsql;

このコードを実行しようとすると、ERROR: syntax error at or near "END"ってエラーが出る。なぜかというと、IFブロックが閉じられてないから。

こういうミスを防ぐには?

いつもコードの構造を意識しよう。ブロック(たとえばIF)を開いたら、すぐに閉じるのも書いておくといい。修正版はこんな感じ:

CREATE OR REPLACE FUNCTION check_number(num INTEGER)
RETURNS TEXT AS $$
BEGIN
    IF num > 0 THEN
        RETURN 'ポジティブ';
    ELSE
        RETURN 'ネガティブ';
    END IF; -- ブロックを閉じるのを忘れずに
END;
$$ LANGUAGE plpgsql;

2. CASEで全条件の処理忘れ: 「どこにも当てはまらなかったら?」

CASEを使うときは、予想外の値が来たときのためにELSEブランチも必ず書こう。これがないと、NULLが返ってきて困ることになる。

ミスの例:

CREATE OR REPLACE FUNCTION grade_result(grade CHAR)
RETURNS TEXT AS $$
BEGIN
    RETURN CASE grade
        WHEN 'A' THEN 'エクセレント'
        WHEN 'B' THEN 'グッド'
        WHEN 'C' THEN 'アベレージ'
        -- もしgrade = 'D'や他の評価だったら?
    END;
END;
$$ LANGUAGE plpgsql;

Dを渡すと、この関数はNULLを返しちゃう。これが原因でバグることもある。

修正版:

CREATE OR REPLACE FUNCTION grade_result(grade CHAR)
RETURNS TEXT AS $$
BEGIN
    RETURN CASE grade
        WHEN 'A' THEN 'エクセレント'
        WHEN 'B' THEN 'グッド'
        WHEN 'C' THEN 'アベレージ'
        ELSE '不明な評価' -- 他のケースもキャッチ
    END;
END;
$$ LANGUAGE plpgsql;

3. 無限ループの問題: 「なんでサーバーが固まったの?」

LOOPを使うとき、抜ける条件を忘れがち。これで無限ループになっちゃう:

ミスの例:

CREATE OR REPLACE FUNCTION infinite_loop_demo()
RETURNS VOID AS $$
DECLARE
    i INTEGER := 1;
BEGIN
    LOOP
        i := i + 1;
        -- 抜ける条件がない!
    END LOOP;
END;
$$ LANGUAGE plpgsql;

このコードはサーバーを固めちゃう。ループが永遠に終わらないから。

修正方法:

EXITで抜ける条件を追加しよう:

CREATE OR REPLACE FUNCTION finite_loop_demo()
RETURNS VOID AS $$
DECLARE
    i INTEGER := 1;
BEGIN
    LOOP
        i := i + 1;
        IF i > 10 THEN
            EXIT; -- 抜ける条件
        END IF;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

4. ループでのイテレーション抜け漏れ: 「足りないデータはどうなる?」

CONTINUEでイテレーションをスキップするとき、全部のパターンをちゃんと考えてないとミスることがある。たとえば:

ミスの例:

CREATE OR REPLACE FUNCTION skip_even()
RETURNS VOID AS $$
DECLARE
    i INTEGER := 0;
BEGIN
    WHILE i < 10 LOOP
        i := i + 1;
        IF i % 2 = 0 THEN
            CONTINUE; -- 偶数はスキップ
        END IF;
        RAISE NOTICE '奇数: %', i;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

もし全部の数字が偶数だったら?サーバーは動くけど、何も表示されない。

修正方法:

全部のデータをちゃんと処理してるか確認して、ログも追加しよう:

CREATE OR REPLACE FUNCTION skip_even_logging()
RETURNS VOID AS $$
DECLARE
    i INTEGER := 0;
BEGIN
    WHILE i < 10 LOOP
        i := i + 1;
        IF i % 2 = 0 THEN
            RAISE NOTICE '偶数スキップ: %', i;
            CONTINUE;
        END IF;
        RAISE NOTICE '奇数: %', i;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

これで、どの数字がスキップされたかも見えるようになる。

5. エラー処理のミス: 「RAISE EXCEPTIONどこいった?」

RAISE EXCEPTIONでエラー処理するのは強力だけど、使い方を間違えるとすぐバグる。

ミスの例:

CREATE OR REPLACE FUNCTION calculate_square(num INTEGER)
RETURNS INTEGER AS $$
BEGIN
    IF num < 0 THEN
        RAISE '負の数はダメだよ!';
    END IF;
    RETURN num * num;
END;
$$ LANGUAGE plpgsql;

このコードはエラーになる。なぜならRAISEのシンタックスが間違ってる(レベル指定がない)。

修正版:

CREATE OR REPLACE FUNCTION calculate_square(num INTEGER)
RETURNS INTEGER AS $$
BEGIN
    IF num < 0 THEN
        RAISE EXCEPTION '負の数はダメだよ!';
    END IF;
    RETURN num * num;
END;
$$ LANGUAGE plpgsql;

6. ロギングのミス: 「なんでerror_logにエラーが書き込まれないの?」

error_logテーブルへの書き込みがうまくいかないのは、INSERT INTOのクエリミスが原因かも。

ミスの例:

CREATE OR REPLACE FUNCTION log_error(err_msg TEXT)
RETURNS VOID AS $$
BEGIN
    INSERT INTO error_log (error_message, error_time)
    VALUES (err_msg, CURRENT_TIMESTAMP); -- カラム名が違ったら?
END;
$$ LANGUAGE plpgsql;

もしerror_logテーブルのカラム名が(たとえばerror_msgに)変わってたら、これでエラーになる。

防ぐには:

テーブル構造をちゃんと確認するか、スキーマをしっかり管理しよう。

7. うっかりミスと「ヒューマンエラー」

ミスは技術的なものだけじゃなくて、うっかりや注意不足でも起きる。デバッグの消し忘れ、使ってない変数、コードのフォーマット崩れ…こういうのがあると、関数がカオスになる。

例:

DECLARE
    i INTEGER; -- 使わない変数、なんであるの?

修正:いらないコードは消して、スッキリ分かりやすくしよう。

これでPL/pgSQLでよくあるミスを避けて、もっと楽しくバグの少ないコードが書けるはず!テスト・ロギング・バグ修正は早めにやって、余計なストレスやクライアントからの電話を減らそう!

1
アンケート/クイズ
エラー処理、レベル 52、レッスン 4
使用不可
エラー処理
エラー処理
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION