4 データ型とホスト変数

この章では、Pro*COBOLプログラムを作成する際に必要となる基本的な情報を、次の内容で説明します。

4.1 Oracle Databaseのデータ型

Oracle Databaseは、内部データ型および外部データ型の2種類のデータ型を認識します。内部データ型はOracle Databaseがデータベース列にどのようにデータを格納するかを指定します。

Oracle Databaseは、データベース疑似列を表す場合にも内部データ型を使用します。外部データ型は、データがホスト変数にどのように格納されるかを指定します。

関連項目:

Oracleの内部(組込みとも呼ばれます)データ型の詳細は、データ型を参照してください。

4.1.1 内部データ型

表4-1は、各Oracle組込みデータ型の説明をまとめたものです。

表4-1 Oracle組込みデータ型の概要

データ型 説明 列の長さおよびデフォルト

CHAR (size)

固定長文字データ。長さsizeは文字数またはバイト数(各国語キャラクタ・セットによる)。

表内の行ごとに固定(後続の空白を含む)。列サイズは、固定幅の各国語キャラクタ・セットの場合は文字数、または1文字を格納するために必要なバイト数で、各行の上限は2000バイトです。デフォルトのサイズは、各国語キャラクタ・セットに応じて、各行につき1文字または1バイトです。サイズを設定する際は、キャラクタ・セット(1バイトまたはマルチバイト)を考慮に入れてください。

VARCHAR2 (size)

固定長文字データ。長さサイズは文字数またはバイト数(各国語キャラクタ・セットによる)。最大サイズを指定する必要があります。

行ごとに可変。列サイズは、固定幅の各国語キャラクタ・セットの場合は文字数、可変幅の各国語キャラクタ・セットの場合はバイト数です。最大サイズは、1文字を格納するために必要なバイト数によって決定されます。各行の上限は4000バイトです。デフォルトのサイズは、各国語キャラクタ・セットに応じて1文字または1バイトです。

NCHAR (size)

固定長文字データ。長さサイズは文字数またはバイト数(各国語キャラクタ・セットによる)。

表内の行ごとに固定(後続の空白を含む)。列サイズは、固定幅の各国語キャラクタ・セットの場合は文字数、可変幅の各国語キャラクタ・セットの場合はバイト数です。最大サイズは、1文字を格納するために必要なバイト数によって決定されます。各行の上限は2000バイトです。デフォルトは、キャラクタ・セットに応じて1文字または1バイトです。

NVARCHAR2 (size)

可変長データ。長さサイズは文字数またはバイト数(各国語キャラクタ・セットによる)。最大サイズを指定する必要があります。

行ごとに可変。列サイズは、固定幅の各国語キャラクタ・セットの場合は文字数です。最大サイズは、1文字を格納するために必要なバイト数によって決定されます。各行の上限は4000バイトです。デフォルトは、キャラクタ・セットに応じて1文字または1バイトです。

CLOB

シングルバイト文字データ

最大2^32 - 1 バイトまたは4GB。

NCLOB

シングルバイトまたは固定長マルチバイト各国語キャラクタ・セット(NCHAR)データ

最大2^32 - 1 バイトまたは4GB。

LONG

可変長文字データ

表内の行ごとに可変、最大で1行当たり2^31 - 1 バイトまたは2GB。下位互換性を維持するために提供されています。

NUMBER(p、s)

可変長数字データ。最大精度pまたは位取りs (あるいはその両方)は38。

行ごとに可変。1列に必要な最大領域は1行当たり21バイト。

DATE

日付および時刻の固定長データ(紀元前(B.C.E) 4712年1月1日から、西暦4712年12月31日まで)

表内の行ごとに7バイトで固定。デフォルトの書式は、NLS_DATE_FORMATパラメータで指定される文字列(DD-MON-YYなど)。

BLOB

非構造型バイナリ・データ

最大2^32 - 1 バイトまたは4GB。

BFILE

外部ファイルに格納されたバイナリ・データ

最大2^32 - 1 バイトまたは4GB。

RAW (size)

可変長ロー・バイナリ・データ

表の行ごとに可変、1行当たり最大2000バイト。最大サイズを指定する必要があります。下位互換性を維持するために提供されています。

LONG RAW

可変長ロー・バイナリ・データ

表内の行ごとに可変、最大で1行当たり2^31 - 1 バイトまたは2GB。下位互換性を維持するために提供されています。

ROWID

行アドレスを表すバイナリ・データ

表の行ごとに10バイト(拡張ROWID)または6バイト(制限付きROWID)で固定。

4.1.2 外部データ型

外部データ型には内部データ型がすべて含まれ、サポートされる他のホスト言語で使用するいくつかのデータ型も含まれています。データ型の同値化ではデータ型名を、動的SQL方法4ではデータ型コードを使用します。次の表に、外部データ型を示します。

表4-2 外部データ型

名前 コード 説明

CHAR

1

96

<= 65535バイト、可変長文字列()

<= 65535バイト、固定長文字列()

CHARF

96

<= 65535バイト、固定長文字列

CHARZ

97

<= 65535バイト、固定長、NULL終了文字列()

DATE

12

7バイト、固定長日付/時刻値

DECIMAL

7

COBOLパック10進数

DISPLAY

91

先行符号付きCOBOL数値文字列

DISPLAY TRAILING

152

COBOL後続符号付き数値

FLOAT

4

4バイトまたは8バイトの浮動小数点数

INTEGER

3

2バイト、4バイトまたは8バイトの符号付き整数。

LONG

8

<= 2147483647バイト、固定長文字列

LONG RAW

24

<= 217483647バイト、固定長バイナリ・データ

LONG VARCHAR

94

<= 217483643バイト、可変長文字列

LONG VARRAW

95

<= 217483643バイト、可変長バイナリ・データ

NUMBER

2

2進化10進数形式で表したOracle内部形式番号。

OVERPUNCH LEADING

172

埋込み先行符号付きCOBOL数値文字列

OVERPUNCH TRAILING

154

埋込み後続符号付きCOBOL数値文字列(PIC S9(n)V9(m) DISPLAY形式での宣言と同じ)

RAW

23

<= 65535バイト、固定長バイナリ・データ()

ROWID

11

固定長バイナリ値(システム固有)

STRING

5

<= 65535バイト、NULL終了文字列()

UNSIGNED

68

2バイトまたは4バイトの符号なし整数

UNSIGNED DISPLAY

153

COBOL符号なし数値

VARCHAR

9

<= 65533バイト、可変長文字列

VARCHAR2

1

<= 65535バイト、可変長文字列()

VARNUM

6

可変長バイナリ数

VARRAW

15

<= 65533バイト、可変長バイナリ・データ

注意:

CHARのデータ型コードは、PICX=VARCHAR2のときには1、PICX=CHARFのときには96になります。

一部のプラットフォームでは、最大サイズが32767 (32K)です。

4.1.2.1 CHAR

CHARの動作は、オプションPICXの設定によって異なります。PICXを参照してください。

4.1.2.2 CHARF

デフォルトでは、CHARFデータ型はすべての非可変長文字ホスト変数を表します。CHARFデータ型は、固定長文字列の格納に使用します。ほとんどのプラットフォームでは、CHARF値の最大長は65535 (64K)バイトです。PICXを参照してください。

入力時。Oracleでは、入力ホスト変数に指定されたバイト数を読み取り、後続の空白を切り捨てずに、ターゲット・データベース列に入力値を格納します。

入力値がデータベース列の定義より長い場合は、エラーが発生します。入力値がすべて空白の場合は、空白文字列が格納されます。

出力時。Oracleからは出力ホスト変数に指定したバイト数が戻され、必要に応じて空白が埋め込まれて、出力値がターゲット・ホスト変数に割り当てられます。NULLが戻された場合、変数の元の値は上書きされません。

出力値がホスト変数の宣言長より長い場合、Oracleはホスト変数に割り当てる前に出力値を切り捨てます。標識変数が使用可能な場合、標識変数は出力値の元の長さに設定されます。

4.1.2.3 CHARZ

CHARZデータ型は、固定長のNULL終了文字列を表します。ほとんどのプラットフォームでは、CHARZ値の最大長は65535バイトです。通常Pro*COBOLでは、この外部型は必要ありません。

4.1.2.4 DATE

DATEデータ型は、日付および時刻を7バイトの固定長フィールドで表します。表4-3に示すように、世紀、年、月、日、時(24時間制)、分および秒は、左から右にこの順序で格納されます。

表4-3 日付書式

バイト 1 2 3 4 5 6 7

意味

世紀

1994年10月17日午後1時23分12秒

119

194

10

17

14

24

13

世紀と年を表すバイトは、100を加算した表記です。時間、分および秒は、1を加算した表記です。B.C.E.(西暦紀元前)の日付は99以下です。エポックは、紀元前4712年1月1日です。この日付の場合、世紀のバイトは53で、年のバイトは88です。時間のバイト範囲は1から24です。分と秒の範囲は、1から60です。時刻のデフォルトは、午前零時(1, 1, 1)です。Pro*COBOLは「日時および時間隔のデータ型記述子」に記載されているとおり、追加でさらに5つの日時データ型をサポートします。

4.1.2.5 DECIMAL

DECIMALデータ型は、計算用のパック10進数を表します。COBOLでは、ホスト変数は暗黙的な小数点を持つ符号付きCOMP-3フィールドであることが必要です。データ変換中に有効な数字がなくなると、値は宣言された長さに切り捨てられます。

4.1.2.6 DISPLAY

DISPLAYデータ型は数値文字データを表します。DISPLAYデータ型は、COBOLのDISPLAY SIGN LEADING SEPARATEの数値を参照し、PIC S9(n)にはn + 1バイトの記憶域が、PIC S9(n)V9(d)にはn + d + 1バイトの記憶域が必要です。

4.1.2.7 FLOAT

FLOATデータ型は、小数部分を持つ数値またはINTEGERデータ型の容量を超える数値を表します。FLOATは、COBOLデータ型COMP-1 (4バイトの浮動小数点)およびCOMP-2 (8バイトの浮動小数点)に関連しています。

Oracleでは、数値の内部形式が10進数であるため、浮動小数点の場合よりも大きい精度で数を表現できます。

注意: SQL文でFLOAT値を比較する場合、FLOATデータ型では数値がバイナリ(10進数ではない)で格納されるのでSQLファンクションROUNDを使用します。小数部分は正確に変換されません。

4.1.2.8 INTEGER

INTEGERデータ型は、小数部分のない数値を表します。整数は、2バイト、4バイトまたは8バイトの符号付き2進数です。ワード内のバイトの並びはプラットフォームによって異なります。入力および出力ホスト変数に長さを指定する必要があります。出力時に、列に小数部があると、小数点以降の桁が切り捨てられます。

4.1.2.9 LONG

LONGデータ型は、固定長の文字列を表します。LONGデータ型はVARCHAR2データ型と似ていますが、LONG値の最大長は2147483647バイト(2GB)である点で異なります。

4.1.2.10 LONG RAW

LONG RAWデータ型は、固定長バイナリ・データまたは固定長バイト文字列を表します。LONG RAW値の最大長は、2147483647バイト(2GB)です。

LONG RAWデータはLONGデータと似ていますが、OracleではLONG RAWデータの意味は解釈されず、LONG RAWデータをあるシステムから別のシステムへ送信してもキャラクタ・セットは変換されません。

4.1.2.11 LONG VARCHAR

LONG VARCHARデータ型は、可変長の文字列を表します。LONG VARCHAR変数では、4バイトの長さフィールドに文字列フィールドが続きます。文字列フィールドの最大長は2147483643バイトです。EXEC SQL VAR文では、4バイトの長さフィールドは含めないでください

4.1.2.12 LONG VARRAW

LONG VARRAWデータ型は、バイナリ・データまたはバイト文字列を表します。LONG VARRAW変数では、4バイトの長さフィールドにデータ・フィールドが続きます。データ・フィールドの最大長は2147483643バイトです。EXEC SQL VAR文では、4バイトの長さフィールドは含めないでください

4.1.2.13 NUMBER

NUMBERデータ型は、COBOLデータ型では表せないOracle NUMBERの内部書式を表します。

4.1.2.14 OVER-PUNCH

OVER-PUNCHは、COBOL言語用のデフォルトの符号付き数値です。各桁は10を基数としたASCII形式またはEBCDIC形式で格納され、1つの桁がコンピュータ記憶域の1バイトを占めます。符号は、使用されるバイトの1つの上位ニブルに格納されます。このデータ型がOVER-PUNCHと呼ばれるのは、符号が最初または最後のバイトのどちらかに格納された数字に埋め込まれるためです。デフォルトの符号位置は、後続バイトです。OVER-PUNCHの指定には、PIC S9(n)V9(m) TRAILINGまたはPIC S9(n)V9(m) LEADINGを使用します。

4.1.2.15 RAW

RAWデータ型は、固定長バイナリ・データまたは固定長バイト文字列を表します。ほとんどのプラットフォームでは、RAW値の最大長は65535バイトです。

RAWデータはCHARデータと似ていますが、OracleではRAWデータの意味は解釈されず、RAWデータをあるシステムから別のシステムへ送信してもキャラクタ・セットの変換は行われません。

4.1.2.16 ROWID

ROWIDデータ型は、COBOLのデータベース行識別子です。論理ROWIDおよび物理ROWIDの両方(およびOracle表以外のROWID)をサポートするために、ユニバーサルROWID (UROWID)が定義されています。このデータ型にはSQL-ROWID疑似型を使用します(「ユニバーサルROWID」を参照してください)。

VARCHAR2ホスト変数を使用すると、ROWIDを読込み可能な形式で格納できます。ROWIDを選択またはフェッチしてVARCHAR2ホスト変数に入れると、Oracleはそのバイナリ値を18バイトの文字列に変換し、次の書式で戻します。

BBBBBBBB.RRRR.FFFF

ここで、BBBBBBBBはデータベース・ファイルのブロック、RRRRはブロック内の行(最初の行は0)、FFFFはデータベース・ファイルを示します。これらの値は16進数です。たとえば、次のROWIDを考えます。

0000000E.000A.0007 

これは、7番目のデータベース・ファイルの15番目のブロックの11行目を示します。

通常、ROWIDをフェッチしてVARCHAR2ホスト変数に入れてから、UPDATE文またはDELETE文のWHERE句に含まれるROWID疑似列とホスト変数を比較します。そのようにして、カーソルによってフェッチされた最終行を識別できます。「CURRENT OF句の擬似実行」の例を参照してください。

注意: 完全な移植性が必要な場合、またはアプリケーションでTransparent Gatewayを介してOracle以外のデータベースと通信する場合は、VARCHAR2ホスト変数の宣言時に最大長の256 (18ではない)バイトを指定します。また、アプリケーションがOracle Open Gatewayを介してOracle以外のデータ・ソースと通信する場合も、最大長として256バイトを指定します。ホスト変数の内容は何も類推できませんが、SQL文では正常に動作します。

4.1.2.17 STRING

STRINGデータ型はVARCHAR2データ型と似ていますが、STRING値は常にLOW-VALUE文字で終了する点が異なります。通常、このデータ型はPro*COBOLでは使用されません。

4.1.2.18 UNSIGNED

UNSIGNEDデータ型は符号なし整数を表します。通常、このデータ型はPro*COBOLでは使用されません。

4.1.2.19 VARCHAR

VARCHARデータ型は、可変長の文字列を表します。VARCHAR変数には、2バイトの長さフィールドと、その後に続く65533バイトの文字列フィールドがあります。ただし、VARCHAR配列要素では、文字列フィールドの最大長は65530バイトです。VARCHAR変数の長さを指定するときは、長さフィールド用に必ず2バイトを付加してください。さらに長い文字列には、LONG VARCHARデータ型を使用してください。EXEC SQL VAR文には、2バイトの長さフィールドを含めないでください

4.1.2.20 VARCHAR2

VARCHAR2データ型は、可変長の文字列を表します。ほとんどのプラットフォームでは、VARCHAR2値の最大長は65535バイトです。

VARCHAR2(n)値の最大長は、文字数ではなくバイト数で指定します。したがって、VARCHAR2(n)変数にマルチバイト・キャラクタを格納する場合、最大長はn文字より少なくなります。

入力時。 Oracleは入力ホスト変数に指定されたバイト数を読み込み、後続の空白文字を取り除き、入力値をターゲット・データベース列に格納します。

入力値がデータベース列の定義より長い場合は、エラーが発生します。すべて空白の入力値は、OracleではNULLとして扱われます。

文字値が有効な数値を表している場合は、Oracleはその文字値をNUMBER列値に変換できます。文字値が有効な数値を表していない場合は、エラーが発生します。

出力時。 Oracleからは出力ホスト変数に指定したバイト数が戻され、必要に応じて空白が埋め込まれて、出力値がターゲット・ホスト変数に割り当てられます。NULLが戻されると、Oracleはホスト変数に空白文字を埋めます。

出力値がホスト変数の宣言長より長い場合、Oracleはホスト変数に割り当てる前に出力値を切り捨てます。標識変数が使用可能な場合、標識変数は出力値の元の長さに設定されます。

Oracleでは、NUMBER列値を文字値に変換できます。文字ホスト変数の長さによって精度が決定します。ホスト変数の長さがその数に対して短すぎる場合は、科学表記法が使用されます。たとえば、列値123456789を選択して長さ6のホスト変数に入れると、Oracleはホスト変数に値1.2E08を戻します。

4.1.2.21 VARNUM

VARNUMデータ型は書式がNUMBERと似ていますが、通常はPro*COBOLでは使用されません。

4.1.2.22 VARRAW

VARRAWデータ型は、可変長バイナリ・データまたは可変長バイト文字列を表します。VARRAWデータ型はRAWデータ型に似ていますが、VARRAW変数の場合は2バイトの長さフィールドに<= 65533バイトのデータ・フィールドが続きます。さらに長い文字列には、LONG VARRAWデータ型を使用してください。EXEC SQL VAR文では、2バイトの長さフィールドは含めないでください。VARRAW変数の長さを取得するには、長さフィールドを参照します。

4.1.2.23 SQL疑似列および関数

SQLは、表4-4に示す疑似列を認識します。これらの疑似列は、特定のデータ項目を戻します。

表4-4 擬似列および内部データ型

疑似列 内部データ型

CURRVAL

NUMBER

LEVEL

NUMBER

NEXTVAL

NUMBER

ROWID

ROWID

ROWNUM

NUMBER

疑似列は、実際に表に存在する列ではありません。ただし、疑似列は列のように扱われるため、疑似列の値を表からSELECTする必要があります。疑似列の値は、ダミー表からSELECTする方が便利な場合もあります。

さらにSQLは、表4-5に示すパラメータなしの関数を認識します。これらの関数も、特定のデータ項目を戻します。

表4-5 関数および内部データ型

機能 内部データ型

SYSDATE

DATE

UID

NUMBER

USER

VARCHAR2

SQLの疑似列および関数は、SELECT文、INSERT文、UPDATE文およびDELETE文で参照できます。次の例では、従業員の雇用後の月数の計算にSYSDATEを使用しています。

     EXEC SQL SELECT MONTHS_BETWEEN(SYSDATE, HIREDATE) 
         INTO :MONTHS-OF-SERVICE 
         FROM EMP 
         WHERE EMPNO = :EMP-NUMBER
     END EXEC. 

これから、SQLの疑似列および関数を簡単に説明します。

CURRVALは、指定された順序における現行の番号を戻します。CURRVALを参照する前に、NEXTVALを使用して順序番号を生成する必要があります。

LEVELは、ツリー構造におけるノードのレベル番号を戻します。ルートはレベル1、ルートの子はレベル2、孫はレベル3になります。

SELECT CONNECT BY文でLEVELを使用して、表の一部の行または全部の行をツリー構造に取り込むことができます。また、ORDER BY句またはGROUP BY句でLEVELを使用すると、ツリー内の各レベルでデータが分離されます。

問合せでツリーが検索される方向(ルートから下へ、またはブランチから上へ)は、PRIOR演算子で指定します。ツリーのルートを識別する条件は、START WITH句で指定します。

NEXTVALは、指定された順序における次の番号を戻します。順序を作成した後、それを使用してトランザクション用に一意の順序番号を作成できます。次の例では、順序partnoで部品番号を割り当てます。

     EXEC SQL INSERT INTO PARTS 
         VALUES (PARTNO.NEXTVAL, :DESCRIPTION, :QUANTITY, :PRICE
     END EXEC.

トランザクションで順序番号が生成された場合は、そのトランザクションをコミットまたはロールバックすると順序番号が増分されます。NEXTVALを参照すると、現行の順序番号がCURRVALに格納されます。

ROWNUMは、表から行が選択された順序を示す番号を戻します。最初に選択された行のROWNUMは1に、2番目に戻された行のROWNUMは2になります。SELECT文にORDER BY句が含まれている場合は、ソート選択された行にROWNUMが割り当てられたにソートされます。

ROWNUMを使用して、SELECT文で戻される行数を制限できます。また、UPDATE文でROWNUMを使用して、表の各行に一意の値を割り当てることもできます。WHERE句でROWNUMを使用した場合は、取り出される行数のみが制限され、SELECT文の処理は停止されません。WHERE句でのROWNUMの適切な使用方法は、次の方法のみです。

     ... WHERE ROWNUM < constant END-EXEC. 

これは、ROWNUMの値は行が取り出されるときにのみ増加するためです。次のように指定した場合、4行目までは取り出されないため、この検索条件が満たされません。

     ... WHERE ROWNUM = 5 END-EXEC. 

SYSDATEは、現在の日付と時刻を戻します。

UIDは、Oracleユーザーに割り当てられた一意のID番号を戻します。

USERは、Oracleカレント・ユーザーの名前を戻します。

4.2 日時および時間隔のデータ型記述子

Pro*COBOLでサポートされるOCI日時および時間隔のデータ型を簡単に説明します。

関連項目:

日時データ型記述子の詳細は、『Oracle Database SQL言語リファレンス』を参照してください

ANSI DATE

ANSI DATEDATEに基づいていますが、時刻部分が含まれていません。(したがって、タイム・ゾーンも含まれていません。)ANSI DATEは、DATEデータ型のANSI仕様部の後に指定します。ANSI DATEDATEまたはタイムスタンプ・データ型に割り当てると、Oracle DATEの時間部分およびタイムスタンプがゼロに設定されます。DATEまたはタイムスタンプをANSI DATEに割り当てると、時刻部分は無視されます。

このデータ型ではなく、日付および時刻が含まれているTIMESTAMPデータ型の使用をお薦めします。

TIMESTAMP

TIMESTAMPデータ型は、DATEデータ型の拡張です。DATEデータ型の年、月、日の他、時、分、秒の値が格納されます。タイム・ゾーンはありません。TIMESTAMPデータ型の書式は次のようになります。

TIMESTAMP(fractional_seconds_precision) 

fractional_seconds_precision(オプション)では、SECOND日時フィールドの小数部の桁数を指定します。桁数の範囲は0から9です。デフォルトは6です。

TIMESTAMPWITHTIMEZONE

TIMESTAMP WITH TIME ZONE (TSTZ)データ型はTIMESTAMPの改良型で、その値に明示的なタイム・ゾーン置換が含まれています。タイムゾーンによる時差は、地方時とUTC(協定世界時、旧称はグリニッジ標準時)との時差(時および分単位)です。TIMESTAMP WITH TIME ZONEデータ型の書式は次のとおりです。

TIMESTAMP(fractional_seconds_precision) WITH TIME ZONE

fractional_seconds_precision(オプション)では、SECOND日時フィールドの小数部の桁数を指定します。桁数の範囲は0から9です。デフォルトは6です。

2つのTIMESTAMP WITH TIME ZONE値がUTCで同じ時刻を表す場合は、データに格納されたTIME ZONEオフセットにかかわらず、同一であるとみなされます。

TIMESTAMPWITHLOCALTIMEZONE

TIMESTAMP WITH LOCAL TIME ZONE (TSLTZ)データ型はTIMESTAMPの別の改良型で、その値にタイム・ゾーン置換が含まれています。格納される値の形式はTIMESTAMPと同じです。このデータ型とTIMESTAMP WITH TIME ZONEとの違いは、データベースに格納されるデータがデータベース・タイム・ゾーンに正規化されること、およびタイム・ゾーン置換が列データの一部として格納されないことです。ユーザーがデータを取り出すと、そのユーザーのローカル・セッション・タイム・ゾーンでデータが戻されます。

タイムゾーンによる時差は、地方時とUTC(協定世界時、旧称はグリニッジ標準時)との時差(時および分単位)です。TIMESTAMP WITH LOCAL TIME ZONEデータ型の書式は次のとおりです。

TIMESTAMP(fractional_seconds_precision) WITH LOCAL TIME ZONE

fractional_seconds_precision(オプション)では、SECOND日時フィールドの小数部の桁数を指定します。桁数の範囲は0から9です。デフォルトは6です。

INTERVALYEARTOMONTH

INTERVAL YEAR TO MONTHは、YEARおよびMONTH日時フィールドを使用して期間を格納します。INTERVAL YEAR TO MONTHデータ型の書式は次のようになります。

INTERVAL YEAR(year_precision) TO MONTH

year_precision(オプション)には、YEAR日時フィールドの桁数を指定します。year_precisionのデフォルト値は2です。

INTERVALDAYTOSECOND

INTERVAL DAY TO SECONDデータ型には、日、時間、分および秒による期間が格納されます。INTERVAL DAY TO SECONDデータ型の書式は次のようになります。

INTERVAL DAY (day_precision) TO SECOND(fractional_seconds_precision)

各パラメータの意味は次のとおりです。

  • day_precisionは、DAY日時フィールドの桁数です。これはオプションです。0から9までの値を使用できます。デフォルトは2です。

  • fractional_seconds_precisionは、SECOND日時フィールドの小数部の桁数です。これはオプションです。0から9までの値を使用できます。デフォルトは6です。

注意:

日時データのDML操作で正しい結果を得るには、組込みSQLファンクションDBTIMEZONEおよびSESSIONTIMEZONEで問い合せることによって、データベースおよびセッションのタイムゾーンを確認します。タイム・ゾーンが手動で設定されていない場合、デフォルトではオペレーティング・システムのタイム・ゾーンが使用されます。オペレーティング・システムのタイム・ゾーンがOracleで有効なタイム・ゾーンではない場合、UTCがデフォルト値として使用されます。

4.3 ホスト変数

ホスト変数は、ホスト・プログラムおよびサーバーで通信する際のキーとなります。一般的に、ホスト・プログラムはサーバーにデータを入力し、サーバーはホスト・プログラムにデータを出力します。サーバーは入力データをデータベース列に格納し、出力データをプログラムのホスト変数に格納します。

4.3.1 ホスト変数の宣言

ホスト変数は、Pro*COBOLでサポートされているCOBOLデータ型を使用しCOBOLの規則に従って宣言します。COBOLデータ型には、ソース/ターゲット・データベース列との互換性が必要です。

サポートされているCOBOL変数宣言とその説明、対応する外部データ型およびOracleデータ型コードは、表4-6を参照してください。

表4-6 ホスト変数の宣言

変数の宣言 説明 外部データ型 型コード

PIC X...X

PIC X(n)

PIC X...X VARYING

PIC X(n) VARYING

1バイト文字からなる固定長文字列(1)

1バイト文字からなる長さnの文字列

1バイト文字からなる可変長文字列(12)

1バイト文字からなる可変長文字列(最大長n)(2)

CHARF

VARCHAR

96

9

PIC N...N

PIC G...G

PIC N(n)

PIC G(n)

PIC N...N VARYING

PIC N(n) VARYING

PIC G...G VARYING

PIC G(n) VARYING

マルチバイトNCHAR文字からなる固定長文字列

文字(13)

マルチバイトNCHAR文字からなるn文字の文字列

(3)

マルチバイト・キャラクタからなる可変長文字列(23)

マルチバイト・キャラクタからなる可変長文字列(最大長n)

文字(23)

CHARF

VARCHAR

96

9

PIC S9...9 BINARY

PIC S9(n) BINARY

PIC S9...9 COMP

PIC S9(n) COMP

PIC S9...9 COMP-4

PIC S9(n) COMP-4

整数(457)

INTEGER

3

PIC S9...9 COMP-5

PIC S9(n) COMP-5

バイトスワップ整数(4567)

INTEGER

3

COMP-1

COMP-2

浮動小数点数(5)

FLOAT

4

PIC S9...9[V9...9] COMP-3

PIC S9(n)[V9(n)] COMP-3

PIC S9...9[V9...9]

PACKED-DECIMAL

PIC S9(n)[V9(n)]

PACKED-DECIMAL

パック10進数(45)

DECIMAL

7

PIC S9...9[V9...9] DISPLAY

SIGN LEADING SEPARATE

PIC S9(n)[V9(m)] DISPLAY

SIGN LEADING SEPARATE

PIC S9...9[V9...9] DISPLAY

SIGN TRAILING SEPARATE

PIC S9(n)[V9(m)] DISPLAY

SIGN TRAILING SEPARATE

先行符号表示(811)

後続符号表示(8)

DISPLAY

DISPLAY TRAILING

91

152

PIC 9...9 DISPLAY

PIC 9(n)[V9(m)] DISPLAY

符号なし表示(9)

UNSIGNED DISPLAY

153

PIC S9...9[V9...9] DISPLAY

SIGN TRAILING

PIC S9(n)[V9(m)] DISPLAY

SIGN TRAILING

PIC S9...9[V9...9] DISPLAY

SIGN LEADING

PIC S9(n)[V9(m)] DISPLAY

SIGN LEADING

埋込み後続符号付き(9)

埋込み先行符号付き(9)

OVER-PUNCH

TRAILING

OVER-PUNCH LEADING

154

172

SQL-CURSOR

カーソル変数

SQL-CONTEXT

ランタイム・コンテキスト

SQL-ROWID

ユニバーサルROWID

UROWID

104

SQL-BFILE

外部バイナリ・ファイル

BFILE

112

SQL-BLOB

バイナリLOB

BLOB

113

SQL-CLOB

キャラクタLOB

CLOB

114

注意:

  1. X...Xおよび9...9は、Xまたは9の個数(n)をそれぞれ表します。可変長文字列の場合、nは最大長です。

  2. キーワードVARYINGは、外部データ型VARCHARを文字列に割り当てます。詳細は、「VARCHAR変数の宣言」を参照してください。

  3. Pro*COBOLのソース・ファイルでPIC NまたはPIC Gデータ型を使用する場合は、そのデータ型がCOBOLコンパイラでサポートされていることを事前に確認してください。

  4. 符号付きの数(PIC S...)のみ使用できます。ただし、浮動小数点数の場合はPIC文字列は受け入れられません。

  5. すべてのCOBOLコンパイラで、これらのデータ型が必ずサポートされているとはかぎりません。

  6. COMPまたはCOMP-5では、小数部分を持つ数値は受け入れられません。また、スケーリングされた2進数はサポートされません。SPARC Solarisの64ビット・プラットフォームでは、COMP-5はサポートされません。かわりにCOMPを使用してください。

  7. 整数の最大値はnから18です。この値は、オペレーティング・システムおよびPro*CobolとCobolのコンパイラによって異なります。

  8. DISPLAYおよびSIGNはどちらも省略できます。

  9. DISPLAYは省略できます

  10. TRAILINGを省略した場合、埋め込まれる符号の位置はオペレーティング・システムによって異なります。

  11. LEADINGは省略できます。

表4-6および表4-7の記号{と}は、中に省略可能なエントリが含まれることを示します。記号{および}は、記号|で区切られたトークンのどちらかを選択する必要があることを示します。

表4-7は、各内部データ型の間で変換可能なすべてのCOBOLデータ型を示します。

表4-7 互換性のあるOracleの内部データ型

内部データ型 注意 COBOLデータ型 説明

CHAR(x) VARCHAR2(y)

(1)

(1)

PIC X(n)

PIC X...X

PIC X(n) VARYING

PIC X...X VARYING

PIC S9...9 COMP

PIC S9(n) COMP

PIC S9...9 BINARY

PIC S9(n) BINARY

PIC S9...9 COMP-5

PIC S9(n) COMP-5

COMP-1

COMP-2

PIC S9...9[V9...9] COMP-3

PIC S9(n)[V9(n)] COMP-3

PIC S9...9[V9...9] DISPLAY

PIC S9(n)[V9(n)] DISPLAY

文字列

n文字の文字列

可変長文字列

整数

整数

整数

浮動小数点数

パック10進数

表示

NCHAR(u) NVARCHAR2(v)

(2)

(2)

PIC {N...N | G...G}

PIC { N(n) | G(n)}

各国語キャラクタ文字列

n文字の各国語キャラクタ文字列

BLOB

CLOB

NCLOB

BFILE

SQL-BLOB

SQL-CLOB

SQL-NCLOB

SQL-BFILE

バイナリLOB

キャラクタLOB

各国語キャラクタLOB

外部バイナリ・ファイル

NUMBER

NUMBER (p,s)

(3)

PIC S9...9 COMP

PIC S9(n) COMP

PIC S9...9 BINARY

PIC S9(n) BINARY

PIC S9...9 COMP-5

PIC S9(n) COMP-5

COMP-1

COMP-2

PIC S9...9V9...9 COMP-3

PIC S9(n)V9(n) COMP-3

PIC S9...9V9...9 DISPLAY

PIC S9(n)V9(n) DISPLAY

PIC [X...X| N...N| G...G]

PIC [X(n)| N(n)| G(n)]

PIC X...X VARYING

PIC X(n) VARYING

整数

整数

整数

浮動小数点数

パック10進数

表示

文字列(4)

n文字の文字列(4)

可変長文字列

nバイトの可変長文字列

DATE

LONG

RAW

LONG RAW

ROWID

(5)

(1)

(6)

PIC X(n)

PIC X...X

PIC X(n)

PIC X(n) VARYING

PIC X...X VARYING

SQL-ROWID

nバイトの文字列

文字列

nバイトの可変長文字列

ユニバーサルROWID

注意:

バグ7225844 - パラメータ「1<= x < =2000バイト、デフォルトは1」に次から置き換えられました

置換元

<= x < =2000バイト、デフォルトは1。

  1. 1<=x <= 2000バイト、デフォルトは1。1<=y <=4000 バイト、デフォルトは1。

  2. 1<=u<=2000バイト、デフォルトは1。1<=v<=4000バイト、デフォルトは1。

  3. pの範囲は2から38で、sの範囲は-84から127です。

  4. 文字列が、0から9、ピリオド(.)、+、-、E、e、の変換可能な文字で構成されている場合は、文字列を数値に変換できます。システムのグローバリゼーション・サポート(旧称National Language SupportまたはNLS)の設定によっては、小数点がピリオド(.)からカンマ(,)へ変更になる場合があります。

  5. 文字列型に変換された場合のDATEのデフォルトのサイズは、システムで有効になっているNCHARの設定によって決まります。2進値に変換された場合の長さは7バイトです。

  6. 文字列型に変換すると、ROWIDには18から4000バイト必要です。ROWIDも文字型に変換できます。すべての新規プログラムにSQL-ROWIDを使用することをお薦めします。

4.3.1.1 宣言の例

次の例では、この後で使用するいくつかのホスト変数を宣言しています。

    ... 
 01  STR1  PIC X(3). 
 01  STR2  PIC X(3) VARYING. 
 01  NUM1  PIC S9(5) COMP. 
 01  NUM2  COMP-1. 
 01  NUM3  COMP-2. 
     ... 

次の例に示すように、簡単なCOBOL型の1次元表を宣言することもできます。

     ... 
 01  XMP-TABLES. 
     05  TAB1  PIC XXX OCCURS 3 TIMES. 
     05  TAB2  PIC XXX VARYING OCCURS 3 TIMES. 
     05  TAB3  PIC S999 COMP-3 OCCURS 3 TIMES. 
     ... 
4.3.1.2 初期化

ホスト変数(疑似型のホスト変数を除く)は、次の例に示すように、VALUE句を使用して初期化できます。

 01  USERNAME    PIC X(10) VALUE "SCOTT". 
 01  MAX-SALARY  PIC S9(4) COMP VALUE 5000.
 

文字変数に割り当てられた文字列値がその変数の宣言長より短い場合は、文字列の右側に空白が埋め込まれます。文字変数に割り当てられた文字列値が宣言長より長い場合は、文字列は切り捨てられます。

疑似型の変数にVALUES句を指定しても、すべて無視され、廃棄されます(エラーや警告は発行されません)。

4.3.1.3 制限事項

アルファベット文字(PIC A)変数および編集済データ項目はホスト変数として使用できません。このため、host変数について次の変数宣言はできません。

     .... 
 01  AMOUNT-OF-CHECK  PIC ****9.99. 
 01  FIRST-NAME       PIC A(10). 
 01  BIRTH-DATE       PIC 99/99/99.
 
     .... 

4.3.2 ホスト変数の参照

ホスト変数は、SQL DML文で使用します。次の例に示すように、SQL文ではホスト変数の前にコロン(:)を付ける必要がありますが、COBOL文ではコロンを付けません。

 WORKING-STORAGE SECTION. 
     ... 
     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 
 01  EMP-NUMBER  PIC S9(4) COMP VALUE ZERO. 
 01  EMP-NAME    PIC X(10) VALUE SPACE. 
 01  SALARY      PIC S9(5)V99 COMP-3. 
     EXEC SQL END DECLARE SECTION END-EXEC. 
     ... 
 PROCEDURE DIVISION. 
     ... 
     DISPLAY "Employee number? " WITH NO ADVANCING. 
     ACCEPT EMP-NUMBER. 
     EXEC SQL SELECT ENAME, SAL 
         INTO :EMP-NAME, :SALARY FROM EMP 
         WHERE EMPNO = :EMP-NUMBER 
     END-EXEC. 
     COMPUTE BONUS = SALARY / 10. 
     ... 

次の例に示すように、表または列と同じ名前をホスト変数に指定できます。ただし、このようにすると混乱を招く恐れがあります。

 WORKING-STORAGE SECTION. 
     ... 
     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 
 01  EMPNO  PIC S9(4) COMP VALUE ZERO. 
 01  ENAME  PIC X(10) VALUE SPACE. 
 01  COMM   PIC S9(5)V99 COMP-3. 
     EXEC SQL END DECLARE SECTION END-EXEC. 
     ... 
 PROCEDURE DIVISION. 
     ... 
     EXEC SQL SELECT ENAME, COMM 
         INTO :ENAME, :COMM FROM EMP 
         WHERE EMPNO = :EMPNO 
     END-EXEC.  
4.3.2.1 ホスト変数としてのグループ項目

Pro*COBOLでは、埋込みSQL文内でグループ項目を使用できます。基本項目(1つのレベルで構成)を持つグループ項目は、ホスト変数として使用できます。ホスト・グループ項目(ホスト構造体)は、SELECT文またはFETCH文のINTO句、およびINSERT文のVALUESリストで参照できます。グループ項目をホスト変数として使用する場合は、SQL文ではグループ名のみ使用します。次に例を示します。

 01  DEPARTURE.
     05 HOUR    PIC X(2).
     05 MINUTE  PIC X(2).

このように宣言した場合、次の文は有効です。

     EXEC SQL SELECT DHOUR, DMINUTE
         INTO :DEPARTURE
         FROM SCHEDULE
         WHERE ...

メンバーがグループ項目で宣言される順序は、SQL文中の対応する列の順序と一致する必要があります。また、INSERT文で列のリストが省略されている場合は、データベース表の列の順序と一致する必要があります。グループ項目をホスト変数として使用する場合、グループ項目を基本項目に置換する構文を使用します。先の例では、:DEPARTUREを:DEPARTURE.HOUR, :DEPARTURE.MINUTEに置換します。

ホスト変数として使用するグループ項目には、ホスト表を含めることができます。次の例では、表を含んだグループ項目を使用して、SCHEDULE表に3つのエントリをINSERTしています。

 01  DEPARTURE.
     05  HOUR    PIC X(2) OCCURS 3 TIMES.
     05  MINUTE  PIC X(2) OCCURS 3 TIMES.
 ...
     EXEC SQL INSERT INTO SCHEDULE (DHOUR, DMINUTE) 
          VALUES (:DEPARTURE) END-EXEC.

VARCHAR=YESと指定した場合、Pro*COBOLでは暗黙的なVARCHARが認識されます。ネストされたグループ項目定義がVARCHARホスト変数と類似している場合、そのグループ項目全体がVARYING型の1つの基本項目のように扱われます。VARCHARを参照してください。

グループ項目ではなく基本項目をホスト変数として参照する場合、基本項目名は次の構文で修飾できるため、一意である必要はありません。

group_item.elementary_item

このネーミング変換はSQL文中でのみ行うことができます。COBOLのIN (またはOF)句に類似しています。次に例を示します。

          MOVE MINUTE IN DEPARTURE TO MINUTE-OUT.
          DISPLAY HOUR OF DEPARTURE.

COBOLのIN (またはOF)句は、SQL文では使用できません。混乱しないように、基本項目名を修飾してください。次に例を示します。

     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 
 01  DEPARTURE. 
     05  HOUR    PIC X(2). 
     05  MINUTE  PIC X(2). 
 01  ARRIVAL. 
     05  HOUR    PIC X(2). 
     05  MINUTE  PIC X(2). 
     EXEC SQL END DECLARE SECTION END-EXEC. 
  ...
     EXEC SQL SELECT DHR, DMIN INTO :DEPARTURE.HOUR, :DEPARTURE.MINUTE
         FROM TIMETABLE
         WHERE ...
4.3.2.2 制限事項

ホスト変数は、列、表またはSQL文中の他のオブジェクトでは置換できません。また、Oracle予約語も使用できません。予約語およびキーワードのリストは、「予約語、キーワードおよびネームスペース」を参照してください。

4.4 標識変数

任意のホスト変数に任意指定の標識変数を関連付けることができます。標識変数に関連付けたホスト変数をSQL文内で使用するたびに、結果コードが対応する標識変数内に格納されます。つまり、標識変数によってホスト変数を監視できます。

VALUES句またはSET句中の標識変数を使用して、入力ホスト変数にNULL値を割り当てたり、INTO句中の標識変数を使用して、出力ホスト変数内のNULL値(または文字列の切り捨てられた値)を検出できます。

4.4.1 標識変数の使用方法

標識変数に割り当てることのできる変数は、次のとおりです。

4.4.1.1 入力時

プログラムが標識変数に割り当てる値の意味は、次のとおりです。

標識変数 説明

-1

Oracleによって、その列にNULLが割り当てられます。このホスト変数の値は無視されます。

>=0

Oracleは、このホスト変数の値を列に割り当てます。

4.4.1.2 出力時

Oracleが標識変数に割り当てる値の意味は、次のとおりです。

標識変数 説明

-1

この列の値はNULLです。したがって、このホスト変数の値は予測不能です。

0

列の値がそのままこのホスト変数に割り当てられました。

>0

切り捨てられた列の値がこのホスト変数に割り当てられました。標識変数によって返される整数は、列値の元の長さです。SQLCAのSQLCODEが0(ゼロ)に設定されます。

-2

Oracleによって切り捨てられた列値がこのホスト変数に割り当てられました。ただし、元の列値は決定できませんでした(LONG列など)。

4.4.2 標識変数の宣言

標識変数はPIC S9(4) COMPとして明示的に宣言する必要があります。また、予約語は使用できません。次の例では、COMM-IND(名前は任意)という標識変数を宣言しています。

 WORKING-STORAGE SECTION.
 ...
 01  EMP-NAME    PIC X(10) VALUE SPACE.
 01  SALARY      PIC S9(5)V99 COMP-3. 
 01  COMMISSION  PIC S9(5)V99 COMP-3. 
 01  COMM-IND    PIC S9(4) COMP. 
 ... 

4.4.3 標識変数の参照

SQL文では、標識変数は前にコロンを付け、対応するホスト変数の直後に記述する必要があります。COBOL文では、標識変数の前にコロンを付けたり、対応するホスト変数の直後に標識変数を記述しないでください。次に例を示します。

     EXEC SQL SELECT SAL, COMM 
        INTO :SALARY, :COMMISSION:COMM-IND FROM EMP 
        WHERE EMPNO = :EMP-NUMBER 
     END-EXEC. 
     IF COMM-IND = -1 
        COMPUTE PAY = SALARY 
     ELSE 
        COMPUTE PAY = SALARY + COMMISSION. 
 

判読しやすくするため、それぞれの標識変数の前にINDICATORのオプションのキーワードを置くこともできます。その場合も、インディケータ変数の前にはコロンを付ける必要があります。正しい構文は次のとおりです。

:host_variableINDICATOR:indicator_variable

これは、次の構文と同じです。

:host_variable:indicator_variable

ホスト・プログラムでは、両方の形式の式を使用できます。

4.4.3.1 WHERE句での使用

WHERE句では、標識変数によるNULLの検索はできません。たとえば、次のDELETE文を実行するとエラーが発生します。

*    Set indicator variable. 
     COMM-IND = -1 
     EXEC SQL 
         DELETE FROM EMP WHERE COMM = :COMMISSION:COMM-IND 
     END-EXEC. 

正しい構文は次のとおりです。

     EXEC SQL 
         DELETE FROM EMP WHERE COMM IS NULL 
     END-EXEC. 
4.4.3.2 エラー・メッセージの回避

インジケータを持たないホスト変数にNULLをSELECTまたはFETCHすると、Oracleはエラー・メッセージを出力します。

コマンドラインにUNSAFE_NULL=YESも指定すると、エラー・メッセージは出力されません。

4.4.3.3 ANSI要件

MODE=ORACLEの場合、切り捨てられた列値をSELECTまたはFETCHして標識変数に関連付けられていないホスト変数に格納すると、Oracleはエラー・メッセージを出力します。

ただし、MODE={ANSI | ANSI14 | ANSI13}の場合にはエラーは発生しません。

関連項目:

標識変数の値は、埋込みSQLを参照してください。
4.4.3.4 マルチバイトNCHAR変数の標識変数

マルチバイトNCHAR文字変数の標識変数は、他のホスト変数の場合と同様に使用できます。ただし、正の値(SELECTまたはFETCHの結果が切り捨てられた結果)は、1バイト文字ではなくマルチバイト・キャラクタ単位の文字列の長さを表します。

4.4.3.5 ホスト・グループ項目の標識変数

標識変数をホスト・グループ項目に使用するには、グループ項目の各NULL値可能な変数に対する標識変数を含むグループ項目を別に設定するか、ハーフ・ワード整変数の表を使用します。グループ項目の各変数に標識変数を設定する必要はありませんが、インジケータを使用したいNULL値可能フィールドは、データ・グループ項目の先頭に配置する必要があります。次のインジケータグループ項目は、DEPARTUREグループ項目に使用できます。

 01  DEPARTURE-IND.
     05  HOUR-IND   PIC S9(4) COMP.
     05  MINUTE-IND PIC S9(4) COMP.

インジケータ表を使用する場合、ホスト・グループ項目内のメンバー数と同じ数の要素を持つ表を宣言する必要はありません。次のインジケータ表は、DEPARTUREグループ項目に使用できます。

 01 DEPARTURE-IND PIC S9(4) COMP OCCURS 2 TIMES.

SQL文でインジケータ・グループ項目を参照する方法は、ホスト標識変数を参照する方法と同じです。

     EXEC SQL SELECT DHOUR, DMINUTE
        INTO :DEPARTURE:DEPARTURE-IND
          FROM SCHEDULE
            WHERE ...

問合せが完了すると、選択された各コンポーネントがNULL状態かNOT NULL状態かの情報がホスト・インジケータ・グループ項目に設定されます。インジケータ・ホスト変数に関する制限事項およびANSI必要条件は、ホスト・インジケータ・グループ項目にも適用されます。

4.5 VARCHAR変数

COBOL文字列データ型は固定長です。ただし、Pro*COBOLではVARCHARと呼ばれる可変長文字列擬似型を宣言できます。VARCHAR変数は、データベースに格納するデータおよびデータベースに渡すデータの長さを正確に指定できる擬似型です。

4.5.1 VARCHAR変数の宣言

VARCHARホスト変数は、次の例に示すように、キーワードVARYINGを宣言に追加することによって定義します。

 01  ENAME  PIC X(15) VARYING. 

注意:

PIC NおよびPIC Gは、VARYINGを使用した定義では使用できません。VARCHAR変数でのPIC NおよびPIC Gの正しい使用方法は、「暗黙的なVARCHARグループ項目」を参照してください。

注意:

Pro*COBOLは、VARYINGで宣言される変数名に4文字追加します。したがって、COBOLコンパイラが長さがnの変数名をサポートする場合、Pro*COBOLはそれより4文字少ない変数名(n-4)をサポートします。

COBOLのVARYING句は、添字および索引を増分するために、PERFORM文およびSEARCH文で使用するものです。前述の例のPro*COBOLのVARYING句と混同しないでください。

VARCHARは、Pro*COBOLの拡張データ型または宣言済グループ項目と考えられます。たとえば、Pro*COBOLでは、VARCHAR宣言を展開して

 01  ENAME  PIC X(15) VARYING. 

次のような長さフィールドおよび文字列フィールドを持つグループ項目にします。

 01  ENAME. 
     05  ENAME-LEN  PIC S9(4) COMP.
     05  ENAME-ARR  PIC X(15). 

長さフィールド(接尾辞-LEN)には、文字列フィールド(接尾辞-ARR)に格納されている値の現在の長さが含まれます。VARCHARホスト変数宣言での最大長は1から9,999バイトの範囲内であることが必要です。

VARCHAR変数の利点は、長さフィールドを明示的に設定および参照できることです。Pro*COBOLは、入力ホスト変数を使用して長さフィールドの値を読み取り、そこに指定された数だけ、文字列フィールドの文字を使用します。出力ホスト変数では、Pro*COBOLは、長さの値を文字列フィールドに格納された文字列の長さに設定します。

4.5.2 暗黙的なVARCHARグループ項目

Pro*COBOLは、プリコンパイラ・オプションVARCHAR=YESがコマンドラインで指定された場合、一部のグループ項目を暗黙的にVARCHARホスト変数として認識します。可変長シングルバイト・キャラクタ・タイプの場合は、次の構造を使用してください(長さはシングルバイト文字で表します)。

  nn   data-name-1.
       49  data-name-2 PIC S9(4) COMP.
       49  data-name-3 PIC X(length).

nnには01から48を指定する必要があります。

可変長マルチバイトNCHAR文字列の場合は、次の書式を使用します(長さはダブルバイト文字で表します)。

 nn  DATA-NAME-1.
     49 DATA-NAME-2  PIC  S9(4)  COMP.
     49 DATA-NAME-3  PIC  N(length).

 nn  DATA-NAME-1.
     49 DATA-NAME-2  PIC  S9(4)  COMP.
     49 DATA-NAME-3  PIC  G(length).

The elementary items in these group-item structures must be declared as level 49 for Pro*COBOL to recognize them as VARCHAR host variables.

Pro*COBOLにVARCHARグループ項目の拡張書式を認識させるには、VARCHARオプションをコマンドラインでVARCHAR=YESと指定する必要があります。VARCHAR=NOと指定した場合は、前述の書式と似た宣言はどれも通常のグループ項目として解釈されます。VARCHAR=YESと指定しても、グループ項目定義の書式が拡張VARCHAR書式と類似しているが同じではない場合には、その項目はVARCHARグループ項目ではなく通常のグループ項目と解釈されます。たとえば、VARCHAR=YESと指定して、次のように記述したとします。

  01  LASTNAME.
      48 LASTNAME-LEN  PIC S9(4) COMP.
      48 LASTNAME-TEXT PIC X(15).

このグループ項目の要素にはレベル49ではなくレベル48が使用されているため、この項目はVARCHARグループ項目ではなく通常のグループ項目と解釈されます。

関連項目:

Pro*COBOL VARCHARオプションの詳細は、プリコンパイラのオプションを参照してください。

4.5.3 VARCHAR変数の参照

SQL文でVARCHAR変数を参照する場合は、次の例のように、グループ名の前にコロンを付けたものを使用します。

 WORKING-STORAGE SECTION. 
     ... 
     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 
         ... 
 01  PART-NUMBER  PIC X(5). 
 01  PART-DESC    PIC X(20) VARYING. 
     EXEC SQL END DECLARE SECTION END-EXEC. 
     ... 
 PROCEDURE DIVISION. 
     ... 

     EXEC SQL
         SELECT PDESC INTO :PART-DESC FROM PARTS
         WHERE PNUM = :PART-NUMBER 
     END-EXEC. 

問合せの実行後、データベースから取り出され、PART-DESC-ARRに格納された文字列の実際の長さが、PART-DESC-LENに格納されます。

4.6 文字データの処理

この項では、Pro*COBOLが文字ホスト変数をどのように処理するかを説明します。文字ホスト変数には、シングルバイト文字ホスト変数およびマルチバイト・グローバリゼーション・サポート(旧称「NLS」)文字ホスト変数がそれぞれ2種類あります。

  • PIC X(n)(またはPIC X...X)

  • PIC X(n) VARYING (またはPIC X...X VARYING)

  • PIC N(n)(またはPIC N...N)またはPIC G(n)(またはPIC G...G) 

注意:

マルチバイトNCHARデータ型を使用する前に、使用しているCOBOLコンパイラがPIC Nデータ型またはPIC Gデータ型に対応していることを確認してください。

4.6.1 PIC Xのデフォルト

PIC Xのデフォルトのデータ型はCHARFです(リリース8.0より前はVARCHAR2でした)。下位互換性を保つために、プリコンパイラ・コマンドライン・オプションPICXが用意されています。PICXはコマンドラインまたは構成ファイルにのみ入力できます。詳細は、「PICX」を参照してください。

4.6.2 PICXオプションの効果

PICXオプションによって、文字列内のデータをPro*COBOLがどのように扱うかが決定されます。PICXオプションを使用すると、プログラムでANSI固定長文字列を使用したり、データベース・サーバーおよびPro*COBOLの旧バージョンとの互換性を維持できます。

リリース8.0より前のPro*COBOLと同じ結果を取得するには、PICX=VARCHAR2 (デフォルトではありません)を使用する必要があります。あるいは、次の文を使用します。

     EXEC SQL varname IS VARCHAR2 END-EXEC.

この文は、変数ごとに使用します。

4.6.3 固定長文字変数

固定長文字変数は、PIC X(n)、PIC G(n)およびPIC N(n)データ型を使用して宣言します。これらの変数の型では、文字データはそのロールに基づいて、入力変数または出力変数として扱われます。

4.6.3.1 入力時

PICX=VARCHAR2の場合、プログラム・インタフェースは値をデータベースに送る前に、後続の空白を削除します。固定長CHAR列に挿入した場合、Pro*COBOLはそのデータベース列の長さに達するまで、後続の空白を再度追加します。これに対し、可変長VARCHAR2列に挿入した場合は、Pro*COBOLは空白を追加されません。

PICX=CHARFの場合は、後続の空白は削除されません。

マルチバイト・グローバリゼーション・サポート・データのホスト入力変数の場合、後続のダブルバイトの空白は削除されません。lengthコンポーネントは、バイト単位ではなく文字単位のデータの長さとみなされます。

入力値に余分な文字が後続していないことを確認してください。値がPIC X(n)変数にACCEPTまたはMOVEされると、COBOLによってその変数の長さまで空白が追加されるため、これは通常は問題になりません。

この点について、次の例で示します。

 WORKING-STORAGE SECTION.
     ...
     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 
 01  EMPLOYEES. 
     05  EMP-NAME     PIC X(10). 
     05  DEPT-NUMBER  PIC S9(4) VALUE 20 COMP. 
     05  EMP-NUMBER   PIC S9(9) VALUE 9999 COMP. 
     05  JOB-NAME     PIC X(8). 
             ... 
     EXEC SQL END DECLARE SECTION END-EXEC. 
     ... 
 PROCEDURE DIVISION.
     ...
     DISPLAY "Employee name? " WITH NO ADVANCING. 
     ACCEPT EMP-NAME. 
*    Assume that the name MILLER was entered 
*    EMP-NAME contains "MILLER    " (4 trailing blanks) 
     MOVE "SALES" TO JOB-NAME. 
*    JOB-NAME now contains "SALES   " (3 trailing blanks) 
     EXEC SQL INSERT INTO EMP (EMPNO, ENAME, DEPTNO, JOB) 
         VALUES (:EMP-NUMBER, :EMP-NAME, :DEPT-NUMBER, :JOB-NAME
     END-EXEC. 
     ...

最後の例で、PICX=VARCHAR2を指定してプリコンパイルした場合に、ターゲット・データベース列がVARCHAR2であれば、プログラム・インタフェースによって入力時に後続の空白が削除され、6文字の文字列「MILLER」および5文字の文字列「SALES」のみデータベースに挿入されます。これに対し、ターゲット・データベース列がCHARの場合には、列の幅に達するまで文字列に空白が埋め込まれます。

最後の例で、PICX=CHARFを指定してコンパイルした場合に、JOB列がCHAR(10)として定義されていると、JOB列に挿入される値は「SALES#####」(後続の空白は5個)になります。ただし、JOB列がVARCHAR2(10)として定義されている場合、ホスト変数はPIC X(8)として宣言されているため、挿入される値は「SALES###」(後続の空白は3個)になります。このように、期待したとおりの結果にならない場合があるため、注意してください。

4.6.3.2 出力時

PICXオプションは、固定長文字変数に対する出力には影響しません。PIC X(n)変数を出力ホスト変数として使用すると、Pro*COBOLによって空白が埋め込まれます。たとえば、プログラムがデータベースから文字列「MILLER」をフェッチした場合、EMP-NAME内の値は「MILLER####」(後続の空白は4個)になります。この文字列は、そのまま別のSQL文への入力として使用できます。

4.6.4 可変長変数

VARCHAR変数では、文字データはそのロールに基づいて、入力変数または出力変数として扱われます。

4.6.4.1 入力時

VARCHAR変数を入力ホスト変数として使用する場合は、次の例に示すように、拡張VARCHAR宣言の長さフィールドおよび文字列フィールドに値を割り当てる必要があります。

     IF ENAME-IND = -1 
         MOVE "NOT AVAILABLE" TO ENAME-ARR 
         MOVE 13 TO ENAME-LEN. 

文字列変数に空白を埋め込む必要はありません。SQL操作では、Pro*COBOLは空白も含めて、長さフィールドで指定されたとおりの文字数を使用します。

4.6.4.2 出力時

VARCHAR変数を出力ホスト変数として使用すると、Pro*COBOLによって長さフィールドが設定されます。次に例を示します。

 WORKING-STORAGE SECTION. 
     ... 
     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 
 01  EMPNO  PIC S9(4) COMP. 
 01  ENAME  PIC X(15) VARYING. 
         ... 
     EXEC SQL END DECLARE SECTION END-EXEC. 
     ... 
 PROCEDURE DIVISION. 
     ... 
     EXEC SQL
         SELECT ENAME INTO :ENAME FROM EMP 
         WHERE EMPNO = :EMPNO 
     END-EXEC. 
     IF ENAME-LEN = 0 
         MOVE FALSE TO VALID-DATA.  

VARCHAR変数が固定長文字列より優れている点は、Pro*COBOLによって戻された値の長さをそのまま使用できることです。固定長文字列を使用した場合は、値の長さを取得するには文字数をカウントする必要があります。

マルチバイトNCHARデータのホスト出力変数には何も埋め込まれません。バッファの長さは、文字単位ではなくバイト単位の長さに設定されます。

注意:

PICN_ENDIAN=OSの場合、マルチバイトNCHARデータのバッファの長さは、バイト単位ではなく、文字単位の長さに設定されます。

4.7 ユニバーサルROWID

データベース・サーバーでは、ヒープ表索引構成表の2種類の表編成が使用されます。

ヒープ表はデフォルトです。これは、Oracleより前のすべての表で使用される編成です。物理的な行アドレス(ROWID)は、ヒープ表の行を識別するためのパーマネント・プロパティです。物理ROWIDの外部文字書式は、ベース64でエンコーディングした18バイトの文字列です。

索引構成表には、パーマネント識別子としての物理的な行アドレスがありません。そのような表には、論理ROWIDが定義されます。索引構成表からのSELECT ROWID...文を使用するとき、ROWIDは、表の主キー、制御情報、および物理的な推測を含む不透明な構造です。表から値を検索するために、「WHERE ROWID = ...」などの句を含むSQL文でこのROWIDを使用できます。

ユニバーサルROWIDは、Oracle 8.1 Databaseのリリースで導入されました。ユニバーサルROWIDは、物理ROWIDと論理ROWIDの両方で使用できます。表編成の変更はアプリケーションに影響しないため、ユニバーサルROWIDを使用すると、ヒープ表または索引構成表のデータにアクセスできます。ROWIDに使用される列データ型はUROWID(length)で、lengthはオプションです。

新しいアプリケーションでは、ユニバーサルROWIDを使用してください。

疑似型SQL-ROWIDを使用したユニバーサルROWIDの宣言の例を次に示します。

 01  MY-ROWID SQL-ROWID.

ユニバーサルROWIDのメモリーは、ALLOCATE文を使用して割り当てます。

     EXEC SQL ALLOCATE :MY-ROWID END-EXEC.

SQL DML文でMY-ROWIDを次のように使用します。

     EXEC SQL SELECT ROWID INTO :MY-ROWID FROM MYTABLE WHERE ... END-EXEC.
...
     EXEC SQL UPDATE MYTABLE SET ... WHERE ROWID = :MY-ROWID END-EXEC.
...

必要なくなった場合には、FREEディレクティブを使用してメモリーを解放します。

     EXEC SQL FREE :MY-ROWID END-EXEC.

また、18から4000の幅を持つ文字ホスト変数を、ユニバーサルROWIDのホスト・バインド変数として使用することもできます。文字ベースのユニバーサルROWIDはヒープ表でもサポートされていますが、下位互換性しかありません。ユニバーサルROWIDは可変長であるため、選択時に切り捨てられる場合があります。

文字変数の使用例を次に示します。

 01  MY-ROWID-CHAR PIC X(4000) VARYING.
... 
     EXEC SQL ALLOCATE :MY-ROWID-CHAR END-EXEC.
     EXEC SQL SELECT ROWID INTO :MY-ROWID-CHAR FROM MYTABLE WHERE ... END-EXEC.
...
     EXEC SQL UPDATE MYTABLE SET ... WHERE ROWID = :MY-ROWID-CHAR END-EXEC.
...
     EXEC SQL FREE :MY-ROWID-CHAR END-EXEC.

関連項目:

  • ユニバーサルROWIDの詳細は、Oracle Database概要を参照してください。

  • ユニバーサルROWIDを使用した位置付け更新の例は、位置付け更新を参照してください。

4.7.1 サブプログラムSQLROWIDGET

OracleサブプログラムSQLROWIDGETを使用して、最後に挿入、更新または選択した行のROWIDを取得できます。SQLROWIDGETにはコンテキストまたはNULLおよびROWIDが引数として必要です。

デフォルトのコンテキストを使用するには、SQLROWIDGETへのコールの最初のパラメータとして表意定数NULLを渡します。

ユニバーサルROWIDは、コールに宣言および割当てを行う必要があります。コンテキストを使用する場合、コール前に宣言および割当てを行う必要があります。構文は次のとおりです。

     CALL "SQLROWIDGET" USING NULL rowid. 

または

     CALL "SQLROWIDGET" USING context rowid. 

説明:

context (IN)

擬似型SQL-CONTEXTのランタイム・コンテキスト変数またはデフォルト・コンテキストの場合は表意定数NULL。ランタイム・コンテキストの詳細は、「ランタイム・コンテキストの埋込みSQL文およびディレクティブ」を参照してください。

rowid (OUT)

疑似型SQL-ROWIDのユニバーサルROWID変数。コールの実行が正常に終了すると、この変数は有効なユニバーサルROWIDを指します。エラーが発生した場合は、rowidは定義されません。

次にデフォルト・コンテキストを使用した例を示します。

 01  MY-ROWID SQL-ROWID.  
 ...
     EXEC SQL ALLOCATE :MY-ROWID END-EXEC. 

* INSERT, or UPDATE or DELETE Goes here: 
 ...
     CALL "SQLROWIDGET" USING NULL MY-ROWID. 
* MY-ROWID now has the universal rowid descriptor for the last row
 ...
     EXEC SQL FREE :MY-ROWID END-EXEC. 
 ... 

使用するコンパイラでCALL文に表意定数NULLを使用できない場合は、次のように、実際のS9(9) COMP VALUE 0を使用して変数を宣言し、SQLROWIDGETへのコールにその変数とBY VALUE句を指定してください。

 01 NULL-CONTEXT  PIC S9(9) COMP VALUE ZERO.
 01 MY-ROWID SQLROWID.
....
        CALL "SQLROWIDGET" USING BY VALUE NULL-CONTEXT BY REFERENCE MY-ROWID.

4.8 グローバリゼーション・サポート

広く使用されている7ビットまたは8ビットのASCIIキャラクタ・セットおよびEBCDICキャラクタ・セットが英数字を表すのに十分であっても、日本語などのアジアの言語の中には、数千という文字があるものもあります。このような言語では、個々の文字を表すのに16ビット以上必要です。Oracleは、これらの異なる言語をどのように扱っているでしょうか。

Oracleには、シングルバイトおよびマルチバイト・キャラクタ・データを処理し、キャラクタ・セット間で変換できるように、グローバリゼーション・サポート(旧称National Language SupportまたはNLS)が用意されています。また、アプリケーションを異なる言語環境で実行することもできます。グローバリゼーション・サポートでは、数値書式および日付書式はユーザー・セッション用に指定された言語規則に自動的に適応します。したがって、グローバリゼーション・サポートにより、世界中のユーザーがそれぞれの母国語でOracleと対話できます。

様々なグローバリゼーション・サポート・パラメータを指定して、言語によって異なる機能の操作を制御できます。デフォルト・パラメータ値は初期化ファイルで設定できます。表4-8に、各グローバリゼーション・サポート・パラメータの指定内容を示します。

表4-8 グローバリゼーション・サポート・パラメータ

グローバリゼーション・サポート・パラメータ 指定内容

NLS_LANGUAGE

言語によって異なる表記規則

NLS_TERRITORY

地域によって異なる表記規則

NLS_DATE_FORMAT

日付書式

NLS_DATE_LANGUAGE

日および月の名前に使用する言語

NLS_NUMERIC_CHARACTERS

10進数文字およびグループ・セパレータ

NLS_CURRENCY

各国通貨記号

NLS_ISO_CURRENCY

ISO通貨記号

NLS_SORT

ソート基準

主なパラメータは、NLS_LANGUAGEおよびNLS_TERRITORYです。NLS_LANGUAGEでは、言語によって異なる次の機能のデフォルト値を指定します。

  • サーバー・メッセージに使用する言語

  • 日および月の名前に使用する言語

  • ソート基準

NLS_TERRITORYには、地域によって異なる機能のデフォルト値を指定します。この機能には次が含まれます。

  • 日付書式

  • 小数点文字

  • グループ・セパレータ

  • 各国通貨記号

  • ISO通貨記号

パラメータNLS_LANGを次のように指定して、ユーザー・セッション用に言語ごとに異なるグローバリゼーション・サポート機能の操作を制御できます。

NLS_LANG = language_territory.character set 

languageはユーザー・セッション用のNLS_LANGUAGEの値、territoryはNLS_TERRITORYの値、character setは端末に使用されるコード体系を指します。コード体系(通常はキャラクタ・セットまたはコード・ページと呼ばれる)は、端末で表示できるキャラクタ・セットに対応する数値コードの範囲です。また、これには端末との通信を制御するコードも入っています。

NLS_LANGは、環境変数(または使用しているシステムでこれに相当するもの)として定義します。たとえば、Cシェルを使用するUNIXでは、NLS_LANGを次のように定義できます。

setenv NLS_LANG French_France.WE8ISO8859P1
 

セッション中にグローバリゼーション・サポート・パラメータの値を変更する場合は、次のようなALTER SESSION文を使用します。

ALTER SESSION SET nls_parameter = value 

Pro*COBOLは、Oracle Databaseに格納されている多言語のデータをアプリケーションで処理するためのグローバリゼーション・サポート機能をすべてサポートしています。たとえば、外国語の文字変数を宣言し、それをINSTRB、LENGTHB、SUBSTRBなどの文字列関数に渡すことができます。これらの関数には、それぞれINSTR、LENGTHおよびSUBSTR関数と共通の構文がありますが、文字単位ではなく、バイト単位の操作になります。

関数NLS_INITCAP、NLS_LOWERおよびNLS_UPPERを使用して、大/小文字変換の特別なインスタンスを扱うことができます。さらに、関数NLSSORTを使用して、バイナリ順序ではなく言語上の順序でWHERE句の比較を指定できます。グローバリゼーション・サポート・パラメータをTO_CHAR、TO_DATEおよびTO_NUMBER関数に渡すこともできます。

関連項目:

グローバリゼーション・サポートの詳細は、Oracle Databaseグローバリゼーション・サポート・ガイドを参照してください。

4.9 Pro*COBOLのUnicodeサポート

Pro*COBOLでは、Unicodeで記述されたソース・コードをサポートしていません。ロケールにUTF8を設定する場合は、ASCIIコードのみを使用してソース・コードを記述する必要があります。

Unicode変数を使用する場合は、次の点に注意してください。

  • Pro*COBOLでは、「USAGE NATIONAL」をサポートしていません。Unicode変数を使用する場合は、COBOLプログラムをMF Cobolでコンパイルするために-C NSYMBOL="NATIONAL"を指定します。

  • Unicodeは、PIC XおよびPIC Nで使用できます。

    • AL32UTF8およびUTF8は、PIC Xで使用できます。

    • AL16UTF16は、PIC Nで使用できます。

  • NLS_NCHAR環境変数は、PIC Nで使用するクライアント側キャラクタ・セットと等価にします。NLS_NCHARが設定されていない場合は、NLS_LANGが使用されます。

  • NLS_LANG環境変数は、PIC Xで使用するクライアント側キャラクタ・セットと等価にします。

  • AL16UTF16、JA16SJISFIXEDおよびJA16EUCFIXEDは、NLS_NCHARで設定できます。

  • JA16SJISおよびJA16SJISTILDEも、NLS_NCHARで設定できます。

  • JA16EUCおよびJA16EUCTILDEは、NLS_NCHARで使用できません。

関連項目:

NLS_LANGで使用可能なキャラクタ・セットの詳細は、グローバリゼーション・サポート・ガイドを参照してください。

PICX=charf/varchar2はUnicode PIC X変数に対して機能し、PIC Nに対しては前述のリストに示した制限に従って機能します。

4.9.1 NLS_LOCAL=YESの制限事項

プリコンパイラ・オプションNLS_LOCALをYESと指定した場合、グローバリゼーション・サポート・マルチバイト・データ型の空白埋込みおよび空白削除はランタイム・ライブラリ(SQLLIB)によって実行されます。

NLS_LOCAL=YESの場合、PL/SQLブロック内では、マルチバイトNCHAR機能はサポートされません。これらの機能は、N付き引用符で表された文字リテラルおよび固定長の文字変数を組み込みます。

そのため、次の制限が適用されます。

表は使用できません。 PIC NまたはPIC Gデータ型を使用して宣言するホスト変数として、配列を使用できません。

奇数バイト幅はありません。 マルチバイトのNCHAR文字の格納に、Oracle CHAR列を使用しないでください。奇数バイトのデータがシングルバイト列からマルチバイトのNCHARホスト変数にFETCHされると、ランタイム・エラーが発生します。

ホスト変数の同値化は行えません。 EXEC SQL VAR文を使用してマルチバイトNCHAR文字変数を同値化できません。

動的SQLは使用できません。 Pro*COBOLでは、NCHARマルチバイト・キャラクタ文字列ホスト変数に動的SQLを使用できません。

マルチバイト・グローバリゼーション・サポートのデータが格納されている列に対しては、関数を使用しないでください。

4.9.2 埋込みSQL内の文字列

埋込みSQL文内のマルチバイト・グローバリゼーション・サポート文字列は、文字Nと、その後に続く引用符(')で囲まれた文字列で構成されます。

次に例を示します。

     EXEC SQL 
         SELECT EMPNO INTO :EMP-NUM FROM EMP
         WHERE ENAME=N'NLS_string'
     END-EXEC.

4.9.3 埋込みDDL

プリコンパイラ・オプションがNLS_LOCAL=YESと設定されている場合、NCHARデータを格納する列は埋込みデータ定義言語(DDL)文では使用できません。この制限はプリコンパイル時には適用されないため、NCHARなどの拡張された列型を埋込みDDL文で使用すると、プリコンパイル・エラーではなく実行エラーになります。

4.9.4 空白埋込み

Pro*COBOL文字変数をマルチバイト・グローバリゼーション・サポート変数として定義すると、その変数の外部データ型に応じて、次の空白埋込みおよび空白削除の規則が適用されます。

CHARF。入力データから、後続のダブルバイトの空白文字が削除されます。ただし、文字列がマルチバイト空白文字のみで構成されている場合は、標識としてマルチバイトの空白文字が1つバッファに残されます。

出力ホスト変数には、マルチバイトの空白が埋め込まれます。

VARCHAR。 入力時に、ホスト変数からは後続のダブルバイト空白文字が削除されません。lengthコンポーネントは、バイト単位ではなく文字単位のデータの長さとみなされます。

出力では、ホスト変数には空白は埋め込まれません。バッファの長さは、バイト単位ではなく文字単位のデータの長さに設定されます。

STRING/LONG VARCHAR。 これらのホスト変数を指定するには動的SQLまたはデータ型の同値化を使用する必要がありますが、グローバリゼーション・サポート・データはそのどちらにも対応していないためです。

4.9.5 標識変数

マルチバイトのグローバリゼーション・サポート文字変数でも、他の変数の場合と同様に、インディケータ変数を使用できますが、列の長さの値はバイト単位ではなく文字単位で表されます。

4.9.6 PIC X/PIC N変数とNCHAR/CHAR列の様々な組合せ

Pro*COBOLでは、コマンドライン・オプションcharset_picxおよびcharset_picnによるSELECT、INSERTおよびUPDATE文でのPIC X /PIC N変数とNCHAR/CHAR列の様々な組合せがサポートされています。

4.9.6.1 PIC XとNCHAR列

デフォルトでは、PIC X変数は、CHAR列で使用できるようにサーバー側のデータベース・キャラクタ・セットに変換されます。したがって、NCHAR列でPIC X変数を使用すると、一部のデータが失われる可能性があります。これを回避するには、次のコマンドを使用して、PIC X変数で使用するキャラクタ・セットの形式をNCHARに設定します。

charset_picx=nchar_charset
4.9.6.2 PIC NとCHAR列

デフォルトでは、PIC N変数は、CHAR列で使用できるようにサーバー側の各国語キャラクタ・セットに変換されます。したがって、NCHAR列でPIC N変数を使用すると、パフォーマンスに影響を及ぼす可能性があります。これを回避するには、次のコマンドを使用して、PIC N変数で使用するキャラクタ・セットの形式をCHARに設定します。

charset_picn=db_charset

関連項目:

CHARSET_PICXおよびCHARSET_PICNの詳細は、Pro*COBOLプリコンパイラ・オプションの使用を参照してください。

4.9.7 新しいオプションの使用方法

次の表に、新しいオプションの使用方法を示します。

  • ホスト変数: ホスト変数のタイプ

  • DBの列のタイプ: CHAR/NCHAR

  • charset_picx: charset_picxオプションの値

  • charset_picn: charset_picnオプションの値

  • NLS_NCHAR: NLS_NCHARの値

  • データのキャラクタ・セット: ホスト変数のキャラクタ・セット

ホスト変数 DBの列のタイプ charset_picx charset_picN NLS_NCHAR データのキャラクタ・セット

PIC X

CHAR

nchar_charset

-

設定

NLS_NCHAR

PIC X

CHAR

db_charset

-

設定

NLS_LANG

PIC X

CHAR

nchar_charset

-

未設定

NLS_LANG

PIC X

CHAR

db_charset

-

未設定

NLS_LANG

PIC X

NCHAR

nchar_charset

-

設定

NLS_NCHAR

PIC X

NCHAR

db_charset

-

設定

NLS_LANG

PIC X

NCHAR

nchar_charset

-

未設定

NLS_LANG

PIC X

NCHAR

db_charset

-

未設定

NLS_LANG

PIC N

CHAR

-

nchar_charset

設定

NLS_NCHAR

PIC N

CHAR

-

db_charset

設定

NLS_NCHAR

PIC N

NCHAR

-

nchar_charset

未設定

NLS_LANG

PIC N

NCHAR

-

db_charset

未設定

NLS_LANG

PIC N

NCHAR

-

nchar_charset

設定

NLS_NCHAR

PIC N

NCHAR

-

db_charset

設定

NLS_NCHAR

PIC N

NCHAR

-

nchar_charset

未設定

NLS_LANG

PIC N

NCHAR

-

db_charset

未設定

NLS_LANG

4.10 データ型変換

プリコンパイル時に、各ホスト変数に外部データ型が割り当てられます。たとえば、Pro*COBOLはPIC S9(n) COMP型のホスト変数にINTEGER外部データ型を割り当てます。SQL文で使用するすべてのホスト変数のデータ型コードは、実行時にOracleに渡されます。Oracleは、コードを使用して内部データ型と外部データ型の間で変換します。

Oracleは、SELECTした列値を出力ホスト変数に割り当てる前に、必ずソース列の内部データ型をホスト変数のデータ型に変換します。同様に、入力ホスト変数の値の、列への割当てまたは比較を行う場合は、その前に必ずホスト変数の外部データ型をターゲット列の内部データ型に変換します。

内部データ型と外部データ型との変換は、通常のデータ変換規則に従って行われます。たとえば、CHAR値1234はPIC S9(4) COMP値に変換できます。ただし、CHAR値123465543 (大きすぎる数)や10F (10進数ではない数)をPIC S9(4) COMP値に変換することはできません。同様に、アルファベット文字を含むPIC X(n)値はNUMBER値に変換できません。

ホスト変数のデータ型は、データベース列のデータ型と互換性が必要です。必ず、変換可能な値を指定してください。たとえば、文字列値YESTERDAY をDATE列値に変換しようとすると、エラーが発生します。内部データ型と外部データ型との変換は、通常のデータ変換規則に従って行われます。たとえば、CHAR値1234を2バイトの整数に変換できます。しかし、CHAR値65543(大きすぎる数)や10F(10進数ではない数)を2バイトの整数に変換することはできません。同様に、アルファベット文字を含む文字列値はNUMBER値に変換できません。

数値の変換は、Oracle初期化ファイルのグローバリゼーション・サポート・パラメータで指定された規則に従って行われます。たとえば、ピリオド(.)ではなくカンマ(,)を小数点として認識するようにシステムが構成されている場合があります。

次の表は、サポートされている内部データ型と外部データ型の間での変換を示します。

表4-9 内部データ型と外部データ型の間での変換

外部 内部 - - - - - - -

CHAR

I/O

I/O (2)

I/O

I(3)

I/O

I/O (3)

I/O (1)

CHARF

I/O

I/O (2)

I/O

I (3)

I/O

I/O (3)

I/O (1)

CHARZ

I/O

I/O (2)

I/O

I (3)

I/O

I/O (3)

I/O (1)

DATE

I/O

I/O

I

-

-

-

--

DECIMAL

I/O (4)

-

I

-

-

I/O

-

-

DISPLAY

I/O (4))

-

I

-

-

I/O

-

-

FLOAT

I/O (4)

-

I

-

-

I/O

-

-

INTEGER

I/O (4)

-

I

-

-

I/O

-

-

LONG

I/O

I/O (2)

I/O

I (3.5)

-

I/O

I/O (3)

I/O (1)

LONG RAW

O(6)

-

I (5,6)

I/O

-

-

I/O

-

LONG VARCHAR

I/O

I/O(2)

I/O

I (3,5)

-

I/O

I/O(3))

I/O (1)

LONG VARRAW

I/O (6)

-

I (5,6)

I/O

-

-

I/O

-

NUMBER

I/O (4)

-

I

-

-

I/O

-

-

RAW

I/O (6)

-

I (5,6)

I/O

-

-

I/O

-

ROWID

I

-

I

-

-

-

-

I/O

STRING

I/O

I/O (2)

I/O

I (3.5)

-

I/O

I/O (3)

I/O (1)

UNSIGNED

I/O (4)

-

I

-

-

I/O

-

-

VARCHAR

I/O

I/O (2)

I/O

I (3,5)

-

I/O

I/O (3)

-

VARCHAR2

I/O

I/O (2)

I/O

I (3)

-

I/O

I/O (3)

I/O (1)

VARNUM

I/O (4)

-

I

-

-

I/O

-

-

VARRAW

I/O (6)

-

I (5,6)

I/O

-

-

I/O

-

前述の表の意味は次のとおりです。

  • I = 入力のみ

  • O = 出力のみ

  • I/O = 入出力

注意:

入力時には、ホスト文字列をOracle'BBBBBBBB.RRRR.FFFF'の形式にする必要があります。

出力時には、列値は同じ形式で戻されます。

入力時には、ホスト文字列をデフォルトのDATE文字形式にする必要があります。

出力時には、列値は同じ形式で戻されます。

入力時には、ホスト文字列を16進フォーマットにする必要があります。

出力時には、列値は同じ形式で戻されます。

出力時には、列値は有効な数値を表している必要があります。

入力時には、長さが2000以下であることが必要です。

関連項目:

グローバリゼーション・サポートの詳細は、Oracle Databaseグローバリゼーション・サポート・ガイドを参照してください。

4.11 DATE文字列フォーマットの明示的な制御

Oracleでは、DATE列値を選択して文字ホスト変数に格納する場合、内部バイナリ値を外部文字値に変換する必要があります。このため、デフォルトの日付書式で文字列を戻すSQL関数TO_CHARが暗黙的にコールされます。デフォルトの日付書式は、Oracleの初期化パラメータNLS_DATE_FORMATで設定します。時刻やユリウス暦の日付などのその他の情報を取得するには、書式マスクを指定して明示的にTO_CHARをコールする必要があります。

文字ホスト値をDATE列に挿入する際にも変換が必要です。Oracleは、デフォルトの日付書式を予期するSQL関数TO_DATEを暗黙的にコールします。その他の書式の日付を挿入する場合は、書式マスクを指定して明示的にTO_DATEをコールする必要があります。

Pro*COBOLには、他のバージョンのSQLとの互換性を保証するために、次のような日付文字列を指定するためのプリコンパイラ・オプションが用意されています。

DATE_FORMAT={ISO | USA | EUR | JIS | LOCAL | 'fmt'

DATE_FORMATオプションは、コマンドラインまたは構成ファイル内で指定する必要があります。指定できる日付文字列を次の表に示します。

表4-10 日付文字列用の書式

書式名 略称 日付書式

国際標準化機構規格

ISO

yyyy-mm-dd

USA標準

USA

mm/dd/yyyy

ヨーロッパ標準

EUR

dd.mm.yyyy

日本工業規格

JIS

yyyy-mm-dd

インストール定義

LOCAL

インストール時に定義した任意の書式。

'fmt'は、'Month dd, yyyy'などの日付書式モデルです。個別にコンパイルした単位を後でリンクする場合、すべての単位が同じDATE_FORMAT値を使用している必要があります。

関連項目:

日付書式モデル要素のリストは、日時書式の要素を参照してください。

4.12 データ型の同値化

データ型の同値化により、Oracleで入力データを解釈する方法と出力データの書式を設定する方法を制御できます。対応しているCOBOLのデータ型は、変数単位で外部データ型に同値化できます。

4.12.1 同値化の有用性

データ型の同値化には、いくつかの利点があります。たとえば、COBOLプログラムで 可変長文字列を使用するとします。PIC Xホスト変数を宣言した後に、これを外部データ型VARCHAR2に同値化できます。

また、デフォルトのデータ型変換を変更する場合に、データ型の同値化を使用できます。初期化ファイルのグローバリゼーション・サポート・パラメータで特に指定されていない場合、DATE列値を選択して文字ホスト変数に入れると、Oracleは次のような書式の9バイトの文字列を戻します。

DD-MON-YY 

文字ホスト変数をDATE外部データ型に同値化すると、Oracleは内部形式の7バイトの値を戻します。

4.12.2 ホスト変数の同値化

デフォルトでは、Pro*COBOLはすべてのホスト変数に特定の外部データ型を割り当てます。デフォルトの割当ては、ホスト変数を外部データ型に同値化することによって変更できます。これをホスト変数の同値化と呼びます。

VAR埋込みSQL文の構文は、次のとおりです。

      EXEC SQL
          VAR host_variable IS datatype [CONVBUFSZ [IS] (size)]
      END-EXEC

または

      EXEC SQL VAR host_variable [CONVBUFSZ [IS] (size)] END-EXEC

datatypeは、次のとおりです。

SQL datatype [ ( {length | precision, scale } ) ]

この2つの句のどちらか1つまたは両方を必ず指定する必要があります。

各パラメータの意味は次のとおりです。

表4-11 ホスト変数の同値化

変数 説明

precisionおよびscale

それぞれ有効桁数と四捨五入が実行される点を表す整数リテラル。たとえば位取りが2のときは、1/100の倍数の近似値に値が四捨五入される(3.456は3.46になる)ことを意味します。また位取りが-3のときは、1000の倍数の近似値に値が四捨五入される(3456が3000になる)ことを意味します。

1から99までのprecisionおよび-84から99までのscaleを指定できます。ただし、データベース列の精度および位取りの最大値は、それぞれ38と127です。したがって、precisionが38を超えていると、host_variableの値はデータベース列に挿入できません。一方、列値の位取りが99を超えていると、host_variableに入れる値の選択もフェッチもできません。

precisionおよびscaleは、type_nameがDECIMALまたはDISPLAYの場合にのみ指定してください。

length

前に宣言された入力または出力ホスト変数(あるいはホスト表)。

VARCHARおよびVARRAW外部データ型が2バイト長のフィールドで、nバイトのデータ・フィールドが続く場合、nの値の範囲は1から65533になります。そのため、type_nameがVARCHARまたはVARRAWの場合、host_variableには少なくとも3バイトの長さが必要です。

LONG VARCHARおよびLONG VARRAW外部データ型が4バイト長のフィールドで、nバイトのデータ・フィールドが続く場合、nの値の範囲は1から2147483643になります。そのため、type_nameがLONG VARCHARまたはLONG VARRAWの場合、host_variableには少なくとも5バイトの長さが必要です。

size

指定したhost_variableから別のキャラクタ・セットへの変換に使用するバッファのサイズ(バイト数)を示す整数。

SQL datatype

RAW、STRINGなどの有効な外部データ型の名前。

host_variable

前に宣言された入力または出力ホスト変数あるいはホスト表。

VARCHARおよびVARRAW外部データ型が2バイト長のフィールドで、nバイトのデータ・フィールドが続く場合、nの値の範囲は1から65533になります。そのため、type_nameがVARCHARまたはVARRAWの場合、host_variableには少なくとも3バイトの長さが必要です。

LONG VARCHARおよびLONG VARRAW外部データ型が4バイト長のフィールドで、nバイトのデータ・フィールドが続く場合、nの値の範囲は1から2147483643になります。そのため、type_nameがLONG VARCHARまたはLONG VARRAWの場合、host_variableには少なくとも5バイトの長さが必要です。

に、各外部データ型に使用するパラメータを示します。

NCHARホスト変数(PIC GまたはPIC N句を含む変数)には、EXEC SQL VARは使用できません。

DECLARE_SECTION=TRUEの場合は宣言部が必要であり、また、宣言部にEXEC SQL VAR文を記述する必要があります。

ext_type_nameがFLOATの場合はlengthを指定してください。ext_type_nameがDECIMALの場合は、lengthではなく、precisionおよびscaleを指定してください。

ホスト変数の同値化には、いくつかの利点があります。たとえば、Oracleにデータを格納するが解析は行わない場合に、ホスト変数の同値化を利用できます。4バイトの整数からなるホスト表をRAWデータベース列に格納するとします。この場合は、次に示すように、ホスト表をRAW外部データ型に同値化します。

 WORKING-STORAGE SECTION. 
     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 
 01  EMP-TABLES. 
     05  EMP-NUMBER  PIC S9(4) COMP OCCURS 50 TIMES. 
             ... 
*    Reset default datatype (INTEGER) to RAW.
     EXEC SQL VAR EMP-NUMBER IS RAW (200) END-EXEC.
     EXEC SQL END DECLARE SECTION END-EXEC.

ホスト表を使用する場合、指定したlengthは表を保持するのに必要なバッファ・サイズと一致する必要があります。最後の例では、lengthに200を指定しています。これは50個の4バイト整数に必要なバッファ・サイズです。

使用するグループ項目をLONG VARCHARとして宣言することもできます。

 01  MY-LONG-VARCHAR.
     05 UC-LEN PIC S9(9) COMP.
     05 UC-ARR PIC X(6000).
     EXEC SQL VAR MY-LONG-VARCHAR IS LONG VARCHAR(6000).

関連項目:

4.12.2.1 VAR文のCONVBUFSZ句

EXEC SQL VAR文には、オプションのCONVBUFSZ句を使用できます。指定したホスト変数のキャラクタ・セット間での変換に使用する、ランタイム・ライブラリ内のバッファのサイズ(バイト数)を指定します。

CONVBUFSZ句を指定しないと、ランタイム・ライブラリが、ホスト変数のキャラクタ・サイズ(NLS_LANGで判別)とデータベース・キャラクタ・セットのキャラクタ・サイズとの割合でバッファ・サイズを自動的に決定します。これによって、LONGサイズのバッファが作成されることがあります。データベースでは、LONG列を1つしか指定できません。複数のLONG値が指定されると、エラーとなります。

このようなエラーを回避するには、LONGのサイズよりも短い長さを使用します。キャラクタ・セットの変換の結果、CONVBUFSZで指定される長さよりも長い値になった場合、Pro*COBOLはエラーを戻します。

4.12.2.2

EMP表から従業員の名前を選択して、ヌル文字で終了した文字列を要求するC言語のルーチンに渡すとします。これらの名前に、明示的にヌル終端文字を付ける必要はありません。次のように、ホスト変数をSTRING外部データ型に同値化するのみです。

      EXEC SQL BEGIN DECLARE SECTION END-EXEC.
      ... 
 01   EMP-NAME  PIC X(11).
     EXEC SQL VAR EMP-NAME IS STRING (11) END-EXEC. 
      EXEC SQL END DECLARE SECTION END-EXEC. 

ENAME列の幅は10文字のため、ヌル終端文字を含めるために新しいEMP-NAMEには11文字を割り当てます。(lengthのデフォルト値はホスト変数の長さのため、lengthの指定は任意です。)ENAME列から値を選択してEMP-NAMEに入れると、その値はOracleによってヌル文字で終了にされます。

表4-12 ホスト変数を同値化するためのパラメータ

外部データ型 長さ 精度 スケール デフォルトの長さ

CHAR

オプション

該当なし

該当なし

変数の宣言長

CHARZ

オプション

該当なし

該当なし

変数の宣言長

DATE

該当なし

該当なし

該当なし

7バイト

DECIMAL

該当なし

必須

必須

なし

DISPLAY

該当なし

必須

必須

なし

DISPLAY TRAILING

該当なし

必須

必須

なし

UNSIGNED DISPLAY

該当なし

必須

必須

なし

OVERPUNCH TRAILING

該当なし

必須

必須

なし

OVERPUNCH LEADING

該当なし

必須

必須

なし

FLOAT

オプション(4または8)

該当なし

該当なし

変数の宣言長

INTEGER

オプション(1、2、4または8)

該当なし

該当なし

変数の宣言長

LONG

オプション

該当なし

該当なし

変数の宣言長

LONG RAW

オプション

該当なし

該当なし

変数の宣言長

LONG VARCHAR

必須(注意1)

該当なし

該当なし

なし

LONG VARRAW

必須(注意1)

該当なし

該当なし

なし

NUMBER

該当なし

該当なし

該当なし

該当なし

STRING

オプション

該当なし

該当なし

変数の宣言長

RAW

オプション

該当なし

該当なし

変数の宣言長

ROWID

該当なし

該当なし

該当なし

18バイト(注意2)

UNSIGNED

オプション(1、2または4)

該当なし

該当なし

変数の宣言長

VARCHAR

必須

該当なし

該当なし

なし

VARCHAR2

オプション

該当なし

該当なし

変数の宣言長

VARNUM

該当なし

該当なし

該当なし

22バイト

VARRAW

オプション

該当なし

該当なし

なし

  1. データ・フィールドが65533バイトを超える場合は、-1を渡します。

  2. 一般的な値ですが、デフォルトはポートによって異なります。

4.12.3 CHARFデータ型指定子の使用方法

VAR文でデータ型指定子CHARFを使用すると、COBOLのデータ型を固定長のANSIデータ型CHARに同値化できます。

PICX=CHARFの場合は、VAR文でデータ型CHARを指定すると、ホスト言語のデータ型は固定長のANSIデータ型CHAR (Oracleの外部データ型コード96)に同値化されます。PICX=VARCHAR2の場合は、ホスト言語のデータ型は可変長のデータ型VARCHAR2 (コード1)に同値化されます。

ホスト言語のデータ型をいつでも固定長のANSIデータ型CHARに同値化できます。これには、VAR文でデータ型CHARFを指定します。CHARFを使用すると、PICX=VARCHAR2に設定されている場合でも、ホスト言語のデータ型は固定長のANSIデータ型CHARに同値化されます。

4.12.4 ガイドライン

VARNUM値およびDATE値は、必ずOracleの内部形式で入力してください。Oracleは、VARNUM値およびDATE値の出力には内部形式を使用します。

列値を選択してVARNUMホスト変数に格納した後、先頭バイトをチェックして値の長さを調べることができます。内部データ型で、返されるVARNUM値の例を示しています。

表4-13 VARNUMの例

10進数 長さバイト 指数バイト 仮数バイト 終了文字バイト

5

2

193

6

該当なし

-5

3

62

96

102

2767

3

194

28, 68

該当なし

-2767

4

61

74, 34

102

100000

2

195

11

該当なし

1234567

5

196

2, 24, 46, 68

該当なし

必要とするOracleの外部データ型がない場合は、VARCHAR2ベースまたはRAWベースの外部データ型を使用してください。

関連項目:

DATE値の変換の詳細は、DATE文字列フォーマットの明示的な制御を参照してください。

4.12.5 RAWおよびLONG RAWの値

Oracleでは、RAW列値またはLONG RAW列値を選択して文字ホスト変数に格納する場合、内部バイナリ値を外部文字値に変換する必要があります。この場合、OracleはRAWデータまたはLONG RAWデータの各バイナリ・バイトを文字のペアとして戻します。個々の文字は、ニブル(1/2バイト)の等価の16進値を表します。たとえば、バイナリ・バイト11111111は文字のペア「FF」として戻されます。SQL関数RAWTOHEXはこれと同じ変換を実行します。

文字ホスト値をRAW列またはLONG RAW列に挿入するときも変換が必要です。ホスト変数内の文字のペアはそれぞれ、バイナリ・バイトの等価の16進値を表している必要があります。文字がニブルの16進値を表していない場合、Oracleはエラー・メッセージを発行します。

関連項目:

データ型変換の詳細は、サンプル・プログラム4: データ型の同値化を参照してください。

4.13 プラットフォームのエンディアン形式のサポート

Oracleでは、Unicodeデータ(UTF16)は、常にビッグ・エンディアン形式で格納されます。現在、クライアント・アプリケーションは様々なプラットフォームで実行されます。LinuxおよびWindowsではリトル・エンディアン形式が、Solarisではビッグ・エンディアン形式が使用されています。Pro*Cobolでは、UTF16のデータが挿入または選択されると、サーバーとクライアント間のエンディアン形式が変換されません。このため、PIC N変数のUTF16 (UCS2)の文字列が破損します。

コマンドライン・オプションpicn_endianを使用すると、PIC N変数のプラットフォームのエンディアン形式(LinuxおよびWindowsの場合はリトル・エンディアン形式、Solarisの場合はビッグ・エンディアン形式)を保持できます。

新しいコマンドライン・オプション

picn_endian={BIG|OS}

picn_endian=bigの場合、PIC N変数はキャラクタ・セットID AL16UTF16にバインドされます。

picn_endian=osの場合、PIC N変数はキャラクタ・セットID UCS2にバインドされます。

このオプションのデフォルト値は「big」で、現行の動作が保持されます。NLS_NCHARがAL16UTF16でない場合、このオプションは無視されます。

PIC N変数のキャラクタ・セットの形式は、既存のPro*Cobolコマンドライン・オプションを使用して設定できます。

charset_picn={nchar_charset|db_charset}

関連項目:

PICN_ENDIAN=OSの場合のvarcharホスト変数の詳細は、可変長変数を参照してください。

4.14 サンプル・プログラム4: データ型の同値化

次のプログラムは、Oracleに接続した後、SCOTTアカウントにIMAGEの名前のデータベースの表を作成し、この表への従業員番号のビットマップ・イメージの挿入をシミュレートします。データ型の同値化により、このプログラムはOracle外部データ型LONG RAWを使用してビットマップ・イメージを表現できます。後でユーザーが従業員番号を入力すると、その番号のビットマップがIMAGE表から選択され、端末の画面に表示されます。

* This program simulates the storage and retrieval of bitmap images into table
* IMAGE, which is created in the SCOTT account after logging on to ORACLE.
* Datatype equivalencing allows an ORACLE external type of LONG RAW to be
* specified for the programs representation of the images.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. DTY-EQUIV.
       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-NUMBER    PIC S9(4) COMP.
           05  EMP-NAME      PIC X(10) VARYING.
           05  SALARY        PIC S9(6)V99
                               DISPLAY SIGN LEADING SEPARATE.
           05  COMMISSION    PIC S9(6)V99
                               DISPLAY SIGN LEADING SEPARATE.
           05  COMM-IND      PIC S9(4) COMP.

           EXEC SQL VAR SALARY IS DISPLAY(8,2) END-EXEC.
           EXEC SQL VAR COMMISSION IS DISPLAY(8,2) END-EXEC.

       01  BUFFER-VAR.
           05  BUFFER        PIC X(8192).
           EXEC SQL VAR BUFFER IS LONG RAW END-EXEC.

       01  INEMPNO           PIC S9(4) COMP.
           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-INEMPNO     PIC 9(4).
       01  REPLY             PIC X(10).
       01  INDX              PIC S9(9) COMP.
       01  PRT-QUOT          PIC S9(9) COMP.
       01  PRT-MOD           PIC S9(9) COMP.

       PROCEDURE DIVISION.

       BEGIN-PGM.
           EXEC SQL WHENEVER SQLERROR
               DO PERFORM SQL-ERROR END-EXEC.

           PERFORM LOGON.
           DISPLAY "OK TO DROP THE IMAGE TABLE? (Y/N)  "
               WITH NO ADVANCING.

           ACCEPT REPLY.

           IF (REPLY NOT = "Y") AND (REPLY NOT = "y")
               GO TO SIGN-OFF-EXIT.
           EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
           EXEC SQL DROP TABLE IMAGE END-EXEC.
           DISPLAY " ".
           IF (SQLCODE = 0) DISPLAY
               "TABLE IMAGE DROPPED - CREATING NEW TABLE."
           ELSE IF (SQLCODE = -942) DISPLAY
               "TABLE IMAGE DOES NOT EXIST - CREATING NEW TABLE."
           ELSE PERFORM SQL-ERROR.
           EXEC SQL WHENEVER SQLERROR
               DO PERFORM SQL-ERROR END-EXEC.
           EXEC SQL CREATE TABLE IMAGE
               (EMPNO NUMBER(4) NOT NULL, BITMAP LONG RAW)
           END-EXEC.
           EXEC SQL DECLARE EMPCUR CURSOR FOR
               SELECT EMPNO, ENAME FROM EMP
           END-EXEC.
           EXEC SQL OPEN EMPCUR END-EXEC.
           DISPLAY " ".
           DISPLAY
             "INSERTING BITMAPS INTO IMAGE FOR ALL EMPLOYEES ...".
           DISPLAY " ".

       INSERT-LOOP.
           EXEC SQL WHENEVER NOT FOUND GOTO NOT-FOUND END-EXEC.
           EXEC SQL FETCH EMPCUR
               INTO :EMP-NUMBER, :EMP-NAME
           END-EXEC.
           MOVE EMP-NAME-ARR TO D-EMP-NAME.
           DISPLAY "EMPLOYEE ", D-EMP-NAME WITH NO ADVANCING.
           PERFORM GET-IMAGE.
           EXEC SQL INSERT INTO IMAGE
               VALUES (:EMP-NUMBER, :BUFFER)
           END-EXEC.
           DISPLAY " IS DONE!".
           MOVE SPACES TO EMP-NAME-ARR.
           GO TO INSERT-LOOP.

       NOT-FOUND.
           EXEC SQL CLOSE EMPCUR END-EXEC.
           EXEC SQL COMMIT WORK END-EXEC.
           DISPLAY " ".
           DISPLAY
             "DONE INSERTING BITMAPS.  NEXT, LET'S DISPLAY SOME.".

       DISP-LOOP.
           MOVE 0 TO INEMPNO.
           DISPLAY " ".
           DISPLAY "ENTER EMPLOYEE NUMBER (0 TO QUIT):  "
               WITH NO ADVANCING.

           ACCEPT D-INEMPNO.

           MOVE D-INEMPNO TO INEMPNO.
           IF (INEMPNO = 0)
               GO TO SIGN-OFF.
           EXEC SQL WHENEVER NOT FOUND GOTO NO-EMP END-EXEC.
           EXEC SQL SELECT EMP.EMPNO, ENAME, SAL, NVL(COMM, 0), BITMAP
               INTO :EMP-NUMBER, :EMP-NAME, :SALARY,
                    :COMMISSION:COMM-IND, :BUFFER
               FROM EMP, IMAGE
               WHERE EMP.EMPNO = :INEMPNO
                 AND EMP.EMPNO = IMAGE.EMPNO
           END-EXEC.
           DISPLAY " ".
           PERFORM SHOW-IMAGE.
           MOVE EMP-NAME-ARR TO D-EMP-NAME.
           MOVE SALARY TO D-SALARY.
           MOVE COMMISSION TO D-COMMISSION.
           DISPLAY "EMPLOYEE ", D-EMP-NAME, " HAS SALARY ", D-SALARY
               WITH NO ADVANCING.
           IF COMM-IND = -1
               DISPLAY " AND NO COMMISSION."
           ELSE
               DISPLAY " AND COMMISSION ", D-COMMISSION, "."
           END-IF.
           MOVE SPACES TO EMP-NAME-ARR.
           GO TO DISP-LOOP.

       NO-EMP.
           DISPLAY "NOT A VALID EMPLOYEE NUMBER - TRY AGAIN.".
           GO TO DISP-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 " ".

       GET-IMAGE.
           PERFORM MOVE-IMAGE
               VARYING INDX FROM 1 BY 1 UNTIL INDX > 8192.

       MOVE-IMAGE.
           STRING '*' DELIMITED BY SIZE
               INTO BUFFER
               WITH POINTER INDX.
           DIVIDE 256 INTO INDX
               GIVING PRT-QUOT REMAINDER PRT-MOD.
           IF (PRT-MOD = 0) DISPLAY "." WITH NO ADVANCING.

       SHOW-IMAGE.
           PERFORM VARYING INDX FROM 1 BY 1 UNTIL INDX > 10
               DISPLAY "               *************************"
           END-PERFORM.
           DISPLAY " ".

       SIGN-OFF.
           EXEC SQL DROP TABLE IMAGE END-EXEC.
       SIGN-OFF-EXIT.
           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.