【PL/SQL】静的SQLカーソルに値を渡す(引数)

2020年10月27日

PL/SQLでSQLの条件値が、都度、変わる場合にどうしていますか?
悪い例と良い例を提示していきます。
今回は、静的SQLカーソルの場合です

変数を使用する(悪い例①)

「wkSHNCD」の変数で仲介し、カーソルに値を指定しています
保守性等を考えると、良い方法とは言えません

DECLARE
    wkSHNCD VARCHAR2(5);
 
    CURSOR csrTEST IS
        SELECT *
          FROM TESTTBL
         WHERE (SHNCD = wkSHNCD);
 
    DB_TEST csrTEST%ROWTYPE;
BEGIN
    wkSHNCD := '00001';
 
    OPEN csrTEST;
    LOOP
        FETCH csrTEST INTO DB_TEST;
        EXIT WHEN csrTEST%NOTFOUND;
    END LOOP;
    CLOSE csrTEST;
 
    wkSHNCD := '00002';
 
    OPEN csrTEST;
    LOOP
        FETCH csrTEST INTO DB_TEST;
        EXIT WHEN csrTEST%NOTFOUND;
    END LOOP;
    CLOSE csrTEST;
END;

カーソルを必要なだけ作成する(悪い例②)

PL/SQLをやり始めで、静的SQLの認識が無い時にやりがちです
力押しです
パターンが多い時、後々パターンが増える時、良い所がありません
そもそも、可読性が最悪です

DECLARE
    CURSOR csrTEST1 IS
        SELECT *
          FROM TESTTBL
         WHERE (SHNCD = '00001');
 
    DB_TEST1 csrTEST1%ROWTYPE;
 
    CURSOR csrTEST2 IS
        SELECT *
          FROM TESTTBL
         WHERE (SHNCD = '00002');
 
    DB_TEST2 csrTEST2%ROWTYPE;
BEGIN
    OPEN csrTEST1;
    LOOP
        FETCH csrTEST1 INTO DB_TEST1;
        EXIT WHEN csrTEST1%NOTFOUND;
    END LOOP;
    CLOSE csrTEST1;
 
    OPEN csrTEST2;
    LOOP
        FETCH csrTEST2 INTO DB_TEST2;
        EXIT WHEN csrTEST2%NOTFOUND;
    END LOOP;
    CLOSE csrTEST2;
END;

カーソルに値を渡す(引数)(良い例)

関数に値を渡すのと同じ方法で、静的カーソルにも値を渡せます
CUSOR宣言時に、カーソル名の右横に括弧書きで引数を指定します
引数の名称は任意です
複数の引数を指定する場合はカンマ「,」で区切ります
引数の型(NUMBER、VARCHAR2等)を指定しますが、桁数の指定は必要ありません
OPEN時にカーソル名の右横に渡す値を指定します
下記の例では固定値を渡していますが、変数値も渡せます

DECLARE
    CURSOR csrTEST(IN_SHNCD IN VARCHAR2, IN_KEYNO IN NUMBER) IS
        SELECT *
          FROM TESTTBL
         WHERE (SHNCD = IN_SHNCD) AND
               (KEYNO = IN_KEYNO);
 
    DB_TEST csrTEST%ROWTYPE;
BEGIN
    OPEN csrTEST('00001', 42);
    LOOP
        FETCH csrTEST INTO DB_TEST;
        EXIT WHEN csrTEST%NOTFOUND;
    END LOOP;
    CLOSE csrTEST;
  
    OPEN csrTEST('00002', 56);
    LOOP
        FETCH csrTEST INTO DB_TEST;
        EXIT WHEN csrTEST%NOTFOUND;
    END LOOP;
    CLOSE csrTEST;
END;

まとめ

PL/SQLを始めたばかりの頃は、静的SQLに馴染めなくないでしょうか?
それはPL/SQL(ストアドプロシージャ)以外でSQLを記述する場合は、動的SQLだからです(フレームワークで隠蔽されていても・・・)
PL/SQLでは、馴染みのある動的SQLが敷居が高く、馴染みの無い静的SQLの敷居が低い文法となっています
UPDATE、INSERTになると、カーソル定義も必要なくベタ書きで動きます
ただ、可変が必要になると、動的SQLが必須なので別の記事を参考にステップアップしてみて下さい

【PL/SQL】メニュー

サイトマップ

2020年10月27日Oracle,PL/SQL,SQL,データベース

Posted by こっぷ