7 Oracle Database Provider for DRDAでのデータ型のサポートと変換
Oracleでのデータ型のサポートと、OracleとDRDAの間でのデータ型の変換について説明します。
7.1 データ変換の概要
DRDAではデータ型のエンコーディングに定様式データ・オブジェクト・コンテンツ体系(FD:OCA)が使用されます。いくつかの型はOracleネイティブの型に類似していないため、変換が必要です。また、一部のOracleデータ型ではFD:OCAで直接エンコーディングがサポートされていません。たとえばOracle NUMBERの場合、整数および浮動小数点の両方を含む様々な値が含まれている可能性があります。この二重性が原因で、特定のDRDA型へマップして数値の値の損失を緩和できません。どの型を選択する場合でも、値の末端範囲で精度またはスケールのいずれかがある程度失われます。
Oracle Database Provider for DRDAで使用されるデータ型変換には、DRDAメタデータ記述子からOracle OCIインタフェースの型への変換と、Oracle列型からDRDAメタデータ記述子への変換の2種類があります。アプリケーション・プログラマの方向けに、これらについてバインド変数のSQL型または記述されている列型で説明します。「DRDAデータ型からOracleデータ型への変換」および「Oracleデータ型からDRDAへの変換」を参照してください。
Oracle NUMBERの一般的なマッピング・メカニズムについては、「データ型の対応および再マッピング」を参照してください。
7.2 数値範囲に関する考慮事項: 全般
Oracle NUMBER、IEEE浮動小数点、IBM 16進浮動小数点(HEX浮動小数点、S390またはSystem390浮動小数点)、10進数浮動小数点(DECFLOAT)の各データ型間の変換時には、各データ型の範囲と特性が異なることに注意してください。たとえば、クライアント側プログラムのIBM HEX FLOATバインド変数のすべての値はOracle NUMBERに適合しますが、Oracle NUMBERの一部の値はIBM HEX FLOATでは正しく戻されません。この場合はDECFLOAT34のほうが適切です。
その他の考慮事項は次のとおりです。
-
無限大。一部の浮動小数点型は正の無限大と負の無限大をサポートしています。
無限大をサポートしていないデータ型で無限大が使用されると、正の無限大の場合は最大許容値が使用され、負の無限大の場合は負の最大許容値が使用されます。
-
浮動小数点。IEEE
FLOAT列は、OracleではBINARY_FLOAT型およびBINARY_DOUBLE型を使用して定義できます。DB2 z/OSでは、浮動小数点型(REAL、FLOAT、DOUBLE、DOUBLE PRECISION)は、IBM HEX浮動小数点です。DB2/400およびDB2 LUWでは、浮動小数点型(REAL、FLOAT、DOUBLE、DOUBLE PRECISION)はIEEE浮動小数点です。 -
非数。一部のデータ型では非数(Not A Number (NAN))がサポートされています。非数は、値が割り当てられていないこと、または計算結果が無効または未定義であることを示す特殊な値です。
7.2.1 Oracle NUMBER
Oracle NUMBERの特性は次のとおりです。
下限
1E-130
上限
9.999 999 999 999 999 999 999 999 999 999 999 999 9E+125
無限大
負の無限大および正の無限大の両方がサポートされています。
非数
サポートされていません。
7.2.2 FLOAT (IBM HEXまたはS390)
FLOAT、DOUBLEおよびLONG DOUBLEサブデータ型に適用される特性を次に示します。
範囲の下限
5.397605 x 10-79
範囲の上限
7.237005 x 10+75
無限大
サポート対象外
非数
サポート対象外
7.2.3 FLOAT (IEEE)
FLOAT (BINARY_FLOAT)、DOUBLE (Oracle BINARY_DOUBLE)およびLONG DOUBLEサブデータ型に適用される特性を次に示します。
無限大
正の無限大および負の無限大の両方がサポートされています。
非数
サポートされています。
サブタイプの範囲は次のとおりです。
範囲の下限
FLOAT (Oracle BINARY_FLOAT): 1.175 494 x 10-38
DOUBLE (Oracle BINARY_DOUBLE): 2.225 074 x 10-308
LONG DOUBLE: 3.362 103 x 10-4932
範囲の上限
FLOAT (Oracle BINARY_FLOAT): 3.402 823 x 10+38
DOUBLE (Oracle BINARY_DOUBLE): 1.797 693 x 10+308
LONG DOUBLE: 1.189 731 x 10+4932
7.2.4 DECFLOAT
DECFLOAT7、DECFLOAT16、DECFLOAT34サブデータ型に適用される特性を次に示します。
無限大
正および負の両方の無限大のサポート
非数
サポート対象
サブタイプの範囲は次のとおりです。
範囲の下限
DECFLOAT7: 0.000 001 x 10-95
DECFLOAT16: 0.000 000 000 000 001 x 10-383
DECFLOAT34: 0.000 000 000 000 000 000 000 000 000 000 001 x 10-6143
範囲の上限
DECFLOAT7: 9.999 999 x 10+96
DECFLOAT16: 9.999 999 999 999 999 x 10+384
DECFLOAT34: 9.999 999 999 999 999 999 999 999 999 999 999 x 10+6144
7.3 数値範囲に関する考慮事項: COBOLユーザー
DRDAデータベースには3つの整数型オプション(SMALLINT (2バイナリ・バイト)、INTEGER (4バイナリ・バイト)、BIGINT (8バイナリ・バイト))があります。変換時に、DB2 CREATE TABLE定義で使用されている型ではなく、使用方法に基づいて、同等の値を格納するOracle列が定義される必要があります。
DRDA SMALLINT、INTEGER、BIGINTの実際の範囲は次のとおりです。
-
SMALLINTの下限は-32,768、上限は32,767です。 -
INTEGERの下限は-2,147,483,648、上限は2,147,483,647です。 -
BIGINTの下限は-9,223,372,036,854,775,808、上限は9,223,372,036,854,775,807です。
ただしアプリケーション・レベルでは、これらのDRDA列値を維持するCOBOL変数を宣言するときには、一定の桁数または対応するDRDA整数データ型のフル・バイナリ精度のいずれかを使用ます。
COBOLでは、同等のバイナリ整数データ型が次のように定義されます。
-
USAGE:BINARY、COMPUTATIONALCOMP、COMPUTATIONAL-4、COMP-4。これらは同等です。 -
PICTURE:S9(1-4)(2バイト整数)、S9(5-9)(4バイト整数)、S9(10-18)(8バイト整数)
通常、値はPICTUREの桁数に制限されます。
たとえばPICTURE S9(4) COMPは、通常-32,768から+32,767までの範囲の2バイト整数です。ただし、生成されるCOBOLコードでは、-9,999から+9,999までの範囲の値のみが許容されます。DRDA SMALLINT、INTEGERおよびBIGINT型の列へのアクセスおよびこれらの更新の目的でのみこれらの型のバインド変数を使用する場合は、Oracleで列をNUMBER(n)として定義します(nは前述のPICTURE S9(n)定義に一致します)。
COBOLコンパイラ・オプションTRUNC(BIN)で、BINARY、COBOL変数COMPUTATIONAL、COMP、COMPUTATIONAL-4、COMP-4を使用する場合、バイナリ整数の範囲はデータ型の範囲全体になる可能性があります。TRUNCコンパイラ・オプションが有効になっているかどうかに関係なく、COMPUTATIONAL-5とCOMP-5のいずれを使用しても効果は同じです。2進整数の全範囲を使用してCOBOL、C、PL/Iまたはアセンブラでプログラミングする場合は、Oracle列をNUMBER(n+1)として定義します(nは、前述のPICTURE S9(n)に対応します)。
DRDAのデータ型と使用方法に基づいて推奨される代替Oracleデータ型を次に示します。
COBOL COMPで使用されている場合:
-
SMALLINTはOracleNUMBER(4)に変換する必要があります。 -
INTEGERはOracleNUMBER(9)に変換する必要があります。 -
BIGINTはOracleNUMBER(18)に変換する必要があります。
COBOL COMP、TRUNC(BIN)、COMP-5、C、PL/Iまたはアセンブラの2進整数変数で使用される場合:
-
SMALLINTはOracleNUMBER(5)に変換する必要があります。 -
INTEGERはOracleNUMBER(10)に変換する必要があります。 -
BIGINTはOracleNUMBER(19)に変換する必要があります。
7.3.1 Oracle NUMBERの制約
2進整数値の全範囲を使用する場合は、Oracleの制約を実装し、対応するデータ型の範囲に値を制限することをお薦めします。
たとえばDRDA SMALLINTの場合、例7-1に示すように、SMALLINT値の全範囲のみをサポートする同等のOracle NUMBER列になります。
ただし、このタイプのチェック制約を指定するとパフォーマンスが低下することに注意してください。Oracleは、列が更新されるたびにすべての制約を検証します。
例7-1 DRDA SMALLINTに正確に対応させるためのOracle NUMBERの制約
CREATE TABLE smint_tab (smint NUMBER(5) CONSTRAINT check_smallint CHECK (smint BETWEEN -32768 AND 32767) )
7.4 DRDAデータ型からOracleデータ型への変換
DRDAデータ型とOracleデータ型の間のマッピングについて説明します。
次の略語に注意してください。
-
シングルバイト文字セット(SBCS)の場合、列にはシングルバイト・データのみを格納できます。
-
マルチバイト文字セット(MBCS)の場合、列にはシングルバイト文字とマルチバイト文字の組合せを格納できます。
7.5 Oracleデータ型からDRDAへの変換
表とプロシージャではOracleデータ型が使用されます。オブジェクトを記述するとき、または表やプロシージャからデータを戻すときに、Oracleデータ型が同等のDRDAデータ型にマッピングされます。
7.5.4 LONG
混合型の長い可変長文字列。Oracle LONGでは2^31-1バイトまでサポートされますが、現時点では、最初の32,767バイトのみが戻されます。
SQL型
448, 449
SQL型名
VARCHAR(32767) FOR MIXED DATA
7.5.5 LONG RAW
バイナリ型の長い可変長文字列。Oracle LONG RAWでは2^31-1バイトまでサポートされますが、現時点では、最初の32,767バイトのみが戻されます。
SQL型
448, 449
SQL型名
VARCHAR(32767) FOR BIT DATA
7.5.7 CHAR(n)
混合固定長文字列。2の可能性、データ型に必要な範囲に応じて2つのデータ型のいずれかに変換されます。nが256未満の場合はCHAR(n)、これより長い文字列の場合はVARCHAR(n)に変換されます。
7.5.8 NCHAR(n)
各国語固定長文字列。データ型に必要な範囲に応じて2種類の変換のいずれかが行われます。nが256未満の場合はCHAR(n)、これよりも長い文字列の場合はVARCHAR(n)に変換されます。
7.5.12 TIMESTAMPWITHLOCALTIMEZONE
Oracle TIMESTAMP WITH LOCAL TIME ZONE
SQL型
392, 393
SQL型名
TIMESTAMP
7.5.13 TIMESTAMP(p) WITH TIME ZONE
Oracle TIMESTAMP WITH LOCAL TIME ZONE
SQL型
448, 449
範囲
0 ≤ p ≤ 9
SQL型名
VARCHAR(n) FOR MIXED DATA
TIMESTAMP(0) WITH TIME ZONEの場合はn=148、TIMESTAMP(p) WITH TIME ZONEの場合は149+p
7.5.15 NUMBERおよびFLOAT
Oracle NUMBERおよびFLOATは、様々な数値型を表現するために使用されます。
-
10進精度のみを使用する単純な整数型
-
特定の精度とスケールを使用する固定小数点型
-
最大
38桁までの精度および指数を持つ浮動小数点型
NUMBERは、精度より大きなスケールまたは負のスケールを使用して定義するか、または2進精度を持つFLOATとして定義できます。詳細は、表7-1および表7-2を参照してください。
このデータ型の一般的な形式は、NUMBER(p,s)です。pは精度の変数、sはスケールの変数です。
表7-1 Oracle NUMBERバリアントからDRDAデータ型への変換
| Oracle NUMBER(p,s)のバリアント | DRDAデータ型 | 注 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
クライアントで |
|
|
|
|
|
|
|
両方のデータ型で |
|
|
|
クライアントで Oracle |
|
ここではスケールが負数です。 |
|
クライアントで Oracle |
|
ここではscale > precisionです。 |
|
クライアントが Oracle |
|
任意のスケール |
|
クライアントが Oracle |
|
|
|
クライアントで |
表7-2 Oracle FLOATバリアントからDRDAデータ型への変換
| Oracle FLOAT(n)のバリアント | DRDAデータ型 | 注意 |
|---|---|---|
|
|
|
クライアントが |
|
ここでは |
|
クライアントが |
|
|
|
クライアントが |
7.6 データ型の対応および再マッピング
Oracleには、DRDAデータ型SMALLINT、INTEGER、BIGINTのような個別のデータベース・データ型はありません。場合によっては、列の値範囲を制限するために、特定の精度またはスケールを使用して数値列を定義することが必要となります。そのため、柔軟性が高い数値データベース・データ型としてOracle NUMBERが用意されています。このデータ型は、精度とスケールを指定して定義します。特定の範囲制限が列に対して定義されていない場合、Oracle NUMBERではその列に整数値と小数値が含まれることがあります。
したがって、Oracle以外のデータベースからデータを移行するときには、適切なデータベース・データ型を検討する必要があります。これは特に、限られた範囲または形式のデータを処理するアプリケーションを移行する場合に重要です。
たとえば、NUMBER(5)に固有のデータ範囲がアプリケーションで受け入れられるが、列はデータ型NUMBERで定義されている場合、列に不適切な値または無効な値が挿入され、その値を使用または取得するときにデータの問題が発生する可能性があります。
表の定義が元のOracle以外のデータの近似値にマップされている場合、データ型の互換性の問題は発生しません。ただし、正確にモデル化されていないデータにアクセスする必要がある場合や、範囲制限されていないデータ型を生成する式を問合せで使用する場合には、互換性が高い代替データ型を適用する必要があります。
COUNT(*)式の結果、範囲が限定されていないOracle NUMBERデータ型が生成されることを考慮してください。COUNTを使用する問合せの結果をDRDA INTEGERデータ型として表す必要があるアプリケーションの場合、型の不一致を防ぐために、次のいずれかの操作を実行する必要があります。
-
Oracle
NUMBERを使用するようにアプリケーションを変更する。 -
結果を適切な形式に
CASTするように、問合せ式を変更する。 -
結果のデータ型の形式を再マップする。
多くの場合、アプリケーションの変更が現実的でも実現可能でもなく、データ型の再マップが唯一の有効な解決策となります。
アプリケーション・サーバーでは、表単位または列単位でOracle NUMBERデータ型の結果を同等の個別のDRDAデータ型に変換できる機能が限られています。このメカニズムは、クライアントのARがOracle NUMBERからDRDAデータ型へのデフォルト・マッピングを適切に変換できない場合にも使用できます。サポートされているすべての変換については「Oracleデータ型からDRDAへの変換」を参照してください。
関連トピック
7.6.1 データ型マッピングの適用
データ型マッピングを適用するには、PL/SQLファンクションを起動する必要があります。SET_TYPEMAPの項を参照してください。プロシージャSET_TYPEMAPは、指定された表および列式に対して指定された型変換マップを実装します。型マップ・オブジェクト名の構文は、table_name:column_expressionです。すべての表と指定した列式をインクルードするには、表名の位置にワイルドカード文字(*)を使用できます。また、Oracle NUMBERに評価される、指定された表のすべての列式が、型にマップされることを示す場合にも使用できます。
Oracle NUMBERから別のデータ型への変換の構文は、NUMBER=datatypeです。使用可能なデータ型の名前については、「Oracle NUMBER TYPEMAPデータ型の名前」を参照してください。
デフォルトではOracle NUMBERはDRDA DECFLOAT(34)にマッピングされます。「列を直接使用する問合せでのTYPEMAPの使用」に、列を直接使用する問合せで、取得した列をDRDAのINTEGER型として再マッピングできることを示しています。ファンクションで列を使用する際には、場合によっては式にtypemapを適用する必要があります。詳細は、「ファンクションでのTYPEMAPの使用」を参照してください。
関連トピック
7.6.2 問合せでのTYPEMAPの使用
アプリケーションで、EMPLOYEE_IDの値がDRDAのINTEGER型の形式である必要があるとします。
例7-2 列を直接使用する問合せでのTYPEMAPの使用
CREATE TABLE employees(employee_id NUMBER(6), first_name VARCHAR2(20), ...);
このマッピングでは範囲制限が適用されます。このマッピングを容易にするため、アプリケーション・パッケージORACLE.MYPACKAGEに次のtypemapエントリを適用します。
begin dbms_drdaas.set_typemap ( 'ORACLE', 'MYPACKAGE', 'EMPLOYEES:EMPLOYEE_ID', 'NUMBER=INTEGER'); end;
7.6.3 ファンクションでのTYPEMAPの使用
次のように列に対してCOUNTファンクションを使用するとします。
例7-3 ファンクションでのTYPEMAPの使用
SELECT COUNT(employee_id) FROM employees;
この場合は次のtypemap式を適用します。
begin dbms_drdaas.set_typemap ( 'ORACLE', 'MYPACKAGE', 'EMPLOYEES:COUNT(EMPLOYEE_ID)', 'NUMBER=INTEGER' ); end;
7.6.4 Oracle NUMBER TYPEMAP
表7-3に、使用可能なtypemapの名前とDRDAデータ型への変換を示します。
表7-3 Oracle NUMBER TYPEMAPデータ型の名前
| データ型の名前 | SQL型 | データ型のサイズ | 注意 |
|---|---|---|---|
|
|
500, 501 |
|
単精度整数 |
|
|
496, 497 |
|
整数 |
|
|
492, 493 |
|
長精度整数 |
|
|
480. 481 |
|
単精度浮動小数点 |
|
|
480, 481 |
|
倍精度浮動小数点 |