日本語PDF

3 プログラム要件への対応

この章の項目は次のとおりです。

Oracleとアプリケーション・プログラムの間のデータの受渡しには、ホスト変数、データ型変換、イベント処理およびOracleへのアクセスが必要になります。この章では、これらの要件にどのように対応するかを説明します。変数の宣言、通信領域の宣言、およびOracleデータベースへの接続を行う埋込みSQLコマンドについて学習します。Oracleデータ型、グローバリゼーション・サポート、データ変換、データ型の同値化の利用方法についても学習します。最後の2項では、プログラムにOCIコールを埋め込む方法と、X/Openアプリケーションの開発方法について説明します。

3.1 宣言部

SQL文で使用されるすべてのプログラム変数(つまり、すべてのホスト変数)は、宣言部で宣言する必要があります。SQL文で宣言されていないホスト変数を使用すると、プリコンパイラではエラー・メッセージが出ます。エラー・メッセージの完全なリストは、『Oracle Databaseエラー・メッセージ』を参照してください。

宣言部は、次の文で始まります。

EXEC SQL BEGIN DECLARE SECTION;

そして、次の文で終了します。

EXEC SQL END DECLARE SECTION;

COBOLでは、文の終了文字はEND-EXECです。FORTRANでは改行です。

これら2つの文の間に使用できるのは、次の項目のみです。

  • ホスト変数とインジケータ変数の宣言

  • EXEC SQL DECLARE

  • EXEC SQL INCLUDE

  • EXEC SQL VAR

  • EXEC ORACLE

  • ホスト言語のコメント

プリコンパイルの単位ごとに複数の宣言部を使用できます。さらに、1つのホスト・プログラムには、別々にプリコンパイルされる単位を複数含めることができます。

3.1.1

次の例では、プログラムで後から使用する4つのホスト変数を宣言しています。

EXEC SQL BEGIN DECLARE SECTION; 
 emp_number INTEGER; 
 emp_name CHARACTER(10); 
 salary REAL; 
 commission REAL; 
EXEC SQL END DECLARE SECTION;

ホスト変数の宣言の詳細は、ホスト変数の宣言および参照を参照してください。

3.2 INCLUDE文

INCLUDE文を使用して、ホスト・プログラムにファイルをコピーできます。これはCOBOLのCOPYコマンドに似ています。次に例を示します。

-- copy in the SQLCA file
EXEC SQL INCLUDE SQLCA;

プログラムをプリコンパイルすると、EXEC SQL INCLUDE文はそれぞれ、その文で指定されたファイルのコピーに置き換えられます。

任意のファイルをインクルードできます。ファイルにSQLが埋め込まれている場合、インクルードされるファイルのみがプリコンパイルの対象となるため、そのファイルも必ずインクルードしてください。ファイル拡張子を指定しないと、プリコンパイラでは言語に依存するソース・ファイル用のデフォルトの拡張子であると想定されます(このマニュアルに対する使用ホスト言語の補足資料を参照してください)。

インクルードするファイルのディレクトリ・パスは、プリコンパイラ・オプションを指定することで設定できます。

INCLUDE=<path>

pathのデフォルト値はカレント・ディレクトリです。(ここでは、ディレクトリはファイルの場所の索引です。)

プリコンパイラでは、最初にカレント・ディレクトリを検索し、次にINCLUDEで指定されたディレクトリを検索して、最後に標準のINCLUDEファイル用のディレクトリを検索します。したがって、SQLCAやORACAなどの標準ファイルのディレクトリ・パスを指定する必要はありません。標準以外のファイルについては、現在のディレクトリに格納されている場合を除いて、INCLUDEを使用してディレクトリ・パスを指定する必要があります。

大文字と小文字が区別されるオペレーティング・システム(UNIXなど)を使用している場合は、ファイルを格納したときと同じファイル名を大文字と小文字を区別して指定してください。ディレクトリ・パスを指定するための構文はシステムによって異なります。使用しているシステム固有のOracleマニュアルを参照してください。

3.3 SQLCA

SQLCAは、診断チェックおよびイベント処理を行うためのデータ構造体です。実行時には、Oracleからプログラムに渡されるステータス情報がSQLCAで保持されます。SQL文の実行後、Oracleにより、図3-1に示すようにSQLCA変数が設定され、結果が示されます。

このように、INSERT文、UPDATE文またはDELETE文の実行の成否を確認でき、成功した場合には、何行処理されたかを確認できます。文の実行に失敗した場合は、原因の詳細な情報が得られます。

MODE={ANSI13|ORACLE}のとき、SQLCAをハードコーディングするか、INCLUDE文を使用してプログラムにコピーするかにより、SQLCAを宣言する必要があります。SQLCAの宣言方法および使用方法は、SQL通信領域の使用についてを参照してください。

3.4 Oracleのデータ型

Oracleでは、内部データ型外部データ型という2種類のデータ型が認識されます。内部データ型は、Oracleでデータベース列にデータを格納する方法を指定します。Oracleでは、データベース擬似列を表す内部データ型も使用されます。外部データ型は、データがホスト変数にどのように格納されるかを指定します。

プリコンパイル時に、宣言部の各ホスト変数は、外部データ型コードに関連付けられます。SQL文で使用するすべてのホスト変数のデータ型コードは、実行時にOracleに渡されます。Oracleは、コードを使用して内部データ型と外部データ型の間で変換します。

ノート:

動的SQL方法4またはデータ型の同値化を使用すると、デフォルトのデータ型変換をオーバーライドできます。動的SQLの方法4の詳細は、方法4の使用方法を参照してください。データ型の同値化の詳細は、データ型の同値化を参照してください。

3.4.1 内部データ型

表3-1は、Oracleでデータベースの列および擬似列に使用される内部データ型の一覧です。

表3-1 列および擬似列のデータ型

名前 コード 説明

CHAR

96

固定長文字列(255バイト以下)

DATE

12

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

LONG

8

可変長文字列(2147483647バイト以下)

LONG RAW

24

可変長バイナリ・データ(2147483647バイト以下)

MLSLABEL

105

可変長バイナリ・ラベル(5バイト以下)

NUMBER

2

固定数または浮動小数点数

RAW

23

可変長バイナリ・データ(255バイト以下)

ROWID

11

固定長バイナリ値

VARCHAR2

1

可変長文字列(2000バイト以下)

これらの内部データ型は、ホスト言語のデータ型とは大きく異なる場合があります。たとえば、NUMBERデータ型は、移植性、精度(四捨五入のエラーなし)および正しい照合のために設計されました。これに相当するデータ型を持つホスト言語はありません。

次に内部データ型について簡単に説明します。詳細は、「データ型」を参照してください。

3.4.2 CHAR

CHARデータ型は、固定長の文字データの格納に使用します。データが内部でどのように表されるかは、データベースの文字セットによって決まります。CHARデータ型には、255バイトまでの最大幅を指定できるオプションのパラメータがあります。構文は次のとおりです。

CHAR[(maximum_width)]

最大幅の指定には、定数または変数は使用できません。整数リテラルを使用する必要があります。最大幅を指定しない場合、デフォルトで1になります。CHAR(n)列の最大幅は、文字単位ではなくバイト単位で指定することを思い出してください。そのため、CHAR(n)列にマルチバイト(2バイト)文字が格納される場合、その最大幅はn/2文字未満になります。

3.4.3 DATE

DATEデータ型は、日付と時刻を7バイトの固定長フィールドに格納するために使用します。日付の部分はデフォルトで現在の月の1日に、時刻の部分は午前0時に設定されます。

内部的に、DATEはバイナリ形式で保存されます。DATE列値をプログラムの文字列に変換するとき、Oracleではセッション用にデフォルトの書式マスクが使用されます。ユリウス日の日付など、別の日付/時刻情報が必要な場合は、TO_CHARファンクションに書式マスクを指定して使用してください。DATE列値と文字列との間の変換には、常にVARCHAR2またはSTRINGなどの(外部の)文字データ型を使用してください。

3.4.4 LONG

LONGデータ型は、可変長文字列の格納に使用します。LONG列には、テキスト、文字の配列、さらには短い文書まで格納できます。LONGデータ型は、VARCHAR2データ型と似ていますが、LONG列の最大幅が2147483647バイト(2GB)である点が異なります。

LONG列は、UPDATE文、INSERT文および(大部分の)SELECT文で使用できますが、式、ファンクション・コール、またはWHEREGROUP BYおよびCONNECT BYなどのSQL句では使用できません。各データベース表で使用できるLONG列は1つのみで、その列には索引は付けられません。

3.4.5 LONG RAW

LONG RAWデータ型は、可変長バイナリ・データまたはバイト文字列の格納に使用します。LONG RAW列の最大幅は2147483647バイト(2GB)です。

LONG RAWデータはLONGデータに似ていますが、OracleではLONG RAWデータの意味は解釈されず、あるシステムから別のシステムにLONG RAWデータを送信しても、文字セットの変換は行われない点が異なります。LONGデータに適用される制限事項は、LONG RAWデータにも適用されます。

3.4.6 MLSLABEL

MLSLABELデータ型は、可変長のバイナリ・オペレーティング・システム・ラベルの格納に使用します。Oracleでは、データのアクセス制御にラベルを使用します。

MLSLABELデータ型を使用すれば、データベース列を定義できます。データ型がMLSLABELの列には、任意の有効なオペレーティング・システム・ラベルを挿入できます。ラベルがテキスト形式の場合、Oracleではそのラベルをバイナリ値に自動的に変換します。テキスト文字列の長さは、最大255バイトです。ただし、MLSLABEL値の内部での長さは、2バイトから5バイトの間です。

MLSLABEL列から値を選択し、文字変数に代入することもできます。Oracleでは、内部バイナリ値はVARCHAR2値から自動的に変換されます。

3.4.7 NUMBER

NUMBERデータ型は、固定数または浮動小数点数の格納に使用し、事実上サイズに制限はありません。精度(合計桁数)と位取り(四捨五入が発生する位を決定)を指定できます。

NUMBER値の最大精度は38です。大きさの範囲は1.0E-129から9.99E125です。位取りの範囲は-84から127です。たとえば、位取りが-3とは、数が1000単位で近似されることを意味します(3456は3000になります)。位取りが2とは、値が1/100単位で近似されることを意味します(3.456は3.46になります)。

精度と位取りを指定すると、Oracleはデータを格納する前に追加の整合性チェックをします。値が精度を超えると、Oracleはエラー・メッセージを発行します。値が位取りを上回ると、Oracleは値を丸めます。

3.4.8 RAW

RAWデータ型は、バイナリ・データまたはバイト文字列の格納に使用します(グラフィックス文字のシーケンスなど)。RAWデータは、Oracleでは解釈されません。

RAWデータ型には、255バイトまでの最大幅を指定できる必須パラメータを指定します。構文は次のとおりです。

RAW(maximum_width)

最大幅の指定には、定数または変数は使用できません。整数リテラルを使用する必要があります。

RAWデータはCHARデータと似ていますが、OracleではRAWデータの意味は解釈されず、あるシステムから別のシステムにRAWデータを送信しても、文字セットの変換(たとえば、7ビットASCIIからEBCDIC Code Page 500への変換)は行われない点が異なります。

3.4.9 ROWID

内部的には、Oracleデータベース内のすべての表にはROWIDという擬似列が1つあり、ここには行IDというバイナリ値が格納されます。ROWIDは行を一意に識別し、特定の行にアクセスする最速の方法です。

3.4.10 VARCHAR2

VARCHAR2データ型は、可変長文字列の格納に使用します。文字列が内部でどのように表されるかは、データベース文字セット(たとえば、7ビットASCIIまたはEBCDIC Code Page 500など)によって異なります。

VARCHAR2データベース列の最大幅は2000バイトです。VARCHAR2列を定義するには、次の構文を使用します。

VARCHAR2(maximum_width)

maximum_widthは、1から2000の範囲の整数リテラルです。

VARCHAR2(n)列の最大幅は、文字単位ではなくバイト単位で指定します。そのため、VARCHAR2(n)列にマルチバイト(2バイト)文字が格納される場合、その最大幅はn/2文字未満になります。

3.4.11 SQL疑似列および関数

SQLでは、表3-2の擬似列を認識し、擬似列からは特定のデータ項目が戻されます。

表3-2 擬似列のデータ型

擬似列 内部データ型

CURRVAL

NUMBER

LEVEL

NUMBER

NEXTVAL

NUMBER

ROWID

ROWID

ROWLABEL

MLSLABEL

ROWNUM

NUMBER

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

さらに、SQLでは、表3-3のパラメータがなく、特定のデータ項目を戻すファンクションを認識します。

表3-3 パラメータのないファンクションのデータ型

ファンクション 内部データ型

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;

これから、SQLの疑似列および関数を簡単に説明します。詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

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

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

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

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

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

EXEC SQL INSERT INTO PARTS
 VALUES (partno.NEXTVAL, :description, :quantity, :price);

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

ROWIDは、16進数で行アドレスを戻します。

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

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

... WHERE ROWNUM < constant;

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

... WHERE ROWNUM = 5;

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

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

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

3.4.12 ROWLABEL列

SQLでは、Oracleでデータベースごとに作成される特殊な列ROWLABELも認識されます。他の列と同様に、ROWLABELは、SQL文で参照できます。ROWLABELは、行のオペレーティング・システムのラベルを戻します。

ROWLABELの一般的な使用方法、問合せ結果のフィルタ処理です。たとえば、次の文ではセキュリティ・レベルがunclassifiedより高い行のみが数えられます。

EXEC SQL SELECT COUNT(*) INTO :head_count FROM EMP
 WHERE ROWLABEL > 'UNCLASSIFIED';

3.4.13 外部データ型

表3-4のように、外部データ型にはすべての内部データ型と、サポートされている他のホスト言語で使用するいくつかのデータ型が含まれています。たとえば、STRING外部データ型は、C言語ではNULLで終了する文字列を指し、DECIMALデータ型は、COBOLパック10進数を指します。データ型の名前はデータ型の同値化で使用し、データ型のコードは動的SQLの方法4で使用します。

表3-4 外部データ型

名前 コード 説明

CHAR

1 96

可変長文字列(65535バイト以下)、固定長文字列(65535バイト以下)(ノート1を参照)

CHARF

96

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

CHARZ

97

NULLで終了する固定長文字列(65535バイト以下)(ノート2を参照)

DATE

12

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

DECIMAL

7

COBOLパック10進数

DISPLAY

91

COBOL数値文字列

FLOAT

4

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

INTEGER

3

符号付き整数(2バイトまたは4バイト)

LONG

8

固定長文字列(2147483647バイト以下)

LONG RAW

24

固定長バイナリ・データ(217483647バイト以下)(ノート3を参照)

LONG VARCHAR

94

可変長文字列(217483643バイト以下)(ノート3を参照)

LONG VARRAW

95

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

MLSLABEL

106

可変長バイナリ・データ(2バイトから5バイト)

NUMBER

2

整数または浮動小数点数

RAW

23

固定長バイナリ・データ(65535バイト以下)(ノート2を参照)

ROWID

11

固定長バイナリ値(通常13バイト)

STRING

5

NULLで終了する可変長文字列(65535バイト以下)(ノート2を参照)

UNSIGNED

68

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

VARCHAR

9

可変長文字列(65533バイト以下)(ノート3を参照)

VARCHAR2

1

可変長文字列(65535バイト以下)(ノート2を参照)

VARNUM

6

可変長バイナリ数

VARRAW

15

可変長バイナリ・データ(65533バイト以下)(ノート3を参照)

ノート:

  1. CHARは、MODE={ORACLE|ANSI13|ANSI14}の場合はデータ型1、MODE=ANSIの場合はデータ型96です。

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

  3. EXEC SQL VAR文にはnバイト長のフィールドを含めないでください。

3.4.14 CHAR

CHARの動作は、DBMSオプションとMODEオプションの設定により異なります。

3.4.15 CHARF

MODE=ANSIの場合、OracleではCHARデータ型はすべての文字ホスト変数に割り当てられます。CHARデータ型は、固定長文字列の格納に使用します。ほとんどのプラットフォームでは、CHAR値の最大長は65535バイト(64KB)です。DBMSオプションとMODEオプションの関係の詳細は、表6-4を参照してください。

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

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

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

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

3.4.16 CHARZ

CHARZデータ型は、NULLで終了する固定長文字列の格納に使用します。ほとんどのプラットフォームでは、CHARZ値の最大長は65,535バイトです。Pro*COBOLまたはPro*FORTRANでは、この外部データ型は必要ありません。

入力時、 CHARZデータ型とSTRINGデータ型の機能は同じです。入力値はNULL文字で終了する必要があります。NULL終了文字は、文字列の区切り記号としての役割のみを果し、データの一部にはなりません。

出力時、CHARZデータ型とCHARデータ型の機能は同じです。出力値にはNULL終了文字が付けられ、必要に応じて空白文字も埋め込まれます。

3.4.17 DATE

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

表3-5 DATEデータ型の例

バイト 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)です。

3.4.18 DECIMAL

Pro*COBOLでは、DECIMALデータ型を使用して計算用のパック10進数の格納に使用します。COBOLでは、ホスト変数は暗黙的な小数点を持つ符号付きCOMP-3フィールドであることが必要です。データ変換中に有効な桁が失われると、ホスト変数はアスタリスクで埋められます。

3.4.19 DISPLAY

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

3.4.20 FLOAT

FLOATデータ型は、小数部分を持つ数値またはINTEGERデータ型の容量を超える数値を格納するために使用します。数値はご使用のコンピュータの浮動小数点書式を使用して表され、通常、4または8バイトの記憶域を必要とします。入力および出力ホスト変数に長さを指定する必要があります。

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

ノート:

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

3.4.21 INTEGER

INTEGERデータ型は、小数部分のない数値の格納に使用します。整数は、2バイトまたは4バイトの符号付き2進数です。1語内のバイトの順序は、システムによって異なります。入力および出力ホスト変数に長さを指定する必要があります。出力時には、列値が浮動小数点数であれば、小数部が切り捨てられます。

3.4.22 LONG

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

3.4.23 LONG RAW

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

LONG RAWデータはLONGデータに似ていますが、OracleではLONG RAWデータの意味は解釈されず、あるシステムから別のシステムにLONG RAWデータを送信しても、文字セットの変換は行われない点が異なります。

3.4.24 LONG VARCHAR

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

3.4.25 LONG VARRAW

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

3.4.26 MLSLABEL

MLSLABELデータ型は、可変長のバイナリ・オペレーティング・システム・ラベルの格納に使用します。Oracleでは、データのアクセス制御にラベルを使用します。MLSLABELデータ型を使用して列を定義できます。データ型がMLSLABELの列には、任意の有効なオペレーティング・システム・ラベルを挿入できます。

入力時。Oracleでは、入力値は有効なオペレーティング・システム・ラベルであるバイナリ・ラベルに変換します。無効のラベルの場合は、エラー・メッセージが出ます。ラベルが有効ならば、ターゲット・データベース列に格納されます。

出力時。Oracleでは、バイナリ・ラベルを文字列に変換し、文字列はCHARCHARZSTRINGVARCHARまたはVARCHAR2のいずれかのデータ型です。

3.4.27 NUMBER

NUMBERデータ型は、固定または浮動小数点のOracle数値を格納するために使用します。精度および位取りを指定できます。NUMBER値の最大精度は38です。大きさの範囲は1.0E-129から9.99E125です。位取りの範囲は-84から127です。

NUMBER値は、可変長形式(1バイトの指数部に最大20バイトの仮数部が続く)で格納されます。指数バイトの上位1ビットは符号ビットであり、正数の場合に設定します。下位7ビットは指数を表し、100の位を底とし、オフセットは65です。

各仮数バイトは基数100で範囲1から100の数字です。正数の場合は、それに1を加算した数字となります。負数の場合、101からそれが引かれ、20バイトの仮数部があるのでないかぎり、102を含んでいるバイトがデータ・バイトに追加されます。各仮数バイトは、2つの10進数を表すことができます。仮数は正規化され、先行する0(ゼロ)は格納されません。仮数部には最大20のデータ・バイトを使用できますが、正確さが保証されているのは19バイトのみです。19個のデータ・バイトは、それぞれ基数100の数字を表し、38桁の最大精度を提供します。

出力時、ホスト変数にはOracleで内部的に表されたとおりの数値が含まれます。考えられる最大の数値を含めるには、出力ホスト変数は21バイトの長さが必要です。数値を表すために使用されるバイトのみが戻されます。Oracleでは出力値の空白を埋め込んだり、NULLで終了させたりしません。戻り値の長さを知る必要がある場合は、かわりにVARNUMデータ型を使用してください。通常、このデータ型を使用する理由はほとんどありません。

3.4.28 RAW

RAWデータ型は、固定長のバイナリ・データまたはバイト文字列の格納に使用します。ほとんどのプラットフォームでは、RAW値の最大長は65535バイトです。RAWデータはCHARデータと似ていますが、OracleではRAWデータの意味は解釈されず、RAWデータをあるシステムから別のシステムへ送信しても文字セットの変換は行われません。

3.4.29 ROWID

ROWIDデータ型は、バイナリ行IDを固定長(通常は13バイト)に格納するために使用します。フィールド・サイズは、ポート固有です。そのため、使用しているシステム固有のOracleマニュアルをチェックしてください。VARCHAR2ホスト変数を使用すると、読取り可能な形式で行IDを格納できます。行IDを選択またはフェッチしてVARCHAR2ホスト変数に入れると、Oracleではそのバイナリ値を18バイトの文字列に変換し、次の書式で戻します。

BBBBBBBB.RRRR.FFFF

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

0000000E.000A.0007

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

通常、行IDをVARCHAR2ホスト変数にフェッチし、ホスト変数をUPDATE文またはDELETE文のWHERE句のROWID擬似列と比較します。そのようにして、カーソルによってフェッチされた最終行を識別できます。

ノート:

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

3.4.30 STRING

STRINGデータ型は、VARCHAR2データ型に似ていますが、STRING値は常にヌル文字で終了するという違いがあります。

入力時。Oracleは指定された長さを使用して、ヌル終端文字のスキャンを制限します。ヌル終端文字が見つからなければ、エラーが生成されます。長さを指定しない場合、Oracleは最大長とみなします。大部分のプラットフォームでは65535です。

STRING値の最小長は2バイトです。最初の文字がNULL終了文字で、指定した長さが2の場合、列がNOT NULLと定義されていなければ、OracleではNULLを挿入します。空白のみの値またはNULLで終了する値はそのまま格納されます。

出力時。Oracleは戻された最後の文字に1バイトのヌル文字を追加します。文字列長が指定された長さを超える場合は、Oracleは出力値を切り捨て、1バイトのヌル文字を追加します。

3.4.31 UNSIGNED

UNSIGNEDデータ型は、符号なし整数の格納に使用します。符号なし整数は、2バイトまたは4バイトの2進数です。1語内のバイトの順序は、システムによって異なります。入力および出力ホスト変数に長さを指定する必要があります。出力時には、列値が浮動小数点数であれば、小数部が切り捨てられます。Pro*COBOLまたはPro*FORTRANでは、この外部データ型は必要ありません。

3.4.32 VARCHAR

VARCHARデータ型は、可変長文字列の格納に使用します。VARCHAR変数では、2バイト長のフィールドの後に65533バイト以下の文字列フィールドが続きます。ただし、VARCHAR配列要素では、文字列フィールドの最大長は65530バイトです。VARCHAR変数の長さを指定するときには、長さフィールド用の2バイトが含まれていることを確認してください。これより長い文字列には、LONG VARCHARデータ型を使用してください。EXEC SQL VAR文では、2バイト長のフィールドを含めないでください。

3.4.33 VARCHAR2

MODE=ORACLEの場合、OracleではVARCHAR2データ型をすべての文字ホスト変数に割り当てます。VARCHAR2データ型は、可変長文字列の格納に使用します。ほとんどのプラットフォームでは、VARCHAR2値の最大長は65535バイトです。

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

入力時。Oracleは入力ホスト変数に指定されたバイト数を読み込み、後続の空白文字を取り除き、入力値をターゲット・データベース列に格納します。ここでは注意が必要です。未初期化ホスト変数には、一連のヌル文字が含まれている場合があります。したがって、常に文字入力ホスト変数の宣言長まで空白文字で埋めてください。(COBOL PIC X(n)およびFORTRAN CHARACTER*nの各変数では、これは自動的に行われます。)

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

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

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

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

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

3.4.34 VARNUM

VARNUMデータ型はNUMBERデータ型に似ていますが、VARNUM変数の1バイト目に値の長さが格納される点が異なります。入力時には、ホスト変数の1バイト目を値の長さに設定する必要があります。出力時には、ホスト変数に長さとそれに続いてOracleで内部的に表現された数が含まれます。この数が最大になっても対応できるように、ホスト変数の長さは22バイトにする必要があります。列値をVARNUMホスト変数に選択した後、1バイト目をチェックすれば値の長さがわかります。

3.4.35 VARRAW

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

3.5 データ型変換

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

Oracleでは、選択した列(または擬似列)値を出力ホスト変数に割り当てる前に、必要に応じて、その列の内部データ型をホスト変数のデータ型に変換します。同様に、入力ホスト変数の値をデータベース列に割り当てたり、比較したりする前には、必要に応じて、ホスト変数の外部データ型を列の内部データ型に変換します。

ただし、ホスト変数のデータ型は、データベース列のデータ型との互換性が必要です。必ず、変換可能な値を指定してください。たとえば、文字列値YESTERDAYをDATE列値に変換しようとすると、エラーが発生します。

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

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

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

ノート:

凡例:

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

    I = 入力のみ。出力時には、列値が同じ形式で戻されます。

    O = 出力のみ

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

    I/O = 入力または出力。出力時には、列値が同じ形式で戻されます。

  • 入力時には、ホスト文字列を16進数の形式にする必要があります。出力時には、列値は同じ形式で戻されます。

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

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

  • 入力時には、列値は16進数の形式で格納されます。出力時、列値は16進フォーマットであることが必要です。

  • 入力時には、ホスト文字列をテキスト形式の有効なオペレーティング・システム・ラベルにする必要があります。出力時には、列値は同じ形式で戻されます。

  • 入力時には、ホスト文字列をRAW形式の有効なオペレーティング・システム・ラベルにする必要があります。出力時には、列値は同じ形式で戻されます。

表3-6 内部データ型と外部データ型間の変換

外部 内部: CHAR 内部: DATE 内部: LONG 内部: LONG RAW 内部: MLSLABEL 内部: NUMBER 内部: RAW 内部: ROWID 内部: VARCHAR2

CHAR

I/O

I/O

I/O

I

I/O

I/O

I/O

I/O

I/O

CHARF

I/O

I/O

I/O

I

I/O

I/O

I/O

I/O

I/O

CHARZ

I/O

I/O

I/O

I

I/O

I/O

I/O

I/O

I/O

DATE

I/O

I/O

I

I/O

DECIMAL

I/O

I

I/O

I/O

DISPLAY

I/O

I

I/O

I/O

FLOAT

I/O

I

I/O

I/O

INTEGER

I/O

I

I/O

I/O

LONG

I/O

I/O

I/O

I

I/O

I/O

I/O

I/O

I/O

LONG RAW

O

I

I/O

I/O

O

LONG VARCHAR

I/O

I/O

I/O

I

I/O

I/O

I/O

I/O

I/O

LONG VARRAW

I/O

I

I/O

I/O

I/O

MLSLABEL

I/O

I/O

I/O

I/O

NUMBER

I/O

I

I/O

I/O

RAW

I/O

I

I/O

I/O

I/O

ROWID

I

I

I/O

I

STRING

I/O

I/O

I/O

I

I/O

I/O

I/O

I/O

I/O

UNSIGNED

I/O

I

I/O

I/O

VARCHAR

I/O

I/O

I/O

I

I/O

I/O

I/O

I/O

I/O

VARCHAR2

I/O

I/O

I/O

I

I/O

I/O

I/O

I/O

I/O

VARNUM

I/O

I

I/O

I/O

VARRAW

I/O

I

I/O

I/O

I/O

3.5.1 DATE値

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

文字ホスト変数をDATE列に挿入するときにも変換が必要です。Oracleでは暗黙的にSQLファンクションTO_DATEがコールされ、デフォルトの日付書式が予想されます。他の書式で日付を挿入するには、書式マスクを指定してTO_DATEを明示的にコールする必要があります。

3.5.2 RAWおよびLONG RAWの値

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

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

ORA-01465: invalid hex number

3.6 ホスト変数の宣言および参照

SQL文で使用するプログラム変数はすべて、ホスト変数として宣言する必要があります。ホスト変数は、ホスト言語の規則に従って宣言部で宣言します。通常の有効範囲規則を適用します。ホスト変数名は、長さに制限はありませんが、有効な文字は最初の31文字のみです。ANSI/ISO準拠のため、ホスト変数名は長さを18文字以下にし、先頭が文字で、連続したアンダースコアや後続のアンダースコアを含まないことが必要です。

ホスト変数の外部データ型およびそのソース・データベースまたはターゲット・データベース列の内部データ型は、同じである必要はありませんが、互換性が必要です。表3-6では、必要に応じてOracleで自動的に変換される互換性のあるデータ型を示しています。

Oracle プリコンパイラでは、ほとんどの組込みホスト言語データ型をサポートしています。サポートされるデータ型のリストは、使用ホスト言語の補足資料を参照してください。ユーザー定義のデータ型はサポートされていません。データ型の同値化については、次の項で説明します。

ユーザー定義の構造体の参照はできませんが、Pro*COBOLプリコンパイラを使用すれば、構造体の個々の要素をホスト変数であるかのように参照できます。ホスト変数が使用可能な場所ならば、そのような参照を使用できます。

3.6.1

次の例では、3つのホスト変数を宣言してから、SELECT文を使用して、ホスト変数emp_numberの値に一致する従業員番号をデータベースで検索します。一致する行が見つかると、Oracleでは出力ホスト変数dept_numberemp_nameをその行のDEPTNO列とENAME列の値に設定します。

-- declare host variables
EXEC SQL BEGIN DECLARE SECTION;
 emp_number INTEGER;
 emp_name CHARACTER(10);
 dept_number INTEGER;
EXEC SQL END DECLARE SECTION;
...
display 'Employee number? ';
read emp_number;
EXEC SQL SELECT DEPTNO, ENAME INTO :dept_number, :emp_name
 FROM EMP
 WHERE EMPNO = :emp_number;

ホスト変数の使用方法の詳細は、ホスト変数の使用についてを参照してください。

3.6.2 VARCHAR変数

VARCHAR擬似型を使用すると、可変長文字列を宣言できます。(擬似型は、使用するホスト言語に固有のデータ型ではありません。)VARCHAR変数には2バイト長のフィールドの後に文字列フィールドが1つ続くことを思い出してください。たとえば、Pro*COBOLプリコンパイラでは、次のVARCHAR宣言がどのように処理されるか見てみましょう。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
 01 ENAME PIC X(20) VARYING.
 EXEC SQL END DECLARE SECTION END-EXEC.

宣言は、配列と長さのメンバーを指定した次のCOBOLグループ項目に拡張されます。

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

VARCHARの長さは、長さフィールドを参照すればわかります。文字列ファンクションまたは文字カウント・アルゴリズムを使用する必要はありません。

VARCHARの詳細は、このマニュアルに対する使用ホスト言語の補足資料を参照してください。

3.6.3 ホスト変数のガイドライン

ホスト変数の宣言および参照については、次のガイドラインに従ってください。ホスト変数には次の必要条件があります。

  • 宣言部で明示的に宣言します。

  • SQL文およびPL/SQLブロックではコロン(:)の接頭辞を付けます。

  • ホスト言語でサポートされているデータ型です。

  • ソースまたはターゲットのデータベース列と互換性のあるデータ型です。

ホスト変数では、次のことはしないください。

ホスト変数では次のことができます。

  • SQL文で式が使用可能な場所での使用

  • インジケータ変数と関連付けることができます。

3.7 インジケータ変数の宣言および参照

ホスト変数はすべて、オプションのインジケータ変数に関連付けることができます。インジケータ変数は、2バイトの整数として宣言部で定義し、SQL文では先頭にコロンを付け、INDICATORキーワードを使用しない場合には、ホスト変数の直後に指定する必要があります。

3.7.1 INDICATORキーワード

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

:<host_variable> INDICATOR :<indicator_variable>

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

:<host_variable>:<indicator_variable>

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

3.7.2

通常、インジケータ変数は、入力ホスト変数へのNULLの割当てと、出力ホスト変数に含まれるNULLまたは切り捨てられた値の検出に使用されます。次の例では、3つのホスト変数と1つのインジケータ変数を宣言してから、SELECT文を使用して、ホスト変数emp_numberの値と一致する従業員番号をデータベースで検索します。一致する行が見つかると、出力ホスト変数salarycommissionが、その行のSAL列とCOMM列の値に設定され、リターン・コードがインジケータ変数ind_commに格納されます。次の文では、ind_commを使用して、一連の処理を選択しています。

EXEC SQL BEGIN DECLARE SECTION;
 emp_number INTEGER;
 salary REAL;
 commission REAL;
 ind_comm SMALLINT; -- indicator variable
EXEC SQL END DECLARE SECTION; 
 pay REAL; -- not used in a SQL statement
display 'Employee number? ';
read emp_number;
EXEC SQL SELECT SAL, COMM
 INTO :salary, :commission:ind_comm
 FROM EMP
 WHERE EMPNO = :emp_number;
IF ind_comm = -1 THEN -- commission is null
 set pay = salary;
ELSE
 set pay = salary + commission;
ENDIF;

詳細は、インジケータ変数の使用についてを参照してください。

3.7.3 インジケータ変数のガイドライン

インジケータ編集の宣言および参照については、次のガイドラインに従ってください。インジケータ変数には、次の必要条件があります。

  • 宣言部で2バイト整数として明示的に宣言

  • SQL文で先頭にコロン(:)

  • SQL文およびPL/SQLブロックではホスト変数の直後に指定(INDICATORキーワードを前に付けない場合)

インジケータ変数では、次のことをしないでください。

  • ホスト言語文で先頭にコロン

  • ホスト言語の文中でホスト変数の直後に指定

  • Oracleの予約語

3.8 データ型の同値化

データ型の同値化により、Oracleで入力データを解釈する方法と出力データの書式を設定する方法をカスタマイズできます。サポートされているホスト言語のデータ型は、変数ごとにOracleの外部データ型に同値化できます。

3.8.1 データ型の同値化を行う理由

データ型の同値化は、いくつかの点で役に立ちます。たとえば、COBOLプログラムでNULLで終了するホスト文字列を使用するとします。PIC Xホスト変数を宣言した後で、これを常にNULLで終了する外部データ型STRINGに同値化できます。

Oracleにデータを格納するが、解釈はしないという場合に、データ型の同値化を使用できます。たとえば、LONG RAWデータベース列に整数のホスト配列を格納する場合、ホスト配列を外部データ型LONG RAWに同値化できます。

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

DD-MON-YY

ただし、文字ホスト変数をDATE外部データ型に同値化すると、内部書式の7バイトの値が戻されます。

3.8.2 ホスト変数の同値化

デフォルトでは、Oracleプリコンパイラは、すべてのホスト変数に特定の外部データ型を割り当てます。(これらのデフォルトの割当ては、このマニュアルに対する補足資料で表にまとめられています。)デフォルトの割当ては、宣言部でホスト変数をOracleの外部データ型に同値化することによりオーバーライドできます。これをホスト変数の同値化と呼びます。

使用する構文は次のとおりです。

EXEC SQL VAR <host_variable>
 IS <ext_type_name> [({<length> | <precision>,<scale>})];

ここで、host_variableは、宣言部で先に宣言された入力または出力ホスト変数(あるいはホスト配列)です。VARCHARおよびVARRAW外部データ型が2バイト長のフィールドで、nバイトのデータ・フィールドが続く場合、nの値の範囲は1から65533になります。そのため、type_nameVARCHARまたはVARRAWの場合、host_variableには少なくとも3バイトの長さが必要です。

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

ext_type_nameは、RAWSTRINGなどの有効な外部データ型の名前です。

lengthは、有効な長さをバイトで指定する整数リテラルです。lengthの値は、外部データ型を指定するのに十分な長さにする必要があります。

type_nameDECIMALまたはDISPLAYの場合は、lengthではなく、precisionおよびscaleを指定する必要があります。type_nameVARNUMROWIDまたはDATEの場合、lengthは事前に定義されているために指定できません。他の外部データ型の場合、lengthはオプションです。デフォルトでhost_variableの長さに設定されます。

lengthを指定するときに、type_nameVARCHARVARRAWLONG VARCHARまたはLONG VARRAWの場合は、データ・フィールドの最大長を指定してください。プリコンパイラでは、lengthフィールドの説明をします。type_nameLONG VARCHARまたはLONG VARRAWで、データ・フィールドが65533バイトを超える場合は、lengthフィールドに-1を指定してください。

precisionscaleは、それぞれ有効数字の数値と四捨五入が発生する位置を表します。たとえば、scaleが2の場合、値は小数第2位に値が四捨五入されることを意味します(3.456は3.46になります)、scaleが-3のときは、1000の位に値が四捨五入されます(3456は3000になります)。

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

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

表3-7は、各外部データ型に使用されるパラメータを示しています。

3.8.3

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

EXEC SQL BEGIN DECLARE SECTION;
 ...
 emp_name CHARACTER(11);
 EXEC SQL VAR emp_name IS STRING (11);
EXEC SQL END DECLARE SECTION;

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

表3-7 外部データ型のパラメータ

外部データ型 長さ 精度 位取り デフォルトの長さ

CHAR

オプション

該当なし

該当なし

変数の宣言長

CHARZ

オプション

該当なし

該当なし

変数の宣言長

DATE

該当なし

該当なし

該当なし

7バイト

DECIMAL

該当なし

必須

必須

なし

DISPLAY

該当なし

必須

必須

なし

FLOAT

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

該当なし

該当なし

変数の宣言長

INTEGER

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

該当なし

該当なし

変数の宣言長

LONG

オプション

該当なし

該当なし

変数の宣言長

LONG RAW

オプション

該当なし

該当なし

変数の宣言長

LONG VARCHAR

必須(ノート1)

該当なし

該当なし

なし

LONG VARRAW

必須(ノート1)

該当なし

該当なし

なし

MLSLABEL

必須

該当なし

該当なし

なし

NUMBER

該当なし

該当なし

該当なし

使用不可

STRING

オプション

該当なし

該当なし

変数の宣言長

RAW

オプション

該当なし

該当なし

変数の宣言長

ROWID

該当なし

該当なし

該当なし

13バイト(ノート2)

UNSIGNED

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

該当なし

該当なし

変数の宣言長

VARCHAR

必須

該当なし

該当なし

なし

VARCHAR2

オプション

該当なし

該当なし

変数の宣言長

VARNUM

該当なし

該当なし

該当なし

22バイト

VARRAW

オプション

該当なし

該当なし

なし

ノート:

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

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

3.8.4 CHARFデータ型指定子の使用について

VAR文およびTYPE文でデータ型指定子CHARFを使用すると、DBMSの設定に関係なく、ホスト言語のデータ型を固定長のANSIデータ型CHARに同値化できます。

MODE=ANSIの場合、TYPE文でデータ型CHARを指定すると、ホスト言語のデータ型は固定長のANSIデータ型CHAR(Oracleの外部データ型コード96)に同値化されます。ただし、MODE=ORACLEの場合、ホスト言語のデータ型は、ユーザーの意向に関係なく、可変長データ型VARCHAR2(コード1)に同値化されます。

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

3.8.5 ガイドライン

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

列値をVARNUMホスト変数に選択した後、1バイト目をチェックすれば値の長さがわかります。表3-8では、戻されるVARNUM値の例を示しています。

表3-8 戻されるVARNUM値の例

10進数値 VARNUM値の長さバイト VARNUM値の指数バイト VARNUM値の仮数部バイト VARNUM値の終了文字バイト

0

1

128

該当なし

該当なし

5

2

193

6

該当なし

-5

3

62

96

102

2767

3

194

28, 68

該当なし

-2767

4

61

74, 34

102

100000

2

195

11

該当なし

abcdefg

5

196

2, 24, 46, 68

該当なし

DATE値は、通常、プログラムによる値の出力(たとえば、表示)や入力に使用されめ、DD-MON-YYなどの文字書式に変換してください。

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

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

広く使用されている7ビットまたは8ビットのASCIIおよびEBCDICの文字セットは、アルファベットを表すには十分ですが、日本語のようなアジアの言語には数千もの文字が含まれるものがあります。これらの言語では、1文字を表すために16ビット(2バイト)が必要です。Oracleではこうした様々な言語がどのように処理されるかについて説明します。

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

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

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

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

Globalization Support_LANGUAGE

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

Globalization Support_TERRITORY

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

Globalization Support_DATE_FORMAT

日付書式

Globalization Support_DATE_LANGUAGE

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

Globalization Support_NUMERIC_CHARACTERS

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

Globalization Support_CURRENCY

各国通貨記号

Globalization Support_ISO_CURRENCY

ISO通貨記号

Globalization Support_SORT

ソートの順序

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

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

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

  • ソートの順序

Globalization Support_TERRITORYでは、地域によって異なる次の機能のデフォルト値を指定します。

  • 日付書式

  • 小数点文字

  • グループ・セパレータ

  • 各国通貨記号

  • ISO通貨記号

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

Globalization Support_LANG = <language>_<territory>.<character set>

languageはユーザー・セッション用のGlobalization Support_LANGUAGEの値、territoryはGlobalization Support_TERRITORYの値、character setは端末に使用されるコード体系を指定します。コード体系(通常は文字セットまたはコード・ページと呼ばれる)は、端末で表示可能な文字セットに対応する数値コードの範囲です。これには、端末との通信を制御するコードも含まれています。

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

setenv Globalization Support_LANG French_France.WE8ISO8859P1

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

ALTER SESSION SET <Globalization Support_parameter> = <value>

Oracleプリコンパイラでは、グローバリゼーション・サポート機能がすべてサポートされているため、アプリケーションではOracleデータベースに格納されている多言語のデータを処理できます。たとえば、外国語の文字変数を宣言し、それをINSTRBLENGTHBおよびSUBSTRBなどの文字列ファンクションに渡すことができます。これらのファンクションにはそれぞれ、INSTRLENGTHおよびSUBSTRファンクションと同じ構文がありますが、文字単位ではなく、バイト単位で機能します。

Globalization Support_INITCAP、Globalization Support_LOWERおよびGlobalization Support_UPPERファンクションを使用して、大文字小文字変換の特別なインスタンスを処理できます。また、Globalization Support_SORTファンクションを使用して、バイナリ順序ではなく、言語上の順序に基づいてWHERE句の比較を指定できます。グローバリゼーション・サポート・パラメータをTO_CHAR, TO_DATEおよびTO_NUMBERファンクションに渡すこともできます。

3.10 グローバリゼーション・サポートのマルチバイト文字セット

Pro*COBOLプリコンパイラでは、次の機能により、マルチバイトのグローバリゼーション・サポート文字セットのサポートが拡張されています。

  • プリコンパイラによる埋込みSQL文中のマルチバイト・キャラクタ文字列の認識。

  • ANSI標準COBOLのPIC Nデータ型宣言句で、ホスト文字変数を2バイト文字の文字列として解釈するようにプリコンパイラに指示します。

Oracleでは、プリコンパイラのランタイム・ライブラリSQLLIBにより、マルチバイト文字列がサポートされています。

3.10.1 埋込みSQL内の文字列

埋込みSQL文内のマルチバイトのグローバリゼーション・サポート文字列は、文字列をマルチバイト文字列として識別する文字リテラルと、その後に続く一重引用符で囲まれた文字列で構成されます。

たとえば、次のような埋込みSQL文があるとします。

EXEC SQL
 SELECT empno INTO :emp_num FROM emp
 WHERE ename=N'Kuroda'
 END-EXEC.

この文では、'Kuroda'という文字列の前に付いているN文字リテラルにより、この文字列がマルチバイト文字列であると認識されるため、マルチバイト文字の文字列が含まれていることがわかります。

3.10.2 動的SQL

動的SQL文はプリコンパイル時には処理されず、Oracleではマルチバイトのグローバリゼーション・サポート文字列自体は処理されないため、動的SQL文にはグローバリゼーション・サポートのマルチバイト文字列を埋め込むことはできません。

3.10.3 埋込みDDL

グローバリゼーション・サポートのマルチバイト・データを格納する列は、埋込みのデータ定義言語(DDL)文では使用できません。この制限はプリコンパイル時には適用されないため、NCHARなどの拡張された列型を埋込みDDL文で使用すると、プリコンパイル・エラーではなく実行エラーになります。

3.10.4 グローバリゼーション・サポートのマルチバイト・ホスト変数

Pro*COBOLプリコンパイラでは、ANSI規格PIC N句を使用して、マルチバイト文字データのホスト変数を宣言します。PIC N句を使用して宣言された変数は、2バイト文字の文字列変数として認識されます。

  • Globalization Support_LOCAL

  • VARCHAR

これらのオプションの詳細は、Oracleプリコンパイラの実行を参照してください。

3.10.5 制限事項

表は使用できません。

PIC Nデータ型を使用して宣言されたホスト変数は、表に使用できません。

奇数バイト幅はありません。マルチバイトのグローバリゼーション・サポート文字の格納に、Oracle CHAR列を使用しないでください。奇数バイトのデータがシングルバイト列からマルチバイトのグローバリゼーション・サポート(PIC N)・ホスト変数にフェッチされると、ランタイム・エラーが発生します。

ホスト変数の同値化は行えません。マルチバイトのグローバリゼーション・サポート文字変数は、EXEC SQL VAR文を使用して同値化できません。

動的SQLは使用できません。Pro*COBOLでは、グローバリゼーション・サポートのマルチバイト文字に動的SQLを使用できません。

3.10.6 空白埋込み

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

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

出力ホスト変数では、ダブルバイトの空白文字で空白が埋め込まれます。

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

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

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

3.10.7 インジケータ変数

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

3.11 同時接続

Oracleプリコンパイラでは、SQL*Netを介して分散処理がサポートされます。アプリケーションは、ローカル・データベースおよびリモート・データベースの任意の組合せに同時にアクセスしたり、同じデータベースへの複数の接続を確立できます。図3-2では、アプリケーション・プログラムが1つのローカルOracleデータベースおよび3つのリモートOracleデータベースと通信しています。ORA2、ORA3およびORA4は、CONNECT文で使用される論理名です。

図3-2 SQL*Netを介した接続

図3-2の説明が続きます
「図3-2 SQL*Netを介した接続」の説明

SQL*Netは、異なるマシンやオペレーティング・システム間に存在するネットワーク上の境界を排除することにより、Oracleのツールに分散処理環境を提供します。この項では、SQL*Netを介した分散処理がOracleプリコンパイラでどのようにサポートされているかを説明します。さらに、アプリケーションで次の処理がどのように行われるかも学習します。

  • 他のデータベースへの直接または間接アクセス

  • ローカルおよびリモート・データベースの任意の組合せへの同時アクセス

  • 同じデータベースへの複数接続

3.11.1 予備知識

ネットワーク上の通信ポイントは、ノードと呼ばれます。SQL*Netにより、ネットワーク上のノード間で情報(SQL文、データおよびステータス・コード)を送信できます。

プロトコルは、ネットワークへのアクセスに関する一連の規則です。この規則では、障害発生後のリカバリ手順、データを送信およびエラー検査の形式などが規定されます。

ローカル・ドメイン内のデフォルトのデータベースに接続するためのSQL*Netの構文で使用するのは、そのデータベースのサービス名のみです。

サービス名がデフォルト(ローカル)・ドメイン内にない場合は、グローバル指定(すべてのドメインの指定)を使用する必要があります。次に例を示します。

HR.XX.ORACLE.COM

3.11.2 デフォルトのデータベースおよび接続

各ノードにはデフォルトのデータベースがあります。CONNECT文でノードを指定し、データベースを指定しない場合、指定したローカルまたはリモート・ノード上のデフォルトのデータベースに接続されます。データベースもノードも指定しない場合は、現在のノード上のデフォルト・データベースに接続されます。CONNECT文でデフォルト・データベースと現在のノードを指定することはできますが、必要ありません。

デフォルトの接続は、AT句のないCONNECT文を使用して行われます。ローカルまたはリモートの任意のノード上のデフォルトまたは非デフォルトの任意のデータベースに接続できます。AT句のないSQL文は、デフォルトの接続に対して実行されます。逆に、非デフォルトの接続は、AT句があるCONNECT文により行われます。AT句があるSQL文は、非デフォルトの接続に対して実行されます。

すべてのデータベース名は一意である必要があります。ただし、2つ以上のデータベース名で同じ接続を指定できます。つまり、任意のノード上で、任意のデータベースに対する複数の接続を持てます。

3.11.3 明示的接続

通常、Oracleへの接続は次のように行います。

EXEC SQL CONNECT :userid IDENTIFIED BY :password

または、次の文でも接続できます。

EXEC SQL CONNECT :usr_pwd; 

usr_pwdには、username/passwordが含まれます。

次のようにして自動的に接続することもできます。データベースおよびノードを指定しない場合、現在のノード上のデフォルトのデータベースに接続されます。別のデータベースに接続する場合は、そのデータベースを明示的に指定する必要があります。

明示的接続では、SQL文で参照される接続名を指定して、別のデータベースに直接接続します。同時に複数のデータベースに接続することも、同じデータベースに複数回接続することもできます。

3.11.4 単一の明示的接続

次の例では、リモート・ノードにある1つの非デフォルト・データベースに接続します。

ノート:

この機能を簡単に説明するために、この例では、デプロイされたシステムで通常使用されるパスワード管理手法を実行していません。本番環境では、Oracle Databaseのパスワード管理ガイドラインに従い、サンプル・アカウントを無効にしてください。パスワード管理ガイドラインおよびその他のセキュリティ上の推奨事項については、『Oracle Databaseセキュリティ・ガイド』を参照してください。

-- Declare necessary host variables.
EXEC SQL BEGIN DECLARE SECTION;
 username CHARACTER(10);
 password CHARACTER(10);
 db_string CHARACTER(20);
EXEC SQL END DECLARE SECTION;
set username = 'scott';
set password = 'tiger';
set db_string = 'd:newyork-nondef';
-- Assign a unique name to the database connection.
EXEC SQL DECLARE db_name DATABASE;
-- Connect to the nondefault database
EXEC SQL CONNECT :username IDENTIFIED BY :password
 AT db_name USING :db_string;

この例の識別子は、次の目的で使用されています。

  • ホスト変数usernameおよびpasswordは、有効なユーザーを識別します。

  • ホスト変数db_stringには、DECnetプロトコルを使用してリモート・ノードにある非デフォルトのデータベースに接続するためのSQL*Net構文が含まれています。

  • 未宣言の識別子db_nameは、非デフォルト接続の名前を指定します。これは、Oracleで使用される識別子で、ホスト変数でもプログラム変数でもありません

USING句では、db_nameに関連付けられるネットワーク、コンピュータおよびデータベースを指定します。その後、AT句(db_name付き)を使用したSQL文が、db_stringに指定したデータベースで実行されます。

もう1つの方法として、次の例に示すように、AT句で文字ホスト変数を使用できます。

EXEC SQL BEGIN DECLARE SECTION;
 username CHARACTER(10);
 password CHARACTER(10);
 db_name CHARACTER(10);
 db_string CHARACTER(20);
EXEC SQL END DECLARE SECTION;
set username = 'scott';
set password = 'tiger';
set db_name = 'oracle1';
set db_string = 'd:newyork-nondef';
-- connect to the nondefault database
EXEC SQL CONNECT :username IDENTIFIED BY :password
 AT :db_name USING :db_string;
...

db_nameがホスト変数の場合、DECLARE DATABASE文は不要です。db_nameが未宣言の識別子である場合にのみ、CONNECT ... AT db_name文を実行する前に、DECLARE db_name DATABASE文を実行する必要があります。

SQL操作。権限を付与されている場合は、非デフォルトの接続で任意のSQL DML文を実行できます。たとえば、次のように入力します。

EXEC SQL AT db_name SELECT ...
EXEC SQL AT db_name INSERT ...
EXEC SQL AT db_name UPDATE ...

次の例では、db_nameはホスト変数です。

EXEC SQL AT :db_name DELETE ...

db_nameがホスト変数の場合、SQL文で参照されるすべてのデータベース表を、DECLARE TABLE文で定義する必要があります。

カーソルの制御。OPEN, FETCHやCLOSEなどのカーソル制御文は例外で、AT句を使用しません。カーソルを明示的に指定したデータベースに関連付ける場合は、次のようにDECLARE CURSOR文でAT句を使用してください。

EXEC SQL AT :db_name DECLARE emp_cursor CURSOR FOR ...
EXEC SQL OPEN emp_cursor ...
EXEC SQL FETCH emp_cursor ...
EXEC SQL CLOSE emp_cursor;

db_nameがホスト変数の場合、宣言されたカーソルを参照するすべてのSQL文の適用範囲内で宣言する必要があります。たとえば、あるサブプログラム内でカーソルをオープンし、別のサブプログラムでそのカーソルからフェッチする場合は、db_nameをグローバルに宣言するか、それを各サブプログラムに渡す必要があります。

カーソルからのオープン、クローズまたはフェッチには、AT句は使用しません。SQL文は、DECLARE CURSOR文のAT句で名前を付けられたデータベースか、カーソルの宣言でAT句が使用されていない場合はデフォルトのデータベースにおいて実行されます。

AT :host_variable句を使用すると、カーソルに関連付けられた接続を変更できます。ただし、カーソルがオープンされているときは対応付けを変更できません。次の例を検討してください:

EXEC SQL AT :db_name DECLARE emp_cursor CURSOR FOR ...
set db_name = 'oracle1';
EXEC SQL OPEN emp_cursor;
EXEC SQL FETCH emp_cursor INTO ...
set db_name = 'oracle2';
EXEC SQL OPEN emp_cursor; -- illegal, cursor still open
EXEC SQL FETCH emp_cursor INTO ...

これは不適切です。2番目のOPEN文を実行しようとしても、 emp_cursor がまだオープン状態であるためです。異なる接続に対して別々のカーソルが維持されることはありません。emp_cursorは1つのみ存在できます。別の接続のために再オープンするには、その前にクローズする必要があります。最後の例をデバッグするには、次のように、単にカーソルをクローズしてから再オープンします。

EXEC SQL CLOSE emp_cursor; -- close cursor first
set db_name = 'oracle2';
EXEC SQL OPEN emp_cursor;
EXEC SQL FETCH emp_cursor INTO ...

動的SQL。動的SQL文は、文中ではAT句が使用されないカーソル制御文に類似しています。動的SQL方法1では、非デフォルトの接続で文を実行する場合は、AT句を使用する必要があります。次に例を示します。

EXEC SQL AT :db_name EXECUTE IMMEDIATE :sql_stmt;

方法2、3および4では、非デフォルト接続で文を実行する場合、DECLARE STATEMENT文でのみAT句を使用します。PREPARE、DESCRIBE、OPEN、FETCHおよびCLOSEなど、その他の動的SQL文はAT句を使用しません。次の例は、方法2を示しています。

EXEC SQL AT :db_name DECLARE sql_stmt STATEMENT;
EXEC SQL PREPARE sql_stmt FROM :sql_string;
EXEC SQL EXECUTE sql_stmt;

次の例は方法3を示します。

EXEC SQL AT :db_name DECLARE sql_stmt STATEMENT;
EXEC SQL PREPARE sql_stmt FROM :sql_string;
EXEC SQL DECLARE emp_cursor CURSOR FOR sql_stmt;
EXEC SQL OPEN emp_cursor ...
EXEC SQL FETCH emp_cursor INTO ...
EXEC SQL CLOSE emp_cursor;

複数の接続を同時にオープンする場合(アクティブな接続の識別にAT句が必要)でなければ、リモート・データベースに接続する際にAT句を使用する必要はありません。リモート・データベースにデフォルト接続を行うには、次の構文を使用します。

EXEC SQL CONNECT :username IDENTIFIED BY :password
 USING :db-string;

3.11.5 複数の明示的接続

単一の明示的接続の場合と同様に、複数の明示的接続にもAT db_name句を使用できます。次の例では、2つの非デフォルト・データベースに同時に接続しています。

EXEC SQL BEGIN DECLARE SECTION;
 username CHARACTER(10);
 password CHARACTER(10);
 db_string1 CHARACTER(20);
 db_string2 CHARACTER(20);
EXEC SQL END DECLARE SECTION;
...
set username = 'scott';
set password = 'tiger';
set db_string1 = 'New_York';
set db_string2 = 'Boston';
-- give each database connection a unique name
EXEC SQL DECLARE db_name1 DATABASE;
EXEC SQL DECLARE db_name2 DATABASE;
-- connect to the two nondefault databases
EXEC SQL CONNECT :username IDENTIFIED BY :password
 AT db_name1 USING :db_string1;
EXEC SQL CONNECT :username IDENTIFIED BY :password
 AT db_name2 USING :db_string2;

未宣言識別子db_name1およびdb_name2は、2つの非デフォルト・ノードにあるデフォルト・データベースの指名に使用され、これにより、SQL文では後からそれらのデータベースを名前で参照できます。

または、次の例のように、AT句でホスト変数を使用できます。

EXEC SQL BEGIN DECLARE SECTION;
 username CHARACTER(10);
 password CHARACTER(10);
 db_name CHARACTER(10);
 db_string CHARACTER(20);
EXEC SQL END DECLARE SECTION;
...
set username = 'scott';
set password = 'tiger';
FOR EACH nondefault database
 -- get next database name and SQL*Net string
 display 'Database Name? ';
 read db_name;
 display 'SQL*Net String? ';
 read db_string;
 -- connect to the nondefault database
 EXEC SQL CONNECT :username IDENTIFIED BY :password
 AT :db_name USING :db_string;
ENDFOR;

この方法を使用すれば、次の例のように、同じデータベースに複数の接続を行うこともできます。

set username = 'scott';
set password = 'tiger';
set db_string = 'd:newyork-nondef';
FOR EACH nondefault database
 -- get next database name
 display 'Database Name? ';
 read db_name;
 -- connect to the nondefault database
 EXEC SQL CONNECT :username IDENTIFIED BY :password
 AT :db_name USING :db_string;
ENDFOR;

複数の接続に同じSQL*Net文字列を使用する場合でも、接続ごとに異なるデータベース名を使用する必要があります。

3.11.6 暗黙的接続

暗黙的接続は、明示的接続の不要なOracleの分散データベース・データベース・オプションによりサポートされています。たとえば、分散問合せを使用すると、1つのSELECT文で1つ以上の非デフォルト・データベースにアクセスできます。

分散問合せ機能はデータベース・リンクに依存しており、リンクにより接続事態ではなく、CONNECT文に名前が割り当てられます。実行時には、指定したOracleサーバーにより埋込みSELECT文が実行され、非デフォルトのデータベースに暗黙的に接続されて、必要なデータが取得されます。

3.11.7 単一の暗黙的接続

次の例では、1つの非デフォルト・データベースに接続します。まず、プログラムでは次の文が実行され、データベース・リンクが定義されます(通常、データベース・リンクは、DBAまたはユーザーが対話形式で確立します)。

EXEC SQL CREATE DATABASE LINK db_link
 CONNECT TO username IDENTIFIED BY password
 USING 'd:newyork-nondef';

これにより、プログラムでは、次のようにデータベース・リンクを使用して、非デフォルトのEMP表に対して問合せを実行できます。

EXEC SQL SELECT ENAME, JOB INTO :emp_name, :job_title
 FROM emp@db_link
 WHERE DEPTNO = :dept_number;

データベース・リンクは、埋込みSQL文のAT句に使用されるデータベース名とは無関係です。単にOracleに非デフォルトのデータベースの位置、データベースへのパス、使用するOracleユーザー名およびパスワードを指示します。データベース・リンクは、明示的に削除されるまで、データベース・ディクショナリに格納されます。

例では、デフォルトのOracleサーバーは、データベース・リンクdb_linkを使用してSQL*Netで非デフォルトのデータベースに接続します。問合せはデフォルトのサーバーに送信されますが、非デフォルトのデータベースに転送されて実行されます。

データベース・リンクをさらに簡単に参照できるようにするには、次のようにシノニムを作成します(ここでも、通常は対話形式で行われます)。

EXEC SQL CREATE SYNONYM emp FOR emp@db_link;

その結果、プログラムで、次のように非デフォルトのEMP表に問合せができるようになります。

EXEC SQL SELECT ENAME, JOB INTO :emp_name, :job_title
 FROM emp
 WHERE DEPTNO = :dept_number;

これにより、empの場所を意識する必要はなくなります。

3.11.8 複数の暗黙的接続

次の例では、2つの非デフォルト・データベースに同時に接続します。まず、次の一連の文を実行し、2つのデータベース・リンクを定義して、2つのシノニムを作成します。

EXEC SQL CREATE DATABASE LINK db_link1
 CONNECT TO username1 IDENTIFIED BY password1
 USING 'd:newyork-nondef';
EXEC SQL CREATE DATABASE LINK db_link2
 CONNECT TO username2 IDENTIFIED BY password2
 USING 'd:chicago-nondef';
EXEC SQL CREATE SYNONYM emp FOR emp@db_link1;
EXEC SQL CREATE SYNONYM dept FOR dept@db_link2;

その結果、プログラムで、次のように非デフォルトのEMP表とDEPT表に問合せができるようになります。

EXEC SQL SELECT ENAME, JOB, SAL, LOC
 FROM emp, dept
 WHERE emp.DEPTNO = dept.DEPTNO AND DEPTNO = :dept_number;

Oracleでは、db_link1にある非デフォルトのEMP表とdb_link2にある非デフォルトのDEPT表を結合することにより、問合せが実行されます。

3.12 Oracle Call Interface(OCI)コールの埋込み

Oracleプリコンパイラを使用すれば、ホスト・プログラムにOCIコールを埋め込むことができます。それには次のステップを実行します。

  1. OCIログイン・データ領域(LDA)を宣言部の外で宣言します。
  2. OCIコールOLOGではなく、埋込みSQL文CONNECTを使用してOracleに接続します。
  3. Oracleランタイム・ライブラリ・ルーチンSQLLDAをコールして、LDAに接続情報を格納します。

こうして、OracleプリコンパイラとOCIでは、両者が連動していることが認識されます。ただし、Oracleカーソルは共有されません。

Oracleランタイム・ライブラリにより接続が管理され、HDAがメンテナンスされるため、OCIホスト・データ領域(HDA)の宣言を意識する必要はありません。

3.12.1 LDAの設定について

OCIコールを発行してLDAを設定します。

SQLLDA(lda);

ldaでは、LDAデータ構造体を指定します。このコールの書式は、言語によって異なります。CONNECT文が失敗した場合、lda内のlda_rcフィールドはエラーを示す1012に設定されます。

3.12.2 リモートの複数接続

SQLLDAに対するコールにより、最後に実行されたSQL文で使用した接続のLDAが設定されます。追加の接続に必要な別のLDAを設定するには、各CONNECTの後に別のldaを指定してSQLLDAをコールしてください。次の例では、2つの非デフォルト・データベースに同時に接続します。

EXEC SQL BEGIN DECLARE SECTION;
 username CHARACTER(10);
 password CHARACTER(10);
 db_string1 CHARACTER(20);
 db_string2 CHARACTER(20);
EXEC SQL END DECLARE SECTION;
lda1 INTEGER(32);
lda2 INTEGER(32);
set username = 'SCOTT';
set password = 'TIGER';
set db_string1 = 'D:NEWYORK-NONDEF1';
set db_string2 = 'D:CHICAGO-NONDEF2';
-- give each database connection a unique name
EXEC SQL DECLARE db_name1 DATABASE;
EXEC SQL DECLARE db_name2 DATABASE;
-- connect to first nondefault database
EXEC SQL CONNECT :username IDENTIFIED BY :password
 AT db_name1 USING :db_string1;
-- set up first LDA for OCI use
SQLLDA(lda1);
-- connect to second nondefault database
EXEC SQL CONNECT :username IDENTIFIED BY :password
 AT db_name2 USING :db_string2;
-- set up second LDA for OCI use
SQLLDA(lda2);

db_name1およびdb_name2は、ホスト変数ではないので、宣言部で宣言しないでください。これらは、後からSQL文で名前によりデータベースを参照できるように、2つの非デフォルト・ノードにあるデフォルト・データベースを指定する場合にのみ使用します。

3.13 X/Openアプリケーションの開発について

X/Openアプリケーションは、分散トランザクション処理(DTP)環境で動作します。抽象モデルでは、X/Openアプリケーションはリソース・マネージャ(RM)に各種サービスの提供を要求します。たとえば、データベース・リソース・マネージャは、データベース内のデータにアクセスします。リソース・マネージャは、アプリケーションのすべてのトランザクションを制御するトランザクション・マネージャ(TM)と対話します。

図3-3では、DTPモデルのコンポーネントで、Oracleデータベース内のデータに効率的にアクセスするために対話できる方法を示しています。このDTPモデルでは、リソース・マネージャとトランザクション・マネージャの間にXAインタフェースが指定されています。Oracleでは、XA準拠のライブラリが提供され、このライブラリは、X/Openアプリケーションにリンクさせる必要があります。また、アプリケーション・プログラムとリソース・マネージャ間でネイティブ・インタフェースを指定する必要もあります。

図3-3 DTPの仮想モデル

図3-3の説明が続きます
「図3-3 DTPの仮想モデル」の説明

トランザクション・マネージャとリソース・マネージャがアプリケーション・プログラムと対話する方法を指定するこのDTPモデルについては、X/Openガイド『Distributed Transaction Processing Reference Model』および関連出版物にで説明されていますが、これらは次の宛先に書面で請求すれば入手できます。

X/Open Company Ltd.1010 El Camino Real, Suite 380Menlo Park, CA 94025

XAインタフェースの使用方法は、ご使用のトランザクション処理(TP)モニターのユーザー・ガイドを参照してください。

3.13.1 Oracle固有の問題

Oracleプリコンパイラを使用して、X/Open規格に準拠したアプリケーションを開発できます。ただし、次の要件を満たす必要があります。

3.13.2 Oracleへの接続について

X/Openアプリケーションでは、データベースへの接続の確立およびメンテナンスは行われません。かわりに、Oracleにより提供されるトランザクション・マネージャとXAインタフェースにより、データベースの接続および切断が透過的に処理されます。したがって、通常、X/Open準拠のアプリケーションでは、CONNECT文は実行されません。

3.13.3 トランザクション制御

X/Openアプリケーションでは、グローバル・トランザクションに影響を与えるCOMMITROLLBACKSAVEPOINTおよびSET TRANSACTIONなどの文を実行しないでください。たとえば、コミットはトランザクション・マネージャで処理されるため、アプリケーションではCOMMIT文を実行しないでください。また、CREATEALTERおよびRENAMEなどのSQLデータ定義文では暗黙的なコミットが発行されるため、アプリケーションでこれらの文を実行しないでください。

アプリケーションでは、さらなるSQL操作を妨げるエラーが検出された場合、内部のROLLBACK文を実行できます。ただし、今後リリースされるXAインタフェースでは、変更される可能性もあります。

3.13.4 OCIコール

X/OpenアプリケーションでOCIコールを発行する場合は、ランタイム・ライブラリ・ルーチンSQLLD2を使用する必要があります。このルーチンにより、XAインタフェースを通じて確立された指定の接続のために、LDAが設定されます。OCOM、OCON、OCOF、ORLON、OLON、OLOGおよびOLOGOFは、X/Openアプリケーションからは発行できません。

3.13.5 リンク

XA機能を利用するには、XAライブラリをX/Openアプリケーション・オブジェクト・モジュールにリンクさせる必要があります。手順は、使用しているシステム固有のOracleマニュアルを参照してください。