前ページにて、SQL命令のエラー時の処理やカーソルループの脱出処理などWHENEVER命令について説明してきましたが、もっと詳しく処理の結果を知りたいために、Pro*COBOLの内部変数について説明します。この領域を『SQL通信領域』(=SQLCA)と言います。
この領域は、DATA DIVISIONにてホスト変数を宣言した後、INCLUDE SQLCAと記述したSQLCAというCOBOLのCOPYファイルに宣言されています。
1.
SQLCODE ・・・ エラーコード (各SQL命令を実行した後格納される。ORA-xxxxxの値。0が正常)
2.
SQLERRM ・・・ エラーメッセージ (VARYING型のため、SQLERRML=文字長と、SQLERRMC=文字列格納領域がある)
3.
SQLERRD(3) ・・・ 実行した処理件数が入ります。
4.
SQLWARN1 ・・・ ホスト変数の桁数が少なく文字列の切捨てが発生した場合“W”が入ります。
5.
SQLWARN3 ・・・ SELECT句にて指定した列数より、INTO句のホスト変数の数が少ない場合“W”が入ります。多いとエラーになります。
6.
SQLWARN4 ・・・ UPDATE命令やDELETE命令にWHERE句がない場合“W”が入ります。
上記3のSQLERRD(3)について説明します。下記のプログラムは正しいですか?
== 問題 ==
000000 MOVE "MANEGER" TO JOB.111111 EXEC SQL UPDATE emp SET sal = sal * 1.2111111 WHERE job = :JOB END-EXEC.
コンパイルもエラー無く正常に行われ、実行してもエラー処理ルーチンに移らず正常に終了しました。これにて単体テストは終了?
それでは、SQLERRD(3)に処理件数が入っているので表示してみましょう。
000000 MOVE "MANEGER" TO JOB.111111 EXEC SQL UPDATE emp SET sal = sal * 1.2111111 WHERE job = :JOB END-EXEC.000000 DISPLAY SQLERRD(3).
実行すると、処理件数が0と表示されました。なぜでしょうか?
よく見ると、“MANAGER”のつづりが間違っていました。
000000 MOVE "MANAGER" TO JOB.111111 EXEC SQL UPDATE emp SET sal = sal * 1.2111111 WHERE job = :JOB END-EXEC.000000 DISPLAY SQLERRD(3).
これを実行すると処理件数が表示されました。めでたしめでたし!
このように、自分がイメージしている処理通り行われているかチェックすることができます。
000000 MOVE "MANEGER" TO JOB.111111 EXEC SQL UPDATE emp SET sal = sal * 1.2111111 WHERE job = :JOB END-EXEC.000000 IF SQLERRD(3) = 0 THEN000000 DISPLAY "処理対象がありませんでした。" JOB000000 END-IF.
上記のようなチェックをプログラムの中に記述しておくと、思いがけないバグを単体テストの段階で発見できます。
次に良く記述する例を挙げます。
== 例 ==
000000 MOVE 7789 TO ENO.111111 EXEC SQL UPDATE emp SET sal = sal * 1.2111111 WHERE empno = :ENO END-EXEC.000000 IF SQLERRD(3) NOT = 1 THEN000000 DISPLAY "処理対象が不当です。" ENO000000 END-IF.
上記のように、WHERE <主キー> = の場合、必ず処理件数は1件になります。
この例は、empno=7788を間違って7789と記述していることを発見できました。
このように、SQL-DML(INSERT/UPDATE/DELETE)命令のすぐ後ろに処理件数(SQLERRD(3))をチェックするIF文を追加しておくと、精度の高いシステムを構築することができます。