ホスト変数

ここでは、ホスト変数およびホスト変数とデータベースとの値の受け渡しの方法について説明します。

概要

ホスト変数とは、COBOL プログラム内で定義されるデータ項目です。ホスト変数は、データベースとの値の受け渡しに使用されます。ホスト変数は、COBOL プログラムのファイル節、作業場所節、局所記憶節、または連絡節で定義し、1 ~ 48 の範囲の任意のレベル番号を割り当てることができます。レベル-49 は VARCHAR データ項目に予約されています。

埋め込み SQL 文内でホスト変数名を記述する場合は、データ項目名の先頭にコロン (:) を付けてください。コンパイラはこのコロンによって、ホスト変数と同じ名前のテーブルまたはカラムを区別できます。

ホスト変数は、使用方法によって次の 2 つの種類に分けられます。

たとえば、次の文では、: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.

注:

OpenESQL と DB2 プリプロセッサ

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 文内で複数のホスト配列を使用する場合は、各配列の次元を同一にする必要があります。

注:

FOR 句

デフォルトでは、配列全体を 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) に処理済み行の累計数が記録されます。

DB2 プリプロセッサ

SQLERRD(3) には、次の内容が格納されます。

SQLERRD(4) には、次の内容が格納されます。

SQLERRD(5) には、次の内容が格納されます。

インジケータ変数

埋め込み SQL では、インジケータ変数を使用してデータベースに NULL 値を保存したり、データベースから NULL 値を取り込むことができます。 インジケータ変数は、常に次のように定義されます。

pic S9(4) comp-5.

NULL 値

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 データベースを使用している場合は適用されません。