【PL/SQL】静的SQLカーソルに値を渡す(引数)
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が必須なので別の記事を参考にステップアップしてみて下さい