COBOLのSQLCODEを利用したエラーハンドリングとは?|応用ガイド | 応用ガイド

COBOL(コボル)言語のDB操作の結果を判断するSQLCODEとは?

応用-SQLCODE-イメージ

COBOL(コボル)言語のDB操作の結果を判断する「SQLCODE」とは?

一般的なDBはリレーショナル型データベース(RDB)を指します。RDBは、問い合わせ言語(SQL)を利用してデータにアクセスを行います。これらはDBアクセスを学ぶ上での共通事項です。

今回ご紹介するSQLCODEはこれらDBアクセスで利用されるSQLの処理結果を持つ変数で、処理が正常終了しているのか、異常終了しているのか、異常終了している場合はどのようなエラーが発生しているのかを値として持ちます。では、SQLCODEの値の意味とその書き方について見ていきましょう。

書き方:

SQLCODE = 0  ・・処理正常終了

SQLCODE = 100 ・・FETCH処理時、該当データなし

SQLCODE > 0  ・・警告

SQLCODE < 0  ・・処理異常終了

COBOL(コボル)言語のDBアクセスの処理構成と「SQLCODE」との関係

DBアクセスの基本的な処理構成とSQLCODEとの関係について見ていきましょう。

[基本的な処理構成]

1.ホスト変数の定義、2.共通領域の定義、3.データベース接続、4.データベースアクセス

各処理で実施する処理内容は以下の通りです。

1.ホスト変数の定義

COBOL、DB間のデータ連携用の変数を定義します。この変数を利用してDBから取得したデータをCOBOLで加工、編集する事ができるようになります。

2.共通領域の定義

SQL実行時に出るエラー、警告及びステータス情報を格納するための領域を定義します。ここに最新のSQLの実行結果が反映される事になります。今回ご紹介しているSQLCODEもこちらの定義に含まれています。

3.データベース接続

ユーザID、パスワードを指定し、DBと接続します。

4.データベースアクセス

DBの操作(検索、追加、更新、削除など)を行います。今回ご紹介するSQLCODEはこれらDB操作の後に記述し、処理の正常・異常を判断した後、異常終了時は適切なエラーハンドリング処理につなげていく事になります。

では基本的な処理構成について記述したサンプルプログラム(使用例1)を用意しましたので、その書き方について見ていきましょう。

使用例1:

※今回のDBMSは、オープンソースの「PostgreSQL」を使用しています。

※USERNAME、PASSWORDはご自身の環境に合わせて指定ください。

応用-SQLCODE-使用例1

応用-SQLCODE-使用例

使用例1は、DB(testdb)に、ユーザID、パスワードを指定して接続し、テーブル「test」の列名「tidが'0002'」のデータを検索するプログラムです。検索後にSQLCODEが0(正常終了)か、100(該当データなし)か、それ以外(異常終了)かを判断し、後続処理を実施している事がご確認いただけるかと思います。

テーブル(test):処理実行前

応用-SQLCODE-テーブル

実行結果:

応用-SQLCODE-実行結果

COBOL(コボル)言語の「SQLCODE」の応用的な使い方

DBアクセスとSQLCODEの基本的な処理構成と書き方について理解いただけたでしょうか。今度は、応用的な使い方について考えていきましょう。

先ほどご紹介したサンプルプログラムは、SQLCODE=0、100のケースを確認しましたが、今回はSQLCODE<0になるケースについて考えてみましょう。SQLCODE<0は処理が異常終了するケースですので、通常はエラーメッセージ等を出力し、処理を中断させるなどしますが、意図的に処理を進めるケースもあります。

応用編では、このケースとしてDBのレコード新設時にキー重複が発生した場合について考えてみましょう。具体的なサンプルプログラム(使用例2)を用意しましたので、しっかり内容を理解して実際のプログラム作成に活用いただければと思います。

使用例2:

  1. IDENTIFICATION DIVISION.
  2. PROGRAM-ID. db_sqlcode_sample02.
  3. ENVIRONMENT DIVISION.
  4. DATA DIVISION.
  5. WORKING-STORAGE SECTION.
  6. * 1.ホスト変数の定義
  7. EXEC SQL BEGIN DECLARE SECTION END-EXEC.
  8. 01 DBNAME PIC X(32) VALUE "testdb".
  9. 01 USERNAME PIC X(32) VALUE "********".
  10. 01 PASSWORD PIC X(32) VALUE "********".
  11. EXEC SQL END DECLARE SECTION END-EXEC.
  12.  
  13. * 2.共通領域の定義
  14. EXEC SQL INCLUDE SQLCA END-EXEC.
  15.  
  16. PROCEDURE DIVISION.
  17. * 3.データベース接続
  18. EXEC SQL
  19. CONNECT :USERNAME IDENTIFIED BY :PASSWORD
  20. USING :DBNAME
  21. END-EXEC.
  22.  
  23. * 4.データベースアクセス
  24. * 4-1.INSERT1 キー重複
  25. EXEC SQL
  26. INSERT INTO test
  27. (tid,tname)
  28. VALUES ('0002','grape')
  29. END-EXEC.
  30.  
  31. EVALUATE SQLCODE
  32. WHEN ZERO
  33. DISPLAY SQLCODE
  34. EXEC SQL
  35. COMMIT
  36. END-EXEC
  37. WHEN OTHER
  38. DISPLAY SQLCODE "," SQLSTATE
  39. DISPLAY "ERROR"
  40. EXEC SQL
  41. ROLLBACK
  42. END-EXEC
  43. END-EVALUATE.
  44.  
  45. * 4-1.INSERT2 正常
  46. EXEC SQL
  47. INSERT INTO test
  48. (tid,tname)
  49. VALUES ('0003','grape')
  50. END-EXEC.
  51.  
  52. EVALUATE SQLCODE
  53. WHEN ZERO
  54. DISPLAY SQLCODE
  55. EXEC SQL
  56. COMMIT
  57. END-EXEC
  58. WHEN OTHER
  59. DISPLAY SQLCODE "," SQLSTATE
  60. DISPLAY "ERROR"
  61. EXEC SQL
  62. ROLLBACK
  63. END-EXEC
  64. END-EVALUATE.
  65.  
  66. STOP RUN.
  67. END PROGRAM db_sqlcode_sample02.

使用例2は、テーブル「test」に2レコードデータを新設する処理になります(テーブル「test」の主キーは列名「tid」)。ただし「tid='0002'」の場合は既にデータが存在しているためレコードが新設できずSQLCODEも<0で返っています。一方「tid='0003'」の場合はデータが存在しないためレコードが新設でき、SQLCODEも0で正常終了している事がご確認いただけるかと思います。

テーブル(test):処理実行前

応用-SQLCODE-テーブル

実行結果:

応用-SQLCODE-実行結果

テーブル(test):処理実行後

応用-SQLCODE-テーブル

練習問題

最後に練習問題にチャレンジしてみましょう。

問)

使用例1では、FETCH処理後にSQLCODEの判断処理を入れましたが、その他にSQLCODEの判断処理を入れるべきところはないでしょうか?実際にプログラムも修正して確認してみましょう。

答え)

SQLの操作を行っている箇所全てにSQLCODEによる判断処理を入れるべき、となります。具体的にはカーソルのオープン、クローズ処理後になります。

ただし、実際にプログラムに組み込む際には同じような判断処理になる事が多いため、プログラムのコーディングやテスト、プログラムの品質や保守性を考えると、共通処理として定義しておく事が望ましいでしょう。

この記事を読んだ人は、こちらの記事も読んでいます

【未経験者歓迎】COBOLプログラマー・システムエンジニアの募集

株式会社COBOLの求人・転職・募集情報を見る

COBOL入門のカテゴリー

取引企業様 募集中
COBOL技術者 募集
COBOL魂
読者採用
COBOL入門