ここでは、ホスト変数およびホスト変数とデータベースとの値の受け渡しの方法について説明します。
ホスト変数とは、COBOL プログラム内で定義されるデータ項目です。ホスト変数は、データベースとの値の受け渡しに使用されます。ホスト変数は、COBOL プログラムのファイル節、作業場所節、局所記憶節、または連絡節で定義し、1 ~ 48 の範囲の任意のレベル番号を割り当てることができます。レベル-49 は VARCHAR データ項目に予約されています。
埋め込み SQL 文内でホスト変数名を記述する場合は、データ項目名の先頭にコロン (:) を付けてください。コンパイラはこのコロンによって、ホスト変数と同じ名前のテーブルまたはカラムを区別できます。
ホスト変数は、使用方法によって次の 2 つの種類に分けられます。
COBOL プログラムからデータベースに転送されるデータを指定します。
データベースから COBOL プログラムに返されるデータを格納します。
たとえば、次の文では、:book-id は、検索する本の ID を表す入力ホスト変数で、:book-title は検索結果を返す出力ホスト変数です。
EXEC SQL SELECT title INTO :book-title FROM titles WHERE title_id=:book-id END-EXEC
埋め込み SQL 文でホスト変数を使用するには、その前にホスト変数を宣言する必要があります。ホスト変数は、埋め込み SQL 文の BEGIN DECLARE SECTION と END DECLARE SECTION で囲んで宣言します。次に例を示します。
EXEC SQL BEGIN DECLARE SECTION END-EXEC 01 id pic x(4). 01 name pic x(30). EXEC SQL END DECLARE SECTION END-EXEC . . . display "あなたの ID を入力してください : " accept id. * 次の文は、ホスト変数「id」に格納された * 内容と同じ社員番号をもつ社員の名前を * 取得し、ホスト変数 * 「name」に返します。 EXEC SQL SELECT emp_name INTO :name FROM employees WHERE emp_id=:id END-EXEC display "ようこそ " name.
注:
BEGIN DECLARE SECTION および END DECLARE SECTION を使用して宣言されていなくても、データ項目をホスト変数として使用できます。
ホスト変数の宣言では、次の点に留意してください。
配列とは、1 つの変数名に関連付けられた複数のデータ項目の集まりです。複数のホスト変数を配列 (ホスト配列) として定義すると、これらの変数を単一の SQL 文で処理できます。
ホスト配列は、INSERT、UPDATE、および DELETE 文の入力変数として使用したり、SELECT 文や FETCH 文の INFO 句で出力変数として使用したりできます。配列を SELECT 文、FETCH 文、DELETE 文、INSERT 文、および UPDATE 文で使用して、大量のデータを扱うことができます。
ホスト配列は、単一のホスト変数と同様に BEGIN DECLARE SECTION と END DECLARE SECTION を使用して宣言します。ただし、配列の次元を OCCURS 句で指定する必要があります。次に例を示します。
EXEC SQL BEGIN DECLARE SECTION END-EXEC 01 AUTH-REC-TABLES 05 Auth-id OCCURS 25 TIMES PIC X(12). 05 Auth-Lname OCCURS 25 TIMES PIC X(40). EXEC SQL END DECLARE SECTION END-EXEC. . . . EXEC SQL CONNECT USERID 'user' IDENTIFIED BY 'pwd' USING 'db_alias' END-EXEC EXEC SQL SELECT au-id, au-lname INTO :Auth-id, :Auth-Lname FROM authors END-EXEC display sqlerrd(3)
この例では、SELECT 文により配列のサイズとして 25 行分が戻されます。SELECT 文が 25 行を超える行を戻すことができる場合には、25 行が戻され、それ以上の行が取り出し可能であるが戻せなかったことを SQLCODE で示します。
SELECT 文は、選択する行の最大数が分かっている場合に使用してください。戻される行数が不明の場合は、FETCH 文を使用してください。配列の使用では、データをバッチで取り込むことができます。これは、情報のスクロールリストを作成する場合に便利です。
単一 SQL 文内で複数のホスト配列を使用する場合は、各配列の次元を同一にする必要があります。
注:
デフォルトでは、配列全体を SQL 文で処理しますが、必要に応じて FOR 句を使用し、処理する配列の要素数を制限できます。これは、UPDATE、INSERT、および DELETE 文で配列の一部のみを処理する場合に特に便利です。
FOR 句では整数型のホスト変数を使用する必要があります。次に例を示します。
EXEC SQL BEGIN DECLARE SECTION END-EXEC 01 AUTH-REC-TABLES 05 Auth-id OCCURS 25 TIMES PIC X(12). 05 Auth-Lname OCCURS 25 TIMES PIC X(40). 01 maxitems PIC S9(4) COMP-5 VALUE 10. EXEC SQL END DECLARE SECTION END-EXEC. . . . EXEC SQL CONNECT USERID 'user' IDENTIFIED BY 'pwd' USING 'db_alias' END-EXEC EXEC SQL FOR :maxitems UPDATE authors SET au_lname = :Auth_Lname WHERE au_id = :Auth_id END-EXEC display sqlerrd(3)
この例では、UPDATE 文により 10 行 (:maxitems の値) が変更されます。
処理される配列の要素数は、ホスト配列の次元数と FOR 句の変数を比較して決定されます。この場合は、最も小さい値が使用されます。
FOR 句の変数の値が 0 以下の場合は、行は処理されません。
注:
COBSQL プリプロセッサ
COBSQL を使用している場合には、FOR 句に関するこの情報は、Oracle データベースを使用している場合のみに適用されます。Sybase データベースや Informix データベースを使用している場合には適用されません。
SQLDA の SQLERRD の第 3 要素 (SQLERRD(3)) には、INSERT、UPDATE、DELETE、および SELECT INTO の各文で処理された行数が記録されます。
OpenESQL プリプロセッサ
FETCH 文の場合には、SQLERRD(3) は必ず直前の FETCH 文で取り込まれた行数が格納されます。
COBSQL および DB2 プリプロセッサ
FETCH 文の場合は、SQLERRD(3) に処理済み行の累計数が記録されます。
SQLERRD(3) には、次の内容が格納されます。
SQLERRD(4) には、次の内容が格納されます。
SQLERRD(5) には、次の内容が格納されます。
埋め込み SQL では、インジケータ変数を使用してデータベースに NULL 値を保存したり、データベースから NULL 値を取り込むことができます。 インジケータ変数は、常に次のように定義されます。
pic S9(4) comp-5.
COBOL とは異なり、SQL では NULL 値を格納できる変数をサポートしています。NULL 値はエントリが存在しないことを意味し、通常は値が不明または未定義です。NULL 値を使用する場合は、数字カラムのゼロや文字カラムの空白文字などの意図的なエントリを、不明なエントリや適用不能なエントリと区別できます。たとえば、価格カラムから取り込んだ値が NULL の場合でも、対応する品目は無料ではありません。価格は無効または未設定です。
また、ホスト変数と対応するインジケータ変数は、両方で 1 つの SQL 値を示します。これらの変数は、どちらも先頭にコロン (:) を付けて記述します。ホスト変数が NULL の場合は、対応するインジケータ変数の値は -1 になります。ホスト変数が NULL 以外の値であれば、インジケータ変数は -1 以外の値になります。
埋め込み SQL 文では、インジケータ変数は対応するホスト変数の直後に記述してください。たとえば、次の例では、埋め込み UPDATE 文内のホスト変数 (saleprice) の直後に、対応するインジケータ変数 (saleprice-null) が記述されています。
EXEC SQL UPDATE closeoutsale SET temp_price = :saleprice:saleprice-null, listprice = :oldprice END-EXEC
この例で、saleprice-null が -1 の値をもつと、UPDATE 文が実行されたときに、次の文として読み込まれます。
EXEC SQL UPDATE closeoutsale SET temp_price = null, listprice = :oldprice END-EXEC
検索条件にはインジケータ変数は使用できません。NULL 値の検索をするには、is null 構成を使用します。 たとえば、次のように使用します。
if saleprice-null equal -1 EXEC SQL DELETE FROM closeoutsale WHERE temp_price is null END-EXEC else EXEC SQL DELETE FROM closeoutsale WHERE temp_price = :saleprice END-EXEC end-if
データがデータベースからホスト変数に取り込まれたときに、切り捨てが実行される場合は、インジケータ変数を別の用途で使用できます。ホスト変数がデータベースから返されるデータを保持できるほど大きくない場合には、SQLCA データ構造体に警告フラグ (sqlwarn1) が設定され、インジケータ変数はデータベース内のデータのサイズに設定されます。
インジケータ変数と同じように、インジケータ配列を使用します。つまり、次のような場合に使用します。
次の例では、インジケータ配列を -1 に設定して、カラムに NULL 値を挿入します。
01 ix PIC 99 COMP-5. . . . EXEC SQL BEGIN DECLARE SECTION END-EXEC 01 sales-id OCCURS 25 TIMES PIC X(12). 01 sales-name OCCURS 25 TIMES PIC X(40). 01 sales-comm OCCURS 25 TIMES PIC S9(9) COMP-5. 01 ind-comm OCCURS 25 TIMES PIC S9(4) COMP-5. EXEC SQL END DECLARE SECTION END-EXEC. . . . PERFORM VARYING iX FROM 1 BY 1 UNTIL ix > 25 MOVE -1 TO ind-comm (ix) END-PERFORM. . . . EXEC SQL INSERT INTO SALES (ID, NAME, COMM) VALUES (:sales_id, :sales_name, :sales_comm:ind-comm) END-EXEC
COBSQL
COBSQL を使用している場合には、インジケータ配列に関するこの情報は、Oracle データベースを使用している場合のみに適用されます。Sybase データベースを使用している場合は適用されません。