『やさしくわかるSQL』各書店にて好評発売中! オラクルが好き!
Oracle Pro*COBOL FAQ
Top やさしくわかるSQL RDBMS入門 チューニング SQL相談室 Pro*COBOL入門 COBOL相談室 サブルーチン

やさしくわかるPro*COBOL』を公開!
COBOL言語にて基幹システムを構築されているエンジニアは必見です。 

Oracle Pro*COBOL&MF−COBOL言語相談室
を開設しました!

Pro*COBOLは、Oracle Programmerという製品の中に入っています。Oracle Programmerには、Pro*C/C++、Pro*COBOL、Oracle ODBC Driver、Oracle Object for OLE(OO4O)などアプリケーションシステムを開発する為に必要な製品が1つのパッケージになっています。

(1998/05/03) なぜ、COBOL 言語に関する HP が無いのだろうか?よし!俺が作ろう!という事でこのページができました。COBOL だけでは面白くないので、これからの COBOL プログラマーの為に、RDB と関係する事を載せていきます。

このページは、パソコンのMicroFocus COBOL V3.1J〜と、Oracle Pro*COBOL V1.7〜について載せています。

初心者編
中級編
上級編
COBOL編


戻る



Pro*COBOLとは?
 プリコンパイラです。MicorFocus COBOL言語のコンパイラで解釈できないまたは無視する命令をソースに記述する場合プリコンパイラを使用してコンパイラが解釈できるソースを生成します。
 COBOL言語を使用してRDBをアクセスする場合、埋め込みSQLと言う命令(EXEC SQL ... END-EXEC.)を使用します。Pro*COBOLプリコンパイラは、そのCOBOLソースをCOBOLコンパイラが翻訳できるソースを生成してくれます。
 普通COBOLソースの拡張子は.CBLですが、埋め込みSQLを使用したCOBOLソースの拡張子は.PCOです。Pro*COBOLプリコンパイラが.CBLのソースを生成してくれます。
 このプリコンパイラを使用すると、容易にRDBから検索した結果をCOBOLの項目(変数)に読込むことができます。(RDBのデータ型とCOBOL言語のデータ型の型変換機能)


Pro*COBOLの実行方法は?
 PROCOB INAME={ソースファイル名[.PCO]} [Enter] です。
 実行できない場合は、PATH を確認してください。\orawin95\bin などが設定されていますか?また、そのディレクトリの中に PROCOB.EXE が登録されているか確認して下さい。
 PL/SQLブロックなどを記述している場合は、PROCOB INAME={ソースファイル名[.PCO]} SQLCHECK=SEMANTICS USERID={実行ユーザ名}/{パスワード}@{ホスト文字列} [Enter] です。プリコンパイル時にRDBサーバに接続して詳細チェックをかけてくれます。


PIC 9(05).の項目でエラーが出る?
 DATA DIVISION 内に、BEGIN DECLARE SECTION と END DECLARE SECTION の行で挟まれている項目の宣言がホスト変数(COBOL言語とSQL言語との受け渡しに使用される変数)として使用できるのですが、PIC 9(xx). と記述すると宣言の所でエラーが発生したり、PIC S9(xx). と記述すると SQL 文の所でエラーが発生します。
 Pro*COBOL で使用できる数字型項目は、COMP[-4] (バイナリ) と COMP-3 (パック) だけです。項目宣言のところを修正してください。
 COMP または COMP-3 を指定すると、バイト数が小さくなります。集団項目や部分指定を使用しているアプリケーションは注意しましょう。


データベースに接続できない?
 データベースに接続するコマンドは、EXEC SQL CONNECT {ユーザ名} IDENTIFIED BY {パスワード} END-EXEC. ですが、注意事項があります。
 1.リテラルは使用できません。必ず項目(変数)に代入して、その項目を CONNECT :{項目名} と使用します。

 2.クライアント/サーバ構成(サーバ上以外でも実行する可能性のあるプログラム)の場合、ユーザ名とパスワードを分けて記述できません。なぜならホスト文字列があるためです。下記の様に(000110行〜000130行)一度で指定します。

000010 WORKING-STORAGE SECTION.
000020*     |
000030   EXEC SQL BEGIN DECLARE SECTION END-EXEC.
000040 01 USERNAMES  PIC  X(32) VARYING.
000050   EXEC SQL END DECLARE SECTION END-EXEC.
000060   EXEC SQL INCLUDE SQLCA END-EXEC.
000070*
000080 PROCEDURE    DIVISION.
000090*     |
000100   EXEC SQL WHENEVER SQLERROR GOTO SQL-ERR END-EXEC.
000110   MOVE "SCOTT/TIGER@WGS_SRV_ORCL" TO USERNAMES-ARR.
000120   MOVE 24 TO USERNAMES-LEN.
000130   EXEC SQL CONNECT :USERNAMES END-EXEC.
000140*     |
000150   STOP    RUN.
000160*
000170 SQL-ERR.
000180*     |
000190   STOP    RUN.



データベースとの切断はしなくていいの?
 トランザクションの確定処理 COMMIT コマンドがきちんと入っている場合は、無くてもいいです。
 しかし、プログラマーならきちんと切断命令を記述しましょう!CLOSE 命令の無いプログラムみたいなものです。切断命令は、RDBサーバに対して、サーバプロセスを明示的に終了させ、サーバのメモリを開放できます。また SELECT コマンドなどの検索結果(実行集合といいます)を開放し、ロールバックセグメントの有効活用につながります。
 命令は、COMMIT [WORK] RELEASE です。

000080 PROCEDURE    DIVISION.
000090*     |
000130   EXEC SQL COMMIT WORK RELEASE END-EXEC.
000150   STOP    RUN.



エラー処理ルーチンを作りたい!
 下記の様に記述します。
 000070行以下の処理で、エラーが発生した場合は、段落 SQL-ERR に飛びます。
 000120行は、エラー処理ルーチンの宣言解除です。(絶対必要!000140行でエラーが発生したとき無限ループになる為)
 000130行は、エラーメッセージを表示します。(ORA-xxxっていうやつ) SQLERRMC は、000030行の SQLCA 内で宣言されています。
 000140行は、ROLLBACK 処理を行って、セッションを切断します。

000010 WORKING-STORAGE SECTION.
000020*     |
000030   EXEC SQL INCLUDE SQLCA END-EXEC.
000040*
000050 PROCEDURE    DIVISION.
000060   EXEC SQL WHENEVER SQLERROR GOTO SQL-ERR END-EXEC.
000070*     |
000080   EXEC SQL COMMIT WORK RELEASE END-EXEC.
000090   STOP    RUN.
000100*
000110 SQL-ERR.
000120   EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
000130   DISPLAY  SQLERRMC.
000140   EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
000150   STOP    RUN.



ストアド・プロシジャーをコールしたい!
 下記の様に、PL/SQLブロックを記述してコールします。

000010 PROCEDURE   DIVISION.
000020*     |
000030   EXEC SQL EXECUTE
000040        BEGIN
000050          my_proc( 1, 2, 3 );
000060        END; END-EXEC.
000070*     |



COBOL上で可変長文字はどうやって扱うの?
 宣言のし方は、下記の様(000040行)に記述します。

000010 WORKING-STORAGE SECTION.
000020*     |
000030   EXEC SQL BEGIN DECLARE SECTION END-EXEC.
000040 01 USERNAMES  PIC  X(32) VARYING.
000050   EXEC SQL END DECLARE SECTION END-EXEC.

 プリコンパイラを通すと、上記の宣言は、下記の様に変換されます。

000040*01 USERNAMES  PIC   X(32) VARYING.
000041 01 USERNAMES.
000042  02 USERNAMES-LEN     PIC S9(4) COMP-5.
000043  02 USERNAMES-ARR     PIC X(32).

 宣言した可変長文字項目の使い方は、下記の様に記述します。(COBOL言語上) ちょっとめんどくさい!(~_~;)

000110   MOVE "SCOTT/TIGER@WGS_SRV_ORCL" TO USERNAMES-ARR.
000120   MOVE 24             TO USERNAMES-LEN.
※注意:間違って、USERNAMES に代入すると、文字長領域に不当な値が入り、アプリケーションエラーになります。
 宣言した可変長文字項目の使い方は、下記の様に記述します。(埋め込みSQL言語上)

000130   EXEC SQL CONNECT :USERNAMES END-EXEC.
※注意:COBOL言語の項目(変数)を使用するときは、前にコロン(:)をつけます。



PL/SQLブロックを埋め込みたい!
 下記の様に、PL/SQLブロックを記述します。

000010 PROCEDURE   DIVISION.
000020*     |
000030   EXEC SQL EXECUTE
000040        DECLARE
000050*         | ・・・ 変数・カーソル宣言部
000060        BEGIN
000070*         | ・・・ 手続き部
000080        EXCEPTION
000090*         | ・・・ エラー処理部
000100        END; END-EXEC.
000110*     |



処理した行数が知りたい!
 SQL 言語の中でも、UPDATE コマンドと DELETE コマンドは WHERE 句を少々間違っていても、文法さえ合っていればエラーになりません。実行して後から WHERE 句が間違っていたことに気がついたことはありませんか?
 SQLERRD(3) という項目に、処理した行数が入りますので、自分のプログラムをチェックする命令(000110行〜000140行)を常に記述しておきましょう。

000010 PROCEDURE   DIVISION.
000020*     |
000030   EXEC SQL SELECT tokui_name
000040            INTO :TK-NAME
000050            FROM m_tokui
000060            WHERE tokui_code = :TK-CODE    END-EXEC.
000070*     |
000080   EXEC SQL UPDATE m_tokui
000090            SET tokui_name = :TK-NAME
000100            WHERE tokui_code = :TK-CODE    END-EXEC.
000110   IF SQLERRD(3) NOT = 1
000120      DISPLAY  "SYSTEM ERROR (UPDATE m_tokui)"
000130      STOP RUN
000140   END-IF.
000150   EXEC SQL COMMIT                   END-EXEC.
000160*     |



SQL-DDLを実行したい!
 プログラムの中から、DDL 文を発行したいことがあります。下記に方法(000050行)を載せます。

000010 PROCEDURE   DIVISION.
000020*     |
000030   MOVE "ANALYZE TABLE m_tokui COMPUTE STATISTICS" TO SQL-STAT-ARR.
000040   MOVE 40 TO SQL-STAT-LEN.
000050   EXEC SQL EXECUTE IMMEDIATE :SQL-STAT        END-EXEC.
000060*     |



定数を宣言したい!
 IF 文などで良く定数と比較することがあります。後で見ると0が何で1が何なのか解らなくなります。定数を宣言できれば同じゼロでもここではこの意味で使用しているということが解ります。COBOL では、DATA DIVISION で項目を宣言する時、78 レベルを使用します。

000010 PROCEDURE   DIVISION.
000020*     |
000030   IF FLG = 0
000040*     |
000050   END-IF.
000060*     |

       ↓

000010 DATA     DIVISION.
000020*     |
000030 78 NO-UPDATE VALUE 0.
000040*     |
000050 PROCEDURE   DIVISION.
000060*     |
000070   IF FLG = NO-UPDATE
000080*     |
000090   END-IF.
000100*     |



可変長文字を扱いたい!
 ヌル(X"00")で終わる可変長文字を扱いたいときがあります。下記のプログラムは同等な動作をします。(001090行で、リテラルにヌルをくっつけています。STRING 命令を使用しても同じです。)

000010 DATA     DIVISION.
000020 WORKING-STORAGE SECTION.
000030   EXEC SQL BEGIN DECLARE SECTION END-EXEC.
000040 01 USERNAMES1     PIC X(64) VARYING.
000050   EXEC SQL END  DECLARE SECTION END-EXEC.
000060*     |
000070 PROCEDURE   DIVISION.
000080*     |
000090   MOVE "SCOTT/TIGER@HOST" TO USERNAMES1-ARR.
000100   MOVE 16 TO USERNAMES1-LEN.
000110   EXEC SQL CONNECT :USERNAMES1 END-EXEC.

001010 DATA     DIVISION.
001020 WORKING-STORAGE SECTION.
001030   EXEC SQL BEGIN DECLARE SECTION END-EXEC.
001040 01 USERNAMES2     PIC X(64).
001050   EXEC SQL END  DECLARE SECTION END-EXEC.
001060*     |
001070 PROCEDURE   DIVISION.
001080*     |
001090   MOVE "SCOTT/TIGER@HOST" & X"00" TO USERNAMES2.
001100   EXEC SQL CONNECT :USERNAMES2 END-EXEC.



C言語のサブルーチンをコールしたい!
 COBOL のソースから、WinAPI などC言語のサブルーチンをコールしたいことがあります。
まず、IDENTIFICATION DIVISION で呼び出し規則名を宣言(000020〜000030行)します。
次に、DATA DIVISION で32ビットの整数は PIC S9(08) COMP-5. で宣言(000070行)します。
実行部は、CALL とサブルーチン名の間に呼び出し規則名を記述します。数値渡しは USING BY VALUE で、ポインタ渡しは USING BY REFERENCE で、戻り値は RETURNING で読込めます。

000010 IDENTIFICATION DIVISION.
000020 SPECIAL-NAMES.
000030  CALL-CONVENTION 74 IS winapi.
000040*     |
000050 DATA     DIVISION.
000060 WORKING-STORAGE SECTION.
000070 01 V-LONG-INT     PIC S9(08) COMP-5.
000080 01 V-STRING      PIC X(256).
000090 01 V-RET        PIC S9(08) COMP-5.
000100*     |
000110 PROCEDURE   DIVISION.
000120*     |
000130   CALL winapi "xxxxx" USING BY VALUE V-LONG-INT
000140                  BY REFERENCE V-STRING
000150                  RETURNING V-RET.
000160*     |



C言語のサブルーチンをコールするとリンクエラーが出る!
 COBOL コンパイラのデフォルトは、サブルーチンの大文字/小文字を区別しません。C言語などのサブルーチンをリンクする時は大文字/小文字の区別が必要です。
コンパイル時に、CASE オプションを指定してください。


気軽に質問して下さい。お問い合わせは、buchi@t3.rim.or.jpまでお願いします。


戻る

Last update (C) 2004 HiroLaboratory. All rights reserved.