2 プリコンパイラの概要
この章では埋込みSQLプログラムの動作を説明します。重要な用語の定義、基本概念の説明および主なルールを示します。
内容は次のとおりです。
2.1 埋込みSQLプログラミングの基本概念
2.1.1 埋込みSQLアプリケーションの開発ステップ
プリコンパイルを実行すると、通常どおりにコンパイルできるソース・ファイルが生成されます。プリコンパイルを行うと従来の開発過程より1ステップ処理が増えますが、これによって柔軟性に富んだアプリケーションを開発できるという大きな利点があります。
図2-1は、埋込みSQLアプリケーションの開発過程を示しています。
2.1.2 埋込みSQL文
埋込みSQLとは、アプリケーション・プログラムに記述されているSQL文のことです。SQL文を含むアプリケーション・プログラムはホスト・プログラムと呼ばれ、その記述言語はホスト言語と呼ばれます。たとえば、Pro*COBOLでは、SQL文をCOBOLホスト・プログラムに埋め込むことができます。
Oracleデータの操作および問合せには、INSERT文、UPDATE文、DELETE文およびSELECT文を使用します。INSERTはデータベース表へのデータ行の追加、UPDATEは行の変更、DELETEは不要な行の削除、SELECTは検索条件を満たす行の検索を行います。
アプリケーション・プログラムではSQL文のみ有効であり、SQL*Plus文は無効です。(SQL*Plusにはレポートの書式化、SQL文の編集、環境パラメータの設定のための文が追加されています。)
2.1.2.1 実行文および宣言部
埋込みSQL文には、すべての対話型SQL文に加えて、Oracleとホスト・プログラムの間でデータを転送できるその他の文があります。埋込みSQL文には、実行文およびディレクティブという2つのタイプがあります。
実行SQL文は、データベースのコールを生成します。実行SQL文には、ほとんどすべての問合せ、データ操作言語(DML)文、データ定義言語(DDL)文、データ制御言語(DCL)文が含まれます。
一方、ディレクティブではSQLLIBのコールは発生せず、Oracleデータの操作も行われません。
ディレクティブはOracleオブジェクト、コミュニケーション領域およびSQL変数を宣言するために使用します。ディレクティブは、COBOLの宣言を記述できる位置であればどこでも記述できます。
表2-1に、いくつかの埋込みSQL文の一例を分類して示します。
表2-1 埋込みSQL文 - ディレクティブ
STATEMENT | 用途 |
---|---|
ARRAYLEN* |
PL/SQLでのホスト表の使用 |
BEGIN DECLARE SECTION* END DECLARE SECTION* |
ホスト変数の宣言 |
DECLARE* |
Oracleオブジェクトの命名 |
INCLUDE* |
ファイルへのコピー |
VAR* |
変数の同値化 |
WHENEVER* |
ランタイム・エラーの処理 |
表2-2 埋込みSQL文 - 実行可能SQL
STATEMENT | 用途 |
---|---|
ALLOCATE* ALTER CONNECT* CREATE DROP GRANT NOAUDIT RENAME REVOKE TRUNCATE |
Oracleデータの定義および制御 |
CLOSE* DELETE EXPLAIN PLAN FETCH* INSERT LOCK TABLE OPEN* SELECT UPDATE |
Oracleデータの問合せおよび操作 |
COMMIT ROLLBACK SAVEPOINT SET TRANSACTION |
トランザクションの処理 |
DESCRIBE* EXECUTE* PREPARE* |
動的SQLの使用 |
ALTER SESSION SET ROLE |
セッションの制御 |
*対話形式なし
関連項目:
埋込みSQL文およびプリコンパイラ・ディレクティブは、重要な文およびディレクティブを説明しています。2.1.3 埋込みSQL文の構文
アプリケーション・プログラムでは、SQL文とホスト言語の文を自由に混在させることができ、SQL文でホスト言語の変数が使用できます。ホスト・プログラムにSQL文を記述するために特に必要なことは、SQL文をワードEXEC SQLで開始し、トークンEND-EXECで終了することのみです。Pro*COBOLが、実行EXEC SQL文をすべてランタイム・ライブラリSQLLIBのコールに変換します。
大部分の埋込みSQL文がそれに対応する対話型文と異なる点は、新しい句が追加されているか、プログラム変数が使用されていることのみです。次の対話型ROLLBACK文と埋込みROLLBACK文を比較してください。
ROLLBACK WORK; -- interactive * embedded EXEC SQL ROLLBACK WORK END-EXEC.
SQL文の後には、ピリオドやその他の終了記号を置くことができます。次は、どちらも正しいSQL文です。
EXEC SQL ... END-EXEC, EXEC SQL ... END-EXEC.
2.1.4 静的SQL文と動的SQL文
大部分のアプリケーション・プログラムは、静的SQL文および固定的なトランザクションを処理するように設計されています。この場合、処理を実行する前に各SQL文およびトランザクションの構成がわかります。つまり、発行されるSQLコマンド、変更されるデータベースの表、更新される列などが事前にわかります。
しかし、実行時に有効なSQL文を受け入れて処理する必要のあるアプリケーションもあります。この場合、関係するSQLコマンド、データベースの表および列は実行時までわからない場合もあります。
動的SQLは、プログラムの実行時にSQL文を受け取るかまたは作成し、データ型変換を明示的に管理する高度なプログラミング技術です。
2.1.5 埋込みPL/SQLブロック
Pro*COBOLはPL/SQLブロックを1つの埋込みSQL文のように扱うため、SQL文の埋込みが可能なアプリケーション・プログラム内の任意の場所にPL/SQLブロックを埋め込むことができます。PL/SQLをホスト・プログラム内に埋め込むには、PL/SQLと共有する変数を宣言し、キーワードEXEC SQL EXECUTEおよびEND-EXECを使用してPL/SQLブロックを囲みます。
PL/SQLはすべてのSQLデータ操作コマンドおよびトランザクション処理コマンドをサポートしているため、埋込みPL/SQLブロックからOracleデータを柔軟かつ安全に操作できます。
関連項目
2.1.6 ホスト変数および標識変数
ホスト変数とは、COBOL言語で宣言され、Oracleとの間で共有される(つまり、ユーザー・プログラムおよびOracleの両方がその値を参照できる)スカラー変数または表変数、あるいはグループ項目です。ホスト変数はOracleとプログラムの間の通信を仲介します。
データベースにデータを渡すには入力ホスト変数を使用します。データベースからプログラムにデータおよびステータス情報を渡すには、出力ホスト変数を使用します。
ホスト変数は、式を使用できる位置であればどこに使用してもかまいません。SQL文では、ホスト変数にコロン(:)の接頭辞を付けて、データベース・スキーマ名からホスト変数を切り分ける必要があります。
任意のホスト変数に任意指定の標識変数を関連付けることができます。標識変数とは、ホスト変数の値または条件を示す整変数です。NULLとは、値がないか、未知であるか、または適用不可能な値です。標識変数を使用すると、入力ホスト変数にNULLを割り当てたり、出力変数のNULLまたは出力文字ホスト変数の切り捨てられた値を検出できます。
ホスト変数についての禁止事項は次のとおりです。
-
COBOL文で先頭にコロンを付けること
-
ALTERやCREATEなどのデータ定義(DDL)文で使用すること
SQL文中に標識変数を記述する場合は、前にコロンを付けて、関連付けられたホスト変数の直後に記述してください(標識変数の前にオプションのキーワードINDICATORを付けることも可能です)。
SQL文で使用するプログラム変数はすべて、COBOL言語の規則に従って宣言する必要があります。この場合、通常のスコープ規則が適用されます。COBOLでは変数名の長さは任意ですが、Pro*COBOLでは最初の30文字のみが有効になります。数字で始まるものも含め、有効なCOBOL識別子であればどれでもホスト変数識別子として使用できます。
ホスト変数の外部データ型およびそのソース・データベースまたはターゲット・データベース列の内部データ型は、同じである必要はありませんが、互換性が必要です。
関連項目:
データ型変換では、必要に応じてOracleで自動的に変換される互換性のあるデータ型を示しています。2.1.7 Oracleのデータ型
一般的に、ホスト・プログラムはデータベースにデータを入力し、データベースはホスト・プログラムにデータを出力します。Oracleは、入力データをデータベースの表に挿入し、出力データを選択して プログラム・ホスト変数に格納します。データ項目を格納するために、Oracleではそのデータ型を認識する必要があり、データ型により値の記憶形式と有効範囲が指定されます。
Oracleでは、内部データ型と外部データ型という2種類のデータ型が認識されます。内部データ型は、Oracleでデータベース列にデータを格納する方法を指定します。また、Oracleでは、データベース疑似列を表す内部データ型も使用されます。データベース疑似列は特定のデータ項目を戻すものの、表には実際の列はありません。
外部データ型は、データがホスト変数にどのように格納されるかを指定します。ホスト・プログラムからOracleにデータが入力されると、Oracleは必要に応じて、入力ホスト変数の外部データ型とデータベース列の内部データ型の変換を行います。また、Oracleからホスト・プログラムにデータを出力するときも、Oracleは必要に応じて、データベース列の内部データ型と出力ホスト変数の外部データ型の変換を行います。
注意:
動的SQL方法4またはデータ型の同値化を使用すると、デフォルトのデータ型変換をオーバーライドできます。データ型の同値化の詳細は、「DATE文字列フォーマットの明示的な制御」を参照してください。
2.1.8 表
Pro*COBOLでは、表ホスト変数(ホスト表と呼ばれます)を定義して、それを単一のSQL文で操作できます。SELECT文、FETCH文、DELETE文、INSERT文およびUPDATE文を使用すると、大量のデータの問合せおよび操作を簡単に行えます。
関連項目:
ホスト表の詳細は、ホスト表を参照してください。2.1.9 エラーおよび警告
2.1.9.1 SQLCODE/SQLSTATE状態変数
SQL文の実行後、OracleサーバーはSQLCODEまたはSQLSTATEという変数にステータス・コードを戻します。ステータス・コードは、そのSQL文の実行に成功したか、エラーまたは警告状態が発生したかを示します。
2.1.9.2 SQLCA状態変数
SQLCAは、Oracleでプログラムにランタイム・ステータス情報を渡すために使用されるプログラム変数を定義するデータ構造体です。SQLCAを使用すると、直前に試みた処理に関するOracleからのフィードバックに基づいて、異なる処理を実行できます。たとえば、DELETE文が成功したかチェックし、成功した場合は削除された行数をチェックできます。
SQLCAによって、診断チェックおよびイベント処理ができます。実行時には、Oracleからプログラムに渡されるステータス情報をSQLCAで保持します。SQL文の実行後、Oracleにより図2-2に示すようにSQLCA変数が設定されて、結果が示されます。
INSERT文、UPDATE文またはDELETE文の実行の成否を確認でき、成功した場合には、何行処理されたかを確認できます。文の実行に失敗した場合は、原因の詳細な情報が得られます。
MODE={ANSI13 | ORACLE}のとき、SQLCAを宣言するには、SQLCAをハードコーディングするか、INCLUDE文を使用してプログラムにコピーする必要があります。
関連項目:
SQLCAの宣言方法および使用方法は、SQLコミュニケーション領域の使用を参照してください。2.1.9.4 ORACA
ランタイム・エラーについて、SQLCAに格納されている情報よりも詳細な情報が必要なときにORACAを使用します。ORACAは、Oracleの通信を扱うデータ構造です。この中にはカーソル統計情報、現行のSQL文に関する情報、オプションの設定、およびシステムの統計情報が含まれます。
2.2 プログラミング・ガイドライン
2.2.4 コーディング領域
プリコンパイラ・オプションFORMATは、ソース・コードの書式を指定します。FORMAT=ANSI (デフォルト)と指定すると、ANSI規格にできるかぎり準拠したコードを作成できます。ANSI規格では、1から6桁目にオプションの順序番号を、7桁目(インジケータ領域)にはコメント行または継続行を記述できます。
分割ヘッダー、セクション・ヘッダー、段落の名前、FDおよび01文は、8から11桁目(A領域)から始まります。EXEC SQL文、EXEC ORACLE文など、その他の文は、領域B (12から72桁)に記述する必要があります。ソース・コード書式のガイドラインは、コンパイラの規則によって変更できます。
FORMAT=TERMINALを指定すると、COBOL文を1桁目(一番左の桁)から始めるか、または1桁目をインジケータ領域にできます。この書式も、コンパイラの規則によって変更されます。
FORMAT=VARIABLEを指定すると、B領域の長さの柔軟性が許可されます。
COBOL文の書式が実際に受け付けられるかどうかを判断するには、使用しているプラットフォーム用のCOBOLコンパイラのマニュアルを参照してください。
2.2.5 カンマ
SQLでは、次の例に示すように、カンマを使用してリスト項目を区切る必要があります。
EXEC SQL SELECT ENAME, JOB, SAL INTO :EMP-NAME, :JOB-TITLE, :SALARY FROM EMP WHERE EMPNO = :EMP-NUMBER END-EXEC.
COBOLでは、カンマまたは空白を使用してリスト項目を区切ることができます。たとえば、次の2つの文は等価です。
ADD AMT1, AMT2, AMT3 TO TOTAL-AMT. ADD AMT1 AMT2 AMT3 TO TOTAL-AMT.
2.2.6 コメント
SQL文の中にCOBOLのコメント行を入れることができます。COBOLのコメント行は、インジケータ領域内で先頭にアスタリスク(*)を付けて始めます。
SQL文の中には、「- -」で始まるANSI SQLスタイルのコメントを行の最後に記述できます(ただし、SQL文の最終行の後には記述できません)。
行の残りの部分には、「*>」の2文字で始まるCOBOLコメントを記述できます。
SQL文には、C言語スタイル(/* ... */)のコメント文が記述できます。
次の例には、前述の4つのスタイルのコメントがすべて含まれています。
MOVE 12 TO DEPT-NUMBER. *> This is the software development group. EXEC SQL SELECT ENAME, SAL * assign column values to output host variables INTO :EMP-NAME, :SALARY -- output host variables /* column values assigned to output host variables */ FROM EMP WHERE DEPTNO = :DEPT-NUMBER END-EXEC. -- illegal Comment
コメントをネストしたり、SQL文の最終行の終了記号END-EXECの後にコメントを入れることはできません。
2.2.7 行の継続
次の例に示すように、COBOLの規則に従ってSQL文を次の行へ続けることができます。
EXEC SQL SELECT ENAME, SAL INTO :EMP-NAME, :SALARY FROM EMP WHERE DEPTNO = :DEPT-NUMBER END-EXEC.
継続インジケータは必要ありません。
ある行から次の行に文字列リテラルを継続するには、72桁までリテラルを記述します。次の行の7桁目にハイフン(-)、12桁以降に二重引用符を記述して、残りのリテラルを記述します。次に例を示します。
WORKING STORAGE SECTION. ... EXEC SQL BEGIN DECLARE SECTION END-EXEC. ... 01 UPDATE-STATEMENT PIC X(80) VALUE "UPDATE EMP SET BON - "US = 500 WHERE DEPTNO = 20". EXEC SQL END DECLARE SECTION END-EXEC.
2.2.8 Copy文
Copy文はPro*COBOLでは解析されません。そのため、COPY命令に含まれるファイルには、ホスト変数の定義を含めることも、埋込みSQL文を含めることもできません。かわりに、「INCLUDE文の使用」で説明しているINCLUDEプリコンパイラ文を使用します。INCLUDEを使用し、さらにDECLARE_SECTION=YESも使用する際には注意してください。グループ項目は、すべて宣言部の内部に配置するか、あるいはすべて外部に配置する必要があります。
2.2.9 DECIMAL-POINT IS COMMA句
Pro*COBOLでは、ENVIRONMENT DIVISIONでのDECIMAL-POINT IS COMMA句がサポートされます。ソース・ファイルにDECIMAL-POINT IS COMMA句が指定されていると、VALUE句内で数値リテラルの小数部分の開始記号としてカンマを使用できます。
たとえば、次の句は有効です。
IDENTIFICATION DIVISION. PROGRAM-ID. FOO ENVIRONMENT DIVISION. CONFIGURATION SECTION. SPECIAL-NAMES. DECIMAL-POINT IS COMMA. *> <-- ** DATA DIVISION. WORKING-STORAGE SECTION. ... 01 WDATA1 PIC S9V999 VALUE +,567. *> <--- ** 01 WDATA2 PIC S9V999 VALUE -,234. *> <--- ** ...
2.2.10 デリミタ
COBOLの文字列定数およびリテラルのデリミタの指定には、LITDELIMオプションを使用します。LITDELIM=APOSTと指定すると、Pro*COBOLではCOBOLコードを生成する際に引用符を使用します。LITDELIM=QUOTE (デフォルト)と指定すると、次に示すように二重引用符を使用します。
CALL "SQLROL" USING SQL-TMP0.
SQL文では、次の例に示すように、特殊文字または小文字を含む識別子は二重引用符で区切る必要があります。
EXEC SQL CREATE TABLE "Emp2" END-EXEC.
また、文字列定数を区切る場合は、次の例のように引用符を使用します。
EXEC SQL SELECT ENAME FROM EMP WHERE JOB = 'CLERK' END-EXEC.
Pro*COBOLは、Pro*COBOLソース・ファイルで使用されているデリミタに関係なく、LITDELIMの値で指定されたデリミタを生成します。
2.2.11 オプションの分割ヘッダー
次の分割ヘッダーはオプションです。
-
IDENTIFICATION DIVISION
-
ENVIRONMENT DIVISION
-
DATA DIVISION
PROCEDURE DIVISIONヘッダーはオプションではありません。プリコンパイルできるソースは次のとおりです。
*IDENTIFICATION DIVISION header is optional PROGRAM-ID. HELLO. *ENVIRONMENT DIVISION header is optional CONFIGURATION SECTION. *DATA DIVISION header is optional WORKING-STORAGE SECTION. PROCEDURE DIVISION. DISPLAY "Hello World!". STOP RUN.
2.2.12 埋込みSQLの構文
Pro*COBOLプログラムでSQL文を使用する場合は、SQL文の前にEXEC SQLを指定し、SQL文の最後にEND-EXECキーワードを指定します。
関連項目:
Oracle Database SQL言語リファレンス(埋込みSQL構文の詳細)2.2.14 ファイルの長さ
Pro*COBOLが処理できるソース・ファイルの長さには制限があります。内部で使用する変数によって、生成されるファイルのサイズが制限される場合があります。許容される行数の絶対的な制限はありませんが、次に示すようなソース・ファイルの状態によって、ファイル・サイズに制約が生じます。
-
埋込みSQL文の複雑さ(たとえば、バインド変数および定義変数の数)
-
データベース名の使用の有無(たとえば、AT句を使用してデータベース名に接続する場合)
-
埋込みSQL文の数
この制限に関連した問題を防ぐには、複数のプログラム単位を使用してソース・ファイルのサイズを小さくします。
2.2.15 FILLERの使用
ホスト変数の宣言でワードFILLERを使用できます。ワードFILLERは、明示的に参照できないグループの基本項目を指定するときに使用します。次の宣言は有効です。
01 STOCK. 05 DIVIDEND PIC X(5). 05 FILLER PIC X. 05 PRICE PIC X(6).
2.2.16 ホスト変数名
ホスト変数には、有効な標準COBOL識別子であればどれでも使用できます。変数名の長さに制限はありませんが、最初の30文字のみ有効になります。COBOLコンパイラが認識する有効文字の最大数は30です。
移植性を考慮する場合は、ホスト変数名を18文字以下(SQL標準での長さの要件)に制限することもできます。
関連項目:
アプリケーションでの使用に制限のある語のリストは、予約語、キーワードおよびネームスペースを参照してください。2.2.18 レベル番号
ホスト変数を宣言する際、レベル番号01から49および77を使用できます。Pro*COBOLでは、VARYING句を含む変数またはレベル49または77として宣言する擬似型の変数(先頭に「SQL-」が付くデータ型の変数)は使用できません。
2.2.19 MAXLITERALのデフォルト
MAXLITERALオプションを使用して、Pro*COBOLで生成される文字列リテラルの最大長を指定して、コンパイラ制限を超えないようにします。Pro*COBOLの場合はデフォルト値は256ですが、これより小さい値の指定が必要な場合もあります。IBM独自のS370オペレーティング・システムでは120です。
2.2.22 段落およびセクションの名前
次の例に示すように、COBOLの標準的な段落の名前およびセクションの名前をSQL文と関連付けできます。
LOAD-DATA. EXEC SQL INSERT INTO EMP (EMPNO, ENAME, DEPTNO) VALUES (:EMP-NUMBER, :EMP-NAME, :DEPT-NUMBER) END-EXEC.
また、次の例のようにWHENEVER ... DOまたはWHENEVER ... GOTOで段落の名前を参照することもできます。
PROCEDURE DIVISION. MAIN. EXEC SQL WHENEVER SQLERROR DO PERFORM SQL-ERROR END-EXEC. ... SQL-ERROR SECTION. ...
2.2.23 REDEFINES句
COBOLのREDEFINES句を使用して、グループ項目または基本項目を再定義できます。たとえば、次の宣言は有効です。
EXEC SQL BEGIN DECLARE SECTION END-EXEC. 01 REC-ID PIC X(4). 01 REC-NUM REDEFINES REC-ID PIC S9(4) COMP. EXEC SQL END DECLARE SECTION END-EXEC.
EXEC SQL BEGIN DECLARE SECTION END-EXEC. 01 STOCK. 05 DIVIDEND PIC X(5). 05 PRICE PIC X(6). 01 BOND REDEFINES STOCK. 05 COUPON-RATE PIC X(4). 05 PRICE PIC X(7). EXEC SQL END DECLARE SECTION END-EXEC.
1つのINTO句で、グループ項目ホスト変数およびその再定義の両方の項目が使用されていても、Pro*COBOLは警告もエラーも発行しません。
2.2.24 関係演算子
「関係演算子」のように、COBOLの関係演算子はそれに対応するSQLの関係演算子と異なります。また、COBOLでは記号のかわりにワードを使用できますが、SQLでは使用できません。
表2-3 関係演算子
SQL演算子 | COBOL演算子 |
---|---|
= |
=、EQUAL TO |
< >、!=、^= |
NOT=、NOT EQUAL TO |
> |
>、GREATER THAN |
< |
<、LESS THAN |
>= |
>=、GREATER THAN OR EQUAL TO |
<= |
<=、LESS THAN OR EQUAL TO |
2.2.25 文の終了記号
COBOLの文はCOBOL文またはSQL文、あるいはその両方を1つ以上含み、ピリオドで終わります。次の例に示すように、条件文では最後の文のみピリオドで終わる必要があります。
IF EMP-NUMBER = ZERO MOVE FALSE TO VALID-DATA PERFORM GET-EMP-NUM UNTIL VALID-DATA = TRUE ELSE EXEC SQL DELETE FROM EMP WHERE EMPNO = :EMP-NUMBER END-EXEC ADD 1 TO DELETE-TOTAL. END-IF.
SQL文は、カンマ、ピリオドまたはその他のCOBOL文で終了できます。
2.3 宣言部
データベース・サーバーとアプリケーション・プログラムの間のデータの受渡しには、ホスト変数とエラー処理が必要です。この項では、これらの必要条件を満たす方法を説明します。
2.3.1 宣言部の内容
2.3.1.1 例
プログラムで使用する4つのホスト変数を宣言した例を次に示します。
WORKING-STORAGE SECTION. ... EXEC SQL BEGIN DECLARE SECTION END-EXEC. ... 01 EMP-NUMBER PIC 9(4) COMP VALUE ZERO. 01 EMP-NAME PIC X(10) VARYING. 01 SALARY PIC S9(5)V99 COMP-3 VALUE ZERO. 01 COMMISSION PIC S9(5)V99 COMP-3 VALUE ZERO. EXEC SQL END DECLARE SECTION END-EXEC.
2.3.2 プリコンパイラ・オプションDECLARE_SECTION
宣言部はオプションです。Pro*COBOLには、リリース8.0以前のリリースとの下位互換性を保つために、宣言部内の宣言のみホスト変数として使用するかどうかを明示的に制御できるコマンドライン・プリコンパイラ・オプションが用意されています。このオプションは次のとおりです。
DECLARE_SECTION={YES | NO}(デフォルトはNO)
DECLARE_SECTIONオプションは、コマンドラインまたは構成ファイル内で指定する必要があります。
MODE=ORACLEおよびDECLARE_SECTION=YESと設定した場合は、宣言部の中で宣言した変数のみホスト変数として使用できます。MODE=ANSIと設定すると、DECLARE_SECTIONは暗黙的にYESに設定されます。
DECLARE_SECTIONをYESに設定した場合は、SQL文中で使用するすべてのプログラム変数を宣言部内で宣言する必要があります。DECLARE_SECTIONをNOに設定した場合は、宣言部を使用するかどうかを選択できます。この場合、ホスト変数および標識変数は宣言部の中でも宣言部の外でも宣言できます。このようなオプションとしての使用は、リリース8.0以下のリリースと異なる点です。
1つのプリコンパイル・ユニットで複数の宣言部を使用できます。さらに、複数の独立したプリコンパイル・ユニットを1つのホスト・プログラムに含めることもできます。
関連項目:
-
マクロ・オプションおよびマイクロ・オプションの詳細は、マクロ・オプションおよびマイクロ・オプションを参照してください。
-
オプションの詳細は、DECLARE_SECTIONを参照してください。
2.3.3 INCLUDE文の使用
INCLUDE文を使用して、ホスト・プログラムにファイルをコピーできます。次に例を示します。
* Copy in the SQL Communications Area (SQLCA) EXEC SQL INCLUDE SQLCA END-EXEC. * Copy in the Oracle Communications Area (ORACA) EXEC SQL INCLUDE ORACA END-EXEC.
INCLUDEは、どのファイルに対しても実行できます。Pro*COBOLプログラムをプリコンパイルすると、EXEC SQL INCLUDE文はそれぞれ、その文で指定されたファイルのコピーに置き換えられます。
2.3.3.2 検索パス
システムでディレクトリが使用される場合は、次のようにINCLUDEオプションを使用して、INCLUDEするファイルの検索パスを設定できます。
INCLUDE=path
このとき、pathのデフォルト値はカレント・ディレクトリです。
Pro*COBOLは、最初にカレント・ディレクトリを検索し、次にINCLUDEオプションで指定されたディレクトリを検索して、最後に標準INCLUDEファイル用のディレクトリを検索します。このため、SQLCAやORACAなどの標準ファイルのパスを指定する必要はありません。標準以外のファイルについては、カレント・ディレクトリに格納されている場合を除いてパスが必要です。
また次のように、コマンドラインで複数のパスを指定することもできます。
... INCLUDE=<path1> INCLUDE=<path2> ...
複数のパスを指定すると、Pro*COBOLにより、カレント・ディレクトリ、path1ディレクトリ、path2ディレクトリの順に検索されます。標準INCLUDEファイルを含むディレクトリは最後に検索されます。パスの構文はシステムによって異なります。詳細は、使用しているシステム固有のOracleマニュアルを参照してください。
検索パスを指定しても、Pro*COBOLでは最初に現在のディレクトリでファイルを検索します。INCLUDEするファイルが別のディレクトリにある場合、現在のディレクトリ、または検索パス上の先行する他のディレクトリに、同じ名前のファイルがないことを確認してください。大文字と小文字が区別されるオペレーティング・システムを使用している場合は、ファイルを格納したときと同じファイル名を大文字と小文字を区別して指定してください。.
2.4 ネストされたプログラム
COBOLにおけるプログラムのネストは、あるプログラムを別のプログラムの内側に配置することを意味します。包含されたプログラムは、自身を包含しているプログラムのリソースの一部を参照できます。名前はプログラム内でのみ認識されるため、上位プログラムとネストされたプログラムの内部で使用されている名前が同一であり、かつ競合せずに異なるデータ項目を表す場合もあります。ただし、上位プログラムの構成セクションに記述された名前は、ネストされたプログラムで参照されることがあります。
GLOBAL句をサポートしないコンパイラもあります。Pro*COBOLはGLOBAL句を含むコードを生成することにより、ネストされたプログラムをサポートします。GLOBAL句が無条件に生成されるのを防ぐには、プリコンパイラ・オプションでNESTED=NOと指定します。NESTED(=YESまたはNO)のデフォルトはYESで、構成ファイルまたはコマンドラインで指定できますが、インラインで(EXEC ORACLE文)指定することはできません。
プログラムでは、ネストされたプログラムを複数記述できます。同様に、ネストされたプログラムについても、その中にさらにネストされたプログラムを記述できます。ネストされたプログラムは、それを含むプログラムのEND PROGRAMヘッダーの直前に記述する必要があります。
ネストされたプログラムをコールできるのは、そのプログラムを直接的または間接的に含むプログラムのみです。ネストされたプログラムを別のプログラム(ネストのツリー構造の別の分岐にあるプログラムも含む)からコールする場合は、ネストされたプログラムのPROGRAM-ID段落にCOMMON句を記述します。COMMONは、ネストされたプログラムでのみ使用できます。
PROGRAM-ID. <nested-program-name> COMMON.
ファイル定義にGLOBAL句を使用して、レベル01のデータ項目(自動的にグローバルになる従属項目)を記述できます。このように記述したデータ項目は、それらのデータ項目に直接的または間接的に含まれるすべてのサブプログラムで参照できます。上位プログラムにはGLOBALを使用します。上位プログラムでGLOBALと宣言された名前と同じ名前がネストされたプログラムで定義されていると、COBOLではネストされたプログラムの中の宣言が使用されます。データ項目にREDEFINES句が使用されているときは、GLOBALはREDEFINESの後に記述する必要があります。
FD file-name GLOBAL ... 01 data-name1 GLOBAL ... 01 data-name2 REDEFINES data-name3 GLOBAL ...
関連項目
2.4.1 ネストされたプログラムのサポート
Pro*COBOLでは、1つのソース・ファイル内に埋込みSQLを持つ複数のネストされたプログラムを格納できます。上位プログラムでグローバルとしてマークされた、上位プログラム・レベルで有効なホスト変数である01レベルの項目はすべて、上位プログラムが直接的または間接的に含むすべてのプログラムで、有効なホスト変数として使用できます。次に例を示します。
IDENTIFICATION DIVISION. PROGRAM-ID. MAINPROG. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. EXEC SQL BEGIN DECLARE SECTION END-EXEC. 01 REC1 GLOBAL. 05 VAR1 PIC X(10). 05 VAR2 PIC X(10). 01 VAR1 PIC X(10) GLOBAL. EXEC SQL END DECLARE SECTION END-EXEC. PROCEDURE DIVISION. ... <main program statements> ... IDENTIFICATION DIVISION. PROGRAM-ID. NESTEDPROG. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 01 VAR1 PIC S9(4). PROCEDURE DIVISION. ... EXEC SQL SELECT X, Y INTO :REC1 FROM ... END-EXEC. EXEC SQL SELECT X INTO :VAR1 FROM ... END-EXEC. EXEC SQL SELECT X INTO :REC1.VAR1 FROM ... END-EXEC. ... END PROGRAM NESTEDPROG. END PROGRAM MAINPROG.
メイン・プログラムはホスト変数REC1をグローバル変数として宣言しているため、ネストされたプログラムは最初のSELECT文で宣言なしでREC1を使用することができます。VAR1はグローバル変数としても、ネストされたプログラムのローカル変数としても宣言されています。そのため、2番目のSELECT文はS9(4)として宣言されたVAR1を使用し、グローバル宣言をオーバーライドします。3番目のSELECT文では、PIC X(10)として宣言されたREC1のグローバル変数VAR1が使用されています。
前述の例は、DECLARE_SECTION=NOが使用されている場合の結果を説明しています。DECLARE_SECTION=YESの場合、ホスト変数が宣言部で宣言されていない場合、Pro*COBOLはホスト変数を認識しません。DECLARE_SECTION=YESと指定して前述のプログラムをプリコンパイルすると、2番目のSELECT文の結果、あいまいなホスト変数エラーが発生します。最初のSELECT文および3番目のSELECT文は同様に動作します。
注意: 再帰的なネストされたプログラムは、サポートされていません。
2.4.1.1 SQLCAの宣言
ネストされたプログラムでは、提供される組込みSQLCAの定義はグローバルとして宣言されるため、SQLCAの宣言は上位プログラム内でのみ必要になります。SQLCAは、新しいSQL文が実行されるたびに変更できます。提供されるSQLCAはいつでも変更できるため、ネストされたプログラムで追加のSQLCA領域を宣言する場合にはグローバル指定を削除できます。これはSQLDAおよびORACAにも適用されます。
関連項目
2.5 条件付きプリコンパイル
条件付きプリコンパイルとは、特定の条件に基づいてコード・セクションをホスト・プログラムに組み込む(または除外する)プリコンパイルの方法です。たとえば、UNIXでプリコンパイルするときにはあるコード・セクションを組み込み、VMSでプリコンパイルするときには別のコード・セクションを組み込むことができます。条件付きプリコンパイルの使用により、様々な環境で実行できるプログラムを作成できます。
環境および処理を定義する文によってコードの条件文が区切られます。コード・セクションには、ホスト言語の文を記述することも、EXEC SQL文を記述することもできます。次の文でプリコンパイルの条件を制御します。
* -- define a symbol EXEC ORACLE DEFINE symbol END-EXEC. * -- if symbol is defined EXEC ORACLE IFDEF symbol END-EXEC. * -- if symbol is not defined EXEC ORACLE IFNDEF symbol END-EXEC. * -- otherwise EXEC ORACLE ELSE END-EXEC. * -- end this control block EXEC ORACLE ENDIF END-EXEC.
条件文はEND-EXEC
で終了する必要があります。
注意:
使用しているコンパイラの条件付きコンパイル機能が、Pro*COBOLでサポートされない場合があります。
2.5.1 例
次の例では、シンボルSITE2が定義されているときのみSELECT文がプリコンパイルされます。
EXEC ORACLE IFDEF SITE2 END-EXEC. EXEC SQL SELECT DNAME INTO :DEPT-NAME FROM DEPT WHERE DEPTNO = :DEPT-NUMBER EXEC ORACLE ENDIF END-EXEC.
次の例に示すように条件ブロックはネストできます。
EXEC ORACLE IFDEF OUTER END-EXEC. EXEC ORACLE IFDEF INNER END-EXEC. ... EXEC ORACLE ENDIF END-EXEC. EXEC ORACLE ENDIF END-EXEC.
ホスト言語または埋込みSQLのコードをIFDEFとENDIFの間に記述し、シンボルを定義しないことによって、そのコードをコメントとして扱えます。
2.5.2 シンボルの定義
シンボルを定義するには2通りの方法があります。1つは、次の文をホスト・プログラムに組み込む方法です。
EXEC ORACLE DEFINE symbol END-EXEC.
もう1つは、次の構文を使用してコマンドラインでシンボルを定義する方法です。
... INAME=filename ... DEFINE=symbol
symbolの部分は大/小文字区別がありません。
Pro*COBOLをシステムにインストールした時点で、ポート固有のいくつかのシンボルが事前定義されています。たとえば、オペレーティング・システムの事前定義済シンボルには、CMS、MVS、UNIXおよびVMSがあります。
注意:
DEFINE SYMBOL名で、先頭に数字を使用した場合、またはダッシュを含めた場合、プリコンパイル時にリカバリ不可能なエラーが発生します。DEFINE SYMBOL名では、アンダースコアを使用すること、および先頭以外で数字を使用することはできます。
2.6 分割プリコンパイル
複数のCOBOLプログラム・モジュールを別々にプリコンパイルし、後でリンクして1つの実行可能プログラムを作成できます。これにより、プログラムの機能コンポーネントの作成とデバッグを複数のプログラマが分担して行う場合に必要とされる、モジュラー・プログラミングが可能になります。個々のプログラム・モジュールを同じ言語で作成する必要はありません。
2.6.1 ガイドライン
2.6.1.3 単一のSQLCAの使用
2.6.1.3.1 バージョン1.8以下
SQLCAをグローバルに宣言する必要があります。そのためには、次の行を変更してSQLCA.COBファイルを修正します。
01 SQLCA.
これを次のように変更します。
01 SQLCA EXTERNAL.
SQLCA.cobからコピーしたSQLCAのハードコード定義を組み込み、前述の変更を行う方法もあります。その場合も、SQLCAの定義をすべてのプリコンパイル・ユニットに組み込む必要があります。
2.7 コンパイルおよびリンク
実行可能プログラムを作成するには、Pro*COBOLによって生成されたソース・ファイルをコンパイルし、その結果得られたオブジェクト・モジュールを、SQLLIBおよびシステム固有のOracleライブラリ内の必要なモジュールとリンクさせる必要があります。
リンカーはオブジェクト・モジュール内のシンボリック参照を解決します。これらの参照で競合が発生すると、リンクは失敗します。プリコンパイル済のプログラムにサード・パーティのソフトウェアをリンクするときに、このような競合が起こる可能性があります。こうした問題が生じるのは、サード・パーティのソフトウェアの中にはOracleと互換性のないものがあるためです。Oracleサポート・サービスに問い合せて、使用するソフトウェアがサポートされているかどうかを確認してください。
コンパイルおよびリンクの方法はシステムによって異なります。たとえば、システムによっては、ホスト言語プログラムをコンパイルするときにコンパイラの最適化をオフにする必要があります。手順は、使用しているシステム固有のOracleマニュアルを参照してください。
2.8 DEPT表およびEMP表のサンプル
このマニュアルで紹介するほとんどのプログラム例では、DEPTおよびEMPという2つのサンプル・データベース表が使用されています。デモ・ディレクトリにこの2つの表が含まれていない場合は、サンプル・プログラムを実行する前に表を作成してください。次に示すのはそれぞれの表の定義です。
CREATE TABLE DEPT (DEPTNO NUMBER(2), DNAME VARCHAR2(14), LOC VARCHAR2(13)); CREATE TABLE EMP (EMPNO NUMBER(4) primary key, ENAME VARCHAR2(10), JOB VARCHAR2(9), MGR NUMBER(4), HIREDATE DATE, SAL NUMBER(7,2), COMM NUMBER(7,2), DEPTNO NUMBER(2));
2.8.1 DEPTデータおよびEMPデータのサンプル
DEPT表およびEMP表には、それぞれ次のデータ行が設定されています。
DEPTNO DNAME LOC ------- ---------- --------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ------- --------- ------ --------- ------ ------ ------- 7369 SMITH CLERK 7902 17-DEC-80 800 20 7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30 7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30 7566 JONES MANAGER 7839 02-APR-81 2975 20 7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30 7698 BLAKE MANAGER 7839 01-MAY-81 2850 30 7782 CLARK MANAGER 7839 09-JUN-81 2450 10 7788 SCOTT ANALYST 7566 19-APR-87 3000 20 7839 KING PRESIDENT 17-NOV-81 5000 10 7844 TURNER SALESMAN 7698 08-SEP-81 1500 30 7876 ADAMS CLERK 7788 23-MAY-87 1100 20 7900 JAMES CLERK 7698 03-DEC-81 950 30 7902 FORD ANALYST 7566 03-DEC-81 3000 20 7934 MILLER CLERK 7782 23-JAN-82 1300 10
2.9 サンプルEMPプログラム: SAMPLE1.PCO
埋込みSQLについては、プログラム例を見るとよくわかります。次のプログラムは、demo
ディレクトリのSAMPLE1.PCOです。
プログラムでデータベースにログインし、従業員番号を入力すると、従業員名、給与およびコミッションをEMP表に問い合せます。選択の結果はホスト変数EMP-NAME、SALARYおよびCOMMISSIONに格納されます。また、ホスト標識変数COMM-INDを使用して列COMMISSION内のNULL値を検出します。
次に、段落DISPLAY-INFOによって結果が表示されます。
バグ7225844 - パラメータEMP-NAMEにEMP-NUMBERから置き換えられました
COBOL変数USERNAME、PASSWDおよびEMP-NAMEは、VARYING句によって宣言されます。VARYING句により、VARCHARという可変長文字列のOracle外部データ型を使用できます。
エラー処理のためにSQLCAコミュニケーション領域が組み込まれています。エラーが発生すると、段落SQL-ERRORが実行されます。
ここで使用されているBEGIN DECLARE SECTION文およびEND DECLARE SECTION文は、プリコンパイラ・オプションDECLARE_SECTIONがYES、またはオプションMODEがANSIに設定されていない場合、省略できます。
エラー処理のためにWHENEVER文を使用しています。
このプログラムは、従業員番号として0 (ゼロ)を入力すると終了します。
注意:
この機能を簡単に説明するために、この例では、デプロイされたシステムで通常使用されるパスワード管理手法を実行していません。本番環境では、Oracle Databaseのパスワード管理ガイドラインに従い、サンプル・アカウントを無効にしてください。パスワード管理ガイドラインおよびその他のセキュリティ上の推奨事項については、『Oracle Databaseセキュリティ・ガイド』を参照してください。
* This program logs on to ORACLE, prompts the user for an employee number, * queries the database for the employee's name, salary, and commission, then * displays the result. The program terminates when the user enters a 0. * ID DIVISION. PROGRAM-ID. QUERY. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. EXEC SQL BEGIN DECLARE SECTION END-EXEC. 01 USERNAME PIC X(10) VARYING. 01 PASSWD PIC X(10) VARYING. 01 EMP-REC-VARS. 05 EMP-NAME PIC X(10) VARYING. 05 EMP-NUMBER PIC S9(4) COMP VALUE ZERO. 05 SALARY PIC S9(5)V99 COMP-3 VALUE ZERO. 05 COMMISSION PIC S9(5)V99 COMP-3 VALUE ZERO. 05 COMM-IND PIC S9(4) COMP VALUE ZERO. EXEC SQL END DECLARE SECTION END-EXEC. EXEC SQL INCLUDE SQLCA END-EXEC. 01 DISPLAY-VARIABLES. 05 D-EMP-NAME PIC X(10). 05 D-SALARY PIC Z(4)9.99. 05 D-COMMISSION PIC Z(4)9.99. 05 D-EMP-NUMBER PIC 9(4). 01 D-TOTAL-QUERIED PIC 9(4) VALUE ZERO. PROCEDURE DIVISION. BEGIN-PGM. EXEC SQL WHENEVER SQLERROR DO PERFORM SQL-ERROR END-EXEC. PERFORM LOGON. QUERY-LOOP. DISPLAY " ". DISPLAY "ENTER EMP NUMBER (0 TO QUIT): " WITH NO ADVANCING. ACCEPT D-EMP-NUMBER. MOVE D-EMP-NUMBER TO EMP-NUMBER. IF (EMP-NUMBER = 0) PERFORM SIGN-OFF. MOVE SPACES TO EMP-NAME-ARR. EXEC SQL WHENEVER NOT FOUND GOTO NO-EMP END-EXEC. EXEC SQL SELECT ENAME, SAL, NVL(COMM, 0) INTO :EMP-NAME, :SALARY, :COMMISSION:COMM-IND FROM EMP WHERE EMPNO = :EMP-NUMBER END-EXEC. PERFORM DISPLAY-INFO. ADD 1 TO D-TOTAL-QUERIED. GO TO QUERY-LOOP. NO-EMP. DISPLAY "NOT A VALID EMPLOYEE NUMBER - TRY AGAIN.". GO TO QUERY-LOOP. LOGON. MOVE "SCOTT" TO USERNAME-ARR. MOVE 5 TO USERNAME-LEN. MOVE "TIGER" TO PASSWD-ARR. MOVE 5 TO PASSWD-LEN. EXEC SQL CONNECT :USERNAME IDENTIFIED BY :PASSWD END-EXEC. DISPLAY " ". DISPLAY "CONNECTED TO ORACLE AS USER: ", USERNAME-ARR. DISPLAY-INFO. DISPLAY " ". DISPLAY "EMPLOYEE SALARY COMMISSION". DISPLAY "-------- ------ ----------". MOVE EMP-NAME-ARR TO D-EMP-NAME. MOVE SALARY TO D-SALARY. IF COMM-IND = -1 DISPLAY D-EMP-NAME, D-SALARY, " NULL" ELSE MOVE COMMISSION TO D-COMMISSION DISPLAY D-EMP-NAME, D-SALARY, " ", D-COMMISSION END-IF. SIGN-OFF. DISPLAY " ". DISPLAY "TOTAL NUMBER QUERIED WAS ", D-TOTAL-QUERIED, ".". DISPLAY " ". DISPLAY "HAVE A GOOD DAY.". DISPLAY " ". EXEC SQL COMMIT WORK RELEASE END-EXEC. STOP RUN. SQL-ERROR. EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC. DISPLAY " ". DISPLAY "ORACLE ERROR DETECTED:". DISPLAY " ". DISPLAY SQLERRMC. EXEC SQL ROLLBACK WORK RELEASE END-EXEC. STOP RUN.