今週、久しぶりにAS400でストアド・プロシージャを定義しました。
これまでは、シンプルRPGLEをストアド化するばかりでしたが、今回はSQLRPGLEをストアド化してみたのです。
そこでの学びをまとめておきます。
まず、今回発生したエラーについてのJOBJOGの中身について。
追加のメッセージ情報 メッセージ ID . . . . : SQL0577 送信日付 . . . . . . . : 23/10/17 送信時刻 . . . . . . . : 16:18:56 メッセージ . . : SQL データの変更は許されません。 原因--次のエラーの1つが起こっています。 -- データ・アクセス属性として READS SQL DATA または CONTAINS SQL DATA を 指定して作成された,プロシージャーまたは関数が呼び出されました。 READS SQL DATA または CONTAINS SQL DATA を指定した作成されたプロシージャーまたは関数 ,あるいはそのプロシージャーまたは関数で呼び出されるプロシージャーまたは関 数では,データを変更できず, MODIFIES SQL DATA 属性を持つプロシージャーま たは関数を呼び出すことはできません。 -- データを変更するステートメントがルーチン本体に含まれていると, READS SQL DATA および CONTAINS SQL DATA は, SQL のプロシージャーまたは関数の CREATE PROCEDURE, ALTER PROCEDURE, CREATE FUNCTION, または ALTER FUNCTION の各ステートメントには指定できません。 続く ... 続行するには,実行キーを押してください。
こちらのJOBLOGの確認方法については、下記の手順で行いました。
- Javaを実行したIDE(inteliJ IDEA)をデバッグ・モードで起動し、プロシージャ・コール直後(セッション切断前)でBreak。
- AS400の
WRKACTJOB SBS(QUSRWRK)
コマンドから、ユーザー名が合致するQZDASOINIT
ジョブの中身を確認(5.処理→10. ジョブログの表示)
なるほど!
確かにSQLRPGLEでは、バリバリDELETE文を行っておりました。
下記は、CREATE PROCEDURE命令のプロンプトですが、「SQL 使用状況」というオプションがあったのですね!
上記のエラーが発生したときは、「CONTAINS SQL」を指定していました......。
あらためて「SQL 使用状況」を「4. MODIFIES SQL DATA」にして実行したら、問題なくDELETE処理ができました。
もう、エラーメッセージの通りで、ぐうの音も出ません。
CREATE PROCEDURE ステートメントの指定 選択項目を入力して,実行キーを押してください。 EXTERNAL NAME: プログラム . . . . . . TESTPGM1 名前またはブランク ライブラリー . . . . TESTLIB 名前, リスト は F4 キー IS DETERMINISTIC . . . N Y=YES, N=NO SQL 使用状況 . . . . . 4 1=CONTAINS SQL 2=NO SQL 3=READS SQL DATA 4=MODIFIES SQL DATA CALLED ON NULL INPUT N Y=YES, N=NO SPECIFIC . . . . . . . 名前またはブランク ライブラリー . . . . 名前, リスト は F4 キー F3= 終了 F4= プロンプト F5= 最新表示 F12= 取り消し F20= 名前全体の表示 F21=ステートメント の表示
実際の作成ステートメントは、下記の通り。
「MODIFIES SQL DATA」が記述されています。
CREATE PROCEDURE TESTLIB/TESTPGM1(IN P@YYYM DEC (6, 0), OUT P@QCNT DEC (7, 0), OUT P@RTCD CHAR ( 7)) LANGUAGE RPGLE NOT DETERMINISTIC MODIFIES SQL DATA EXTERNAL NAME TESTLIB/TESTPGM1 PARAMETER STYLE GENERAL
一度理解すれば、何てことはない話なのですが、せっかくなので記事にしてみました。
また、新しい体験があれば、引き続きこちらに掲載していきます!