| Oracle Database アプリケーション開発者ガイド-基礎編 10gリリース2(10.2) B19248-02 |
|
この章では、データベース・アプリケーションにおけるSQLデータ型の使用方法について説明します。内容は次のとおりです。
データ型は、ある限定されたプロパティの集合を、表の列、あるいはプロシージャまたはファンクションの引数に使用できる値と対応付けます。このプロパティの集合によって、Oracle Databaseはあるデータ型の値を別のデータ型の値とは異なるものとして扱うようになります。たとえば、Oracle Databaseは、NUMBERデータ型の値は加算できますが、RAWデータ型の値は加算できません。
Oracle Databaseには、多数の組込みデータ型と、データ型として使用できるユーザー定義型の複数のカテゴリが用意されています。Oracle Databaseでサポートされているデータ型は、次のカテゴリに分類できます。
Oracleプリコンパイラでは、埋込みSQLプログラム内の他のデータ型が認識されます。このようなデータ型は外部データ型と呼ばれ、ホスト変数に関連付けられています。Oracle Databaseの組込みデータ型およびユーザー定義型を外部データ型と混同しないでください。
この項の内容は次のとおりです。
次のSQLデータ型を使用して英数字データを格納できます。
CHARデータ型およびNCHARデータ型は、固定長文字リテラルを格納します。
VARCHAR2データ型およびNVARCHAR2データ型は、可変長文字リテラルを格納します。
NCHARデータ型およびNVARCHAR2データ型は、Unicode文字データのみを格納します。
CLOBデータ型およびNCLOBデータ型は、最大(4GB - 1) * (DBMS_LOB.GETCHUNKSIZEから取得した値)のシングルバイト文字列およびマルチバイト文字列を格納します。
LONGデータ型は、最大2GBを含む可変長文字列を格納します。ただし、多くの制限があります。このデータ型は、既存のアプリケーションとの下位互換性を保つためにのみ提供されています。通常、新しいアプリケーションで大量の文字データを格納するには、CLOBデータ型およびNCLOBデータ型を使用し、大量のバイナリ・データを格納するには、BLOBデータ型およびBFILEデータ型を使用します。CHAR列およびVARCHAR2列の長さは、バイト数または文字数として指定できます。NCHAR列およびNVARCHAR2列の長さは、必ず文字単位で指定し、1つの文字が複数バイトで構成される場合にUnicodeデータを格納するために適した長さにします。
次のリストに、列の長さを指定する際の考慮事項を示します。
id VARCHAR2(32 BYTE)id列に格納されるのは、32バイト以内のシングルバイト・データのみです。
name VARCHAR2(32 CHAR)name列には、データベース・キャラクタ・セットによるデータが格納されます。データベース・キャラクタ・セットでマルチバイト・キャラクタが許可される場合は、32文字を32バイトを超える長さで格納できます。
biography NVARCHAR2(2000)biography列では、Unicodeで表現可能な任意の言語による2000文字を表すことができます。エンコーディングは各国語キャラクタ・セットに応じて異なりますが、データベース・キャラクタ・セットがシングルバイトの場合も、列にはマルチバイト値を格納できます。
comment VARCHAR2(2000)commentが2000バイトとして表されるか2000文字として表されるかは、初期化パラメータNLS_LENGTH_SEMANTICSによって決まります。
マルチバイトのデータベース文字コード体系を使用する場合は、文字データ型の列を持つ表のために必要となる領域を慎重に検討してください。データベースの文字コード体系がシングルバイトである場合、1つの列内のバイト数と文字数は同じです。ただし、マルチバイトの場合は、通常このような対応はありません。1つの文字は、マルチバイト・コード体系と、シフトイン/シフトアウト制御コードの有無に応じて、1バイトで構成される場合と、複数バイトで構成される場合があります。バッファのオーバーフローを回避するため、データベース・キャラクタ・セットと異なるUnicodeエンコーディングを使用する可能性がある場合、データをNCHARまたはNVARCHAR2として指定します。
表の文字数字データを格納する列にどのデータ型を使用するかを決めるには、次の相違点を考慮してください。
データをより効率的に格納するには、VARCHAR2データ型を使用します。CHARデータ型ではすべての列値に空白を埋め込み、固定列長に達するまでの後続空白を格納しますが、VARCHAR2データ型では空白を追加しません。
比較セマンティクスでANSI互換性が必要な場合(文字列の比較において後続空白が重要でない(比較対象としない)場合)は、CHARデータ型を使用します。文字列の比較において後続空白が重要である(比較対象とする)場合は、VARCHAR2データ型を使用します。
CHARデータ型およびVARCHAR2データ型は、完全なサポートが保証されています。現在、VARCHARデータ型はVARCHAR2データ型と同義であるとみなされるため、将来も使用できる予定です。
アプリケーションがOracle Databaseとのインタフェースを提供する場合は、クライアント側とサーバー側にキャラクタ・セットがあります。データベース・キャラクタ・セットとユーザー・セッション用に定義されているキャラクタ・セットが異なる場合、Oracle DatabaseではNLS_LANGUAGEパラメータを使用して、CHAR、VARCHAR2およびLONGデータを前者から後者に自動的に変換します。
Oracle Databaseで文字データの比較に使用される比較セマンティクスについては、『Oracle Database SQLリファレンス』のデータ型比較ルールに関する項を参照してください。Oracle Databaseでは、CHAR列に格納されている値には空白を埋めますが、VARCHAR2列に格納された値にはこれを行わないため、VARCHAR2列に格納されている値が占有する領域は、CHAR列に格納された場合より少なくなる可能性があります。このため、VARCHAR2列のある大規模な表の全表スキャンでは、CHAR列に同じデータが格納されている表の全表スキャンより、読み込むデータ・ブロックが少なくなる可能性があります。アプリケーションが文字データを含む大規模な表に対して全表スキャンを行う場合、CHAR列よりVARCHAR2列にデータを格納することによってパフォーマンスを改善できる可能性が高くなります。
使用するデータ型を決定するときに考慮する必要がある要因は、パフォーマンスのみではありません。Oracle Databaseは、各データ型の値を比較するために異なる方法を使用します。アプリケーションがこれらの比較セマンティクスの相違に敏感な場合、特定のデータ型を選択した方がよい場合があります。たとえば、文字値の比較で、Oracle Databaseに後続空白を無視させる場合は、これらの値はCHAR列に格納する必要があります。
多くのSQL文、関数、式および条件では、文字リテラル値を指定する必要があります。文字リテラルは、次の表記法を使用して指定できます。
'users01.dbf'および'Muthu''s computer'のように、'text'表記法を使用した文字リテラル。
N'text'またはn'text'表記法を使用した各国語文字リテラル。Nまたはnは、各国語キャラクタ・セットを使用したリテラルを示します。たとえば、N'résumé'は各国語文字リテラルです。Oracle Databaseでは、N引用符付きのテキストは、データベース・キャラクタ・セットを使用して各国語キャラクタ・セットに変換されます。クライアント側キャラクタに対応するエンコーディングがデータベース・キャラクタ・セットにない場合、Oracle Databaseでは疑問符に変換されます。テキスト・リテラル変換中の潜在的なデータ消失を回避するには、$ORA_NCHAR_LITERAL_REPLACE環境変数をTRUEに設定します。この設定により、N'text'が内部で透過的に置き換えられ、テキスト・リテラルがSQL処理のために保持されます。
UNISTR関数は、UNISTR('¥1234')のように文字列で文字のUnicodeエンコーディング値を指定できるようにすることで、Unicode文字リテラルのサポートを提供します。この方法は、NCHAR列にデータを挿入する場合などに役立ちます。すべての文字には対応するUnicodeエンコーディングが存在するため、クライアント・アプリケーションではデータ消失なしで安全に文字データをサーバーに送信できます。
デフォルトでは、文字リテラルは'Hello'のように一重引用符で囲む必要があります。テキスト自体に一重引用符が含まれていると、この方法では不便です。そこで、Q引用符メカニズムも使用できます。この方法では、qまたはQ、次に一重引用符、最後に引用符のデリミタとして使用する別の文字を順番に指定します。たとえば、リテラルq'#it's the "final" deadline#'では、文字列it's the "final" deadlineの引用符デリミタとしてシャープ記号(#)を使用しています。
Q引用符デリミタには、空白、タブおよび改行を除く任意のシングルバイトまたはマルチバイト・キャラクタを使用できます。左引用符デリミタが、[、{、<または(の場合、右引用符デリミタには対応する]、}、>または)を使用する必要があります。他のすべての場合、左右のデリミタには同一文字を使用する必要があります。
次の文字リテラルには、代替引用符付けメカニズムが使用されています。
q'(name LIKE '%DBMS_%%')' q'<'Data,' he said, 'Make it so.'>' q'"name like '['"' nq'ï1234ï'
この項の内容は次のとおりです。
次のSQLデータ型は数値データを格納します。
NUMBERデータ型は、実数を固定小数点形式または浮動小数点形式で格納するために使用します。このデータ型を使用している数値は、様々なOracle Databaseプラットフォーム間で移植性があることが保証され、最大で10進数38桁の精度を提供します。1 x 10-130〜9.99 x10125の正と負の数値および0(ゼロ)を、NUMBER列に格納できます。
BINARY_FLOATデータ型およびBINARY_DOUBLEデータ型は、それぞれ32ビットIEEE 754形式、および倍精度64ビットIEEE 754形式で、浮動小数点データを格納します。浮動小数点データの算術演算は通常、Oracle NUMBERデータ型の場合と比較して、BINARY_FLOATおよびBINARY_DOUBLEデータ型で行うほうが、より高速です。また、高精度の値は、BINARY_FLOATおよびBINARY_DOUBLEとして格納するほうが、必要とする領域は少なくなります。
Oracle Databaseでサポートされているクライアント・インタフェースでは、BINARY_FLOATデータ型およびBINARY_DOUBLEデータ型の算術演算は、ハードウェアのベンダーが提供するシステム固有の命令セットによって実行されます。ネイティブ浮動小数点データ型という用語は、BINARY_FLOATおよびBINARY_DOUBLEを含むデータ型、およびサポートされているクライアント・インタフェースで実装されているこれらの型すべてを指します。
浮動小数点記数法は、コンピュータ・システムで数値を表現および操作する一般的な方法です。浮動小数点数は、次の構成要素で表現されます。
浮動小数点の値は、例3-1の算式に示すように仮数と指数乗した基数との積に符号が付いたものです。
(-1)符号 . 仮数 . 基数 指数
たとえば、数値4.31は次の式で表すことができます。
(-1)0 . 431 . 10 -2
この式の構成要素は、次のとおりです。
浮動小数点数形式は、浮動小数点数の構成要素の表記方法を指定するものです。表記方法の選択により、形式が表す値の範囲および精度が決定されます。定義上、範囲とは形式で表すことができる最小値から最大値までの間隔であり、精度とは仮数の桁数です。
浮動小数点の値の形式は、無限精度も無限範囲もサポートしていません。数値を表すのは有限値のビットであり、形式で表すことができるのは有限値の値のみです。指定された形式で使用できるよりも高い精度を使用する浮動小数点数は丸められます。
浮動小数点数は、IEEE 754標準に準拠した2進法(基数2を使用)、またはOracle NUMBERなどの10進法(基数10を使用)で表すことができます。基数は、数値を丸める方法など、形式の多くのプロパティに影響します。
Oracle NUMBERのような10進の浮動小数点数形式の場合、最も近い10進の桁に丸められます(例:1000、10または0.01)。IEEE 754形式では、浮動小数点の値に2進形式が使用され、数値は最も近い2進の桁に丸められます(1024、512または1/64など)。
データベースでサポートされているネイティブ浮動小数点データ型は、最も近い2進の桁に丸められるため、10進の桁への丸めを必要とするアプリケーションには適していません。浮動小数点データに10進の桁への丸めを必要とするアプリケーションの場合は、Oracle NUMBERデータ型を使用してください。
2進形式を使用する浮動小数点数の値は、例3-2に示す算式によって決まります。
(-1)s 2E (b0 b1 b2 ... bp-1)
表3-1 に、算式の構成要素を示します。
| 構成要素 | 指定 |
|---|---|
|
|
|
|
|
|
|
|
|
仮数の先頭のビットb0は、非正規の数値(後述)の場合を除いて、(1)に設定する必要があります。したがって、先頭のビットは実際には格納されないため、この形式では精度としてNビットを指定しますが、格納されるのはN-1ビットになります。
これらの形式のパラメータを表3-2に示します。
| パラメータ | 単精度(32ビット) | 倍精度(64ビット) |
|---|---|---|
|
|
24 |
53 |
|
|
-126 |
-1022 |
|
|
+127 |
+1023 |
形式の記憶域パラメータを表3-3に示します。単精度および倍精度データ型のメモリー内形式は、IEEE 754で指定されます。
| データ型 | 符号ビット | 指数ビット | 仮数ビット | ビット数合計 |
|---|---|---|---|---|
|
単精度 |
1 |
8 |
24(23が格納されます) |
32 |
|
倍精度 |
1 |
11 |
53(52が格納されます) |
64 |
仮数の先頭ビットが設定されている場合、仮数は正規化されます。IEEE 754では、仮数の暗黙的な先頭ビットが表せない小さい数値を、非正規として定義します。暗黙的な先頭ビットを設定して正規化すると、指数が大きくなりすぎて、数値が非常に小さくなります。IEEE 754形式では、非正規の値がサポートされています。非正規の値では、次のプロパティが保持されます。
条件: x - y == 0.0(浮動小数点減算を使用)
結果: x == y
表3-4に、IEEE 754標準で必須の形式、およびOracle NUMBERで必須の形式の範囲と精度を示します。範囲の制限は、正数に置き換えて表します。この制限は、負数の絶対値にも適用されます。(ここで使用される「数値e指数」という表記法は、指数乗した10を乗算した数値を表します。数値.10 指数。)
| 範囲および精度 | 単精度32ビット1 | 倍精度64ビット1 | Oracle NUMBERデータ型 |
|---|---|---|---|
|
正の最大正規数 |
3.40282347e+38 |
1.7976931348623157e+308 |
< 1.0e126 |
|
正の最小正規数 |
1.17549435e-38 |
2.2250738585072014e-308 |
1.0e-130 |
|
正の最大非正規数 |
1.17549421e-38 |
2.2250738585072009e-308 |
適用なし |
|
正の最小非正規数 |
1.40129846e-45 |
4.9406564584124654e-324 |
適用なし |
|
精度(10進数) |
6 - 9 |
15 - 17 |
38 - 40 |
|
1
これらの数値は、『IEEE Numerical Computation Guide』から引用されています。 |
IEEE 754では、特殊な数値を表現できます。たとえば、次に示すのは特殊な数値です。
NaNは、未定義の演算の結果を表します。IEEE 754には、NaNを表すビット・パターンが多数あります。ビット・パターンでは、符号ビット・セットを使用して、または使用せずにNaNを表すことができます。IEEE 754では、signalling NaNsとquiet NaNsが区別されます。
IEEE 754では、例外が有効および無効の場合の動作が指定されています。Oracle Databaseでは、例外の有効化は許可されません。データベースの動作は、IEEE 754で指定されている、例外が無効化されている場合の動作になります。特に、Oracle Databaseではsignalling NaNsとquiet NaNsは区別されません。OCIを使用するプログラマは、Oracle DatabaseからNaN値を取得する可能性があります。取得されるNaN値がsignalling NaNかquiet NaNかは、クライアント・プラットフォームによって決まり、Oracle Databaseの制御外のものです。
IEEE 754では、どちらのNaNタイプのビット・パターンも定義していません。正の無限大、負の無限大、正のゼロおよび負のゼロはそれぞれ、特定のビット・パターンで表現されます。
符号を無視すると値には次のクラスがあり、NaNを除く各クラスは小さい方から順に示されています。
IEEE 754では、NaNは、他の特殊な値のクラスともNaN自体とも順序付けることはできません。
データベースで使用する場合、ネイティブ浮動小数点データ型の特殊な値は、次のように動作します。
NaNsはすべてquietです。
NaNの順序は次のとおりです。すべての非NaN < NaN
任意のNaN == 他のNaN
NaNsはすべて同じビット・パターンに変換されます。Oracle Databaseでは、浮動小数点データ型が関係する操作について、次の比較演算子が定義されています。
次の特殊ケースに注意してください。
-0は、+0より小さいとはみなされず、等しいとみなされます)。
NaNはそれ自体に等しくなります。NaNは、それ自体を除くすべての値より大きくなります。つまり、xがNaNの場合を除いて、NaN == NaNおよびNaN > xです。Oracle Databaseでは、次の算術演算子が用意されています。
演算の結果を丸めるために使用されるモードを定義できます。演算が実行されると、例外が発生することがあります。例外を無効化することもできます。
従来、Javaでは、浮動小数点算術に厳密な再現性が求められていました。IEEE 754では、このような動作は必要ありません。この規格では、算術を含む演算の結果を、演算でオペランドが使用するよりも大きい範囲を使用する格納先に格納できます。
倍精度乗算の結果は、拡張倍精度格納先での計算に使用できます。この場合、計算結果は、格納先が単精度または倍精度であるかのように丸められます。結果の範囲(指数のビット数)としては、より高精度(拡張倍精度)の格納先でサポートされている範囲が使用できます。このため、二重丸め誤差(結果の最下位ビットが不正)が発生する可能性があります。
この問題は、IA-32およびIA-64命令セット・アーキテクチャを実装するハードウェアで、倍精度乗算および除算を実行した場合のみ発生します。したがって、この例外が発生した場合、これらのデータ型に対する算術をプラットフォームを渡って再現できます。計算の結果がNaNの場合、すべてのプラットフォームでIS NANがTRUEの値が作成されます。ただし、すべてのプラットフォームで同じビット・パターンを使用する必要はありません。
Oracle Databaseでは、浮動小数点と他の形式(10進数精度を使用する文字列形式など)の間で変換を行う関数が定義されています(変換中に精度が失われることがあります)。たとえば、次の関数を使用できます。
TO_BINARY_DOUBLE。float型からdouble型、decimal型(文字列)からdouble型およびfloatまたはdouble型から整数値のdouble型への変換を実行します。
TO_BINARY_FLOAT。double型からfloat型、decimal型(文字列)からfloat型およびfloatまたはdouble型から整数値のfloat型への変換を実行します。
TO_CHAR。floatまたはdouble型からdecimal型(文字列)への変換を実行します。
TO_NUMBER。float、doubleまたはstring型からnumber型への変換を実行します。
Oracle Databaseでは、変換時に例外が発生する可能性があります。IEEE 754仕様では、次の例外が定義されています。
Oracle Databaseでは、ネイティブ浮動小数点データ型に対して、これらの例外は発生しません。例外が発生する状況では、通常、表3-5に示す値が生成されます。
| 例外 | 値 |
|---|---|
|
アンダーフロー |
|
|
オーバーフロー |
|
|
無効な演算 |
|
|
ゼロ除算 |
|
|
不正確 |
任意の値: 端数処理が実行されました |
Oracle Databaseでは、ネイティブ浮動小数点データ型のサポートは、次のクライアント・インタフェースに実装されています。
OCI APIでは、IEEE 754の単精度および倍精度のネイティブ浮動小数点データ型が実装されており、それぞれのデータ型はSQLT_BFLOATおよびSQLT_BDOUBLEです。これらのデータ型とSQLデータ型BINARY_FLOATおよびBINARY_DOUBLEとの変換は、Cデータ型FLOATおよびDOUBLEに対してIEEE 754標準を実装するプラットフォームで正確に行われます。
Oracle Databaseでは、SQLデータ型BINARY_FLOATおよびBINARY_DOUBLEは、Oracle OBJECT型の属性としてサポートされています。
Pro*C/C++では、列データ型BINARY_FLOATおよびBINARY_DOUBLEを使用して、ネイティブFLOATデータ型およびネイティブDOUBLEデータ型がサポートされています。これらのデータ型は、Oracle NUMBERデータ型と同じ方法で使用できます。ネイティブC/C++データ型FLOATおよびDOUBLEを、それぞれBINARY_FLOATおよびBINARY_DOUBLEデータ型にバインドできます。そのためには、アプリケーションのコンパイル時に、Pro*C/C++プリコンパイラ・コマンドライン・オプションNATIVE_TYPESをY(yes)に設定します。
この項の内容は次のとおりです。
Oracle Databaseでは、次の日時データ型がサポートされています。
DATEデータ型は、時間の値(日時)を表に格納するために使用します。DATEデータ型は、世紀、年、月、日、時間、分および秒を格納します。
TIMESTAMPデータ型は、小数秒を含む正確な値を格納するために使用します。たとえば、2つのイベントのどちらが最初に発生するかを決定する必要があるアプリケーションでは、TIMESTAMPを使用します。ジョブの時間を指定するアプリケーションでは、DATEを使用します。
TIMESTAMP WITH TIME ZONEもタイムゾーン情報を格納できるため、特に、複数の地域にまたがって収集または調整する必要がある日付情報の記録に適しています。
TIMESTAMP WITH LOCAL TIME ZONE値は、タイムゾーンが重要でない場合に使用します。たとえば、テレビ会議のスケジュールを立てるアプリケーションで使用できます。これらのテレビ会議では、各参加者がローカルのタイムゾーンで開始時間および終了時間を確認します。
TIMESTAMP WITH LOCAL TIME ZONE型は、クライアント・システムのタイムゾーンを使用して日時を表示する必要がある2層アプリケーションに適しています。通常、3層アプリケーションでこのデータ型を使用するのは不適切です。これは、Webブラウザに表示されるデータがブラウザのタイムゾーンではなくWebサーバーのタイムゾーンによってフォーマットされるためです。Webサーバーはデータベース・クライアントであるため、ローカル時間が使用されます。
INTERVAL DAY TO SECONDデータ型は、2つの日時値の正確な違いを表すために使用します。たとえば、この値を使用して、アラームを36時間後に設定したり、レースの開始から終了までの時間を記録できます。長い時間を高精度で表すには、日の部分に大きな値を使用します。
INTERVAL YEAR TO MONTHデータ型は、年および月のみが重要な場合に、2つの日時の違いを表すために使用します。たとえば、この値を使用して、アラームを18か月後の日付に設定したり、特定の日付から6か月経過したことを確認することができます。
Oracle Databaseは独自の内部形式で日付を格納します。日付データは、それぞれ7バイトの固定長フィールドに格納され、それぞれのバイトは、世紀、年、月、日、時間、分および秒に対応します。
日付の入出力に対するOracle Databaseのデフォルトの標準日付書式は、DD-MON-RRです。RR日時書式要素を使用すると、年の末尾2桁のみを指定して20世紀の日付を21世紀に格納できます。
戻り値の世紀は、指定した2桁の年と現在の年の末尾2桁に応じて異なります。詳細は、『Oracle Database SQLリファレンス』を参照してください。たとえば、次の書式は、1950年〜2049年に発行された問合せでは2004年を指しますが、2050〜2099年に発行される問合せでは2005年を指します。
'13-NOV-04'
デフォルトの日付書式を変更するには、次の方法があります。
現行のデフォルト日付書式以外の日付を入力するには、書式マスク付きTO_DATE関数を使用します。次に例を示します。
SELECT TO_CHAR(TO_DATE('27-OCT-98', 'DD-MON-RR') ,'YYYY') "Year" FROM DUAL;
DD-MON-YYのような日付書式を使用する場合は注意が必要です。YYは、現世紀の年を示します。たとえば、31-DEC-92は、1992年ではなく2092年12月31日を示します。現世紀以外の年を示す場合は、デフォルトでRRなど、異なる書式マスクを使用してください。
システム日付および時刻に戻すには、SQL関数SYSDATEを使用します。FIXED_DATE初期化パラメータを使用すると、SYSDATEを定数に設定できるため、テスト時に便利です。
デフォルトでは、SYSDATEはBCまたはAD修飾子なしで出力されます。書式文字列にBCを追加すると、必要に応じて日付とともにBCまたはADを出力できます。
SELECT TO_CHAR(SYSDATE, 'DD-MON-YYYY BC') FROM DUAL; TO_CHAR(SYSDAT -------------- 24-JAN-2004 AD
時刻は、次のように24時間形式で格納されます。
HH24:MI:SS
デフォルトでは、時刻部分に何も入力しない場合、またはDATE列が切り捨てられた場合、DATE列内の時刻は12:00:00 A.M.(真夜中)となります。
時刻のみの入力では、日付部分は現在の月の最初の日が想定されます。日付の時刻部分を入力するには、例3-3のように、時刻部分を示す書式マスク付きのTO_DATE関数を使用します。
-- create test table CREATE TABLE birthdays ( Bname VARCHAR2(20), Bday DATE ); -- insert a row INSERT INTO birthdays (bname, bday) VALUES ( 'ANNIE', TO_DATE('13-NOV-92 10:56 A.M.','DD-MON-YY HH:MI A.M.') );
Oracle Databaseでは、日付算術に有効な多数の機能が提供されるため、1日の秒数、1か月の日数などを独自に計算する必要はありません。有効な機能の例を次に示します。
ADD_MONTHS関数。日付に指定した月数を加算して戻します。
SYSDATE関数。データベースが常駐するオペレーティング・システムに設定されている現在の日時を戻します。
SYSTIMESTAMP関数。データベースが常駐するシステムのシステム日付(小数秒とタイムゾーンを含む)を戻します。
TRUNC関数。DATE値に適用した場合は、時刻部分を切り捨てるため、その日の1番始め(真夜中)を表します。2つのDATE値を切り捨て比較することによって、それらが同じ日を参照しているかどうかを判断できます。また、GROUP BY句とともに使用して、日計の作成もできます。
+や-など)。たとえば、SYSDATE-7は現在のシステム日付の7日前を指します。
INTERVALデータ型。独自の計算を実行するのではなくデータ型日付算術を実行する場合の定数を表すことができます。たとえば、DATE値にINTERVAL定数を加算または減算したり、2つのDATE値を減算して結果をINTERVALと比較できます。
>、<、=、BETWEENなど)。
Oracle Databaseには、日時データ型間で変換できるように複数の有用な関数が用意されています。有効な関数の例を次に示します。
EXTRACT。日時値または間隔値の式から指定の日時フィールドの値を抽出して戻します。
NUMTODSINTERVAL。NUMBERまたは暗黙的にNUMBER値に変換できる式を、INTERVAL DAY TO SECONDリテラルに変換します。
NUMTOYMINTERVAL。NUMBERまたは暗黙的にNUMBER値に変換できる式を、INTERVAL YEAR TO MONTHリテラルに変換します。
TO_DATE。文字データをDATEデータ型に変換します。
TO_CHAR。DATEデータを文字データに変換します。
TO_DSINTERVAL。文字列をINTERVAL DAY TO SECOND値に変換します。
TO_TIMESTAMP。文字データをTIMESTAMPデータ型の値に変換します。
TO_TIMESTAMP_TZ。文字データをTIMESTAMP WITH TIME ZONEデータ型の値に変換します。
TO_YMINTERVAL。文字列をINTERVAL YEAR TO MONTH型に変換します。TIMESTAMP WITH TIME ZONE値およびTIMESTAMP WITH LOCAL TIME ZONE値は常に正規化された書式で格納されるため、タイムゾーンのオフセットを考慮することなくエクスポート、インポートおよび比較ができます。DATE値およびTIMESTAMP値は対応付けられたタイムゾーンを格納しないため、ソース・データベースとターゲット・データベース間のタイムゾーンの違いを考慮して調整する必要があります。
この項の内容は次のとおりです。
MDSYS.SDO_GEOMETRYデータ型などのOracle Spatialの機能を使用して、地理情報システム(GIS)または空間データを表すことができます。オブジェクト・リレーショナル・モデルまたはリレーショナル・モデルを使用して、データベースにデータを格納できます。PL/SQLパッケージのセットを使用して、データを操作および問い合せることができます。
Oracle interMediaを使用すると、Oracle Databaseで他の企業情報と統合された方法でイメージ、オーディオ、ビデオまたは他の異機種メディア・データを格納、管理および取得できます。Oracle interMediaにより、Oracle Databaseの信頼性、可用性およびデータ管理が従来型、インターネット、E-Commerceおよびマルチメディア・アプリケーションのマルチメディア・コンテンツへと拡張されます。
この種のマルチメディア・データをBLOB値またはBFILE値としてデータベースに格納したり、Webサーバーまたはその他のサーバーに外部的に格納する場合、interMediaを使用して、オブジェクト・リレーショナル・モデルまたはリレーショナル・モデルのいずれかでデータにアクセスし、一連のオブジェクト型を使用してデータを操作および問い合せることができます。
Oracle interMediaは、次の用途にあったORDAudio、ORDDoc、ORDImage、ORDImageSignature、ORDVideoおよびSI_StillImageオブジェクト型とメソッドを提供します。
Oracle Databaseでは、大量のデータを表現するために複数のデータ型を提供しています。これらのデータ型は、ラージ・オブジェクト(LOB)の一般的なカテゴリでグループ化されます。表3-6に、様々なLOBを示します。
BLOB、CLOBまたはNCLOBデータ型のインスタンスは、通常のLOBインスタンスまたは一時LOBインスタンスとして存在します。通常のインスタンスと一時インスタンスは、次の点が異なります。
宣言、解放、作成およびコミットの例外については、通常のLOBインスタンスおよび一時LOBインスタンスでの操作は同じように実行されます。
RAWデータ型およびLONG RAWデータ型は、Oracle Databaseによって解析されない(異なるシステム間でデータを移動するときに変換されない)データを格納します。これらのデータ型は、2進データおよびバイト列のために用意されています。たとえば、LONG RAWは、図形データ、音声データ、文書データおよび2進データの配列に格納できます。解析方法は使用方法によって異なります。
Oracle Net、Export UtilityおよびImport Utilityは、RAWデータまたはLONG RAWデータの送信中は文字変換を行いません。Oracle DatabaseでRAWデータまたはLONG RAWデータとCHARデータ間の変換を自動的に行う場合(INSERT文で文字としてRAWデータを入力する場合など)に、データは、RAWデータの4ビットごとのビット・パターンを表した、1つの16進文字として表現されます。たとえば、ビット11001011の1バイトのRAWデータは、CBとして表示され、入力されます。
LONG RAWデータには索引を付けることができませんが、RAWデータには索引を付けることができます。以前のリリースでは、LONGおよびLONG RAWデータ型は、通常は大量のデータを格納するために使用されていました。新規に開発する場合、これらのデータ型を使用することはお薦めしません。これらのデータ型をアプリケーションで引き続き使用する場合は、LOB型を使用するようにアプリケーションを移行してください。LONG RAW列をバイナリLOB(BLOB)列に変換し、LONG列を文字LOB(CLOBまたはNCLOB)列に変換することをお薦めします。LOB列の制限は、LONG列およびLONG RAW列の制限より少なくなっています。
全文検索を行うには、低レベルのコードを作成するのではなく、Oracle Textを使用します。Oracle Textを使用すると、検索データが特別な索引に格納され、演算子およびPL/SQLパッケージを使用して検索データを問い合せることができます。このテクノロジによって、表、ファイルまたはURLのデータを使用する独自の検索エンジンの作成、および検索ロジックとリレーショナル問合せの結合が可能になります。この方法では、XPath表記法を使用してXMLデータを検索することもできます。
XML形式のファイルとして格納されている情報がある場合、またはオブジェクト型を取り、XMLとして格納する場合、XMLType組込み型を使用します。
XMLType列にはデータがCLOBとして格納されます。既存のCLOB、VARCHAR2または任意のオブジェクト型を取り、XMLTypeコンストラクタをコールしてXMLオブジェクトに変換します。
XMLオブジェクトがデータベース内に入ると、問合せを使用してオブジェクトを検索し(XML XPath表記法を使用する)、データの全体または一部を抽出できます。
既存のリレーショナル・データからXML出力を生成し、リレーショナル表および列にまたがってXML文書を分割することもできます。次のパッケージを使用して、XMLデータをリレーショナル表に、またはリレーショナル表から転送できます。
DBMS_XMLQUERY。データベースからXMLTypeへの転送機能を提供します。
DBMS_XMLGEN。SQL問合せの結果を標準のXML形式に変換します。
DBMS_XMLSAVE。XMLからデータベース型への転送機能を提供します。
次のSQL関数を使用してXMLを処理できます。
EXTRACT。VARCHAR2 XPath文字列を適用し、XMLフラグメントを含むXMLTypeインスタンスを戻します。
SYS_XMLAGG。式で表されるXML文書またはフラグメントをすべて集計し、1つのXML文書を生成します。
SYS_XMLGEN。データベースの特定の行および列に評価される式を取り、XML文書を含むXMLType型のインスタンスを戻します。
UPDATEXML。XMLTypeインスタンスとXPath値のペアを引数として取り、更新された値とともにXMLTypeインスタンスを戻します。
XMLAGG。XMLフラグメントのコレクションを取り、集計されたXML文書を戻します。
XMLCOLATTVAL。XMLフラグメントを作成し、作成後のXMLを各XMLフラグメントの名前列に属性値が含まれるように拡張します。
XMLCONCAT。入力として一連のXMLTypeインスタンスを取り、各行の一連の要素を連結し、連結後の一連の要素を戻します。
XMLELEMENT。識別子の要素名、要素の属性のオプションのコレクションおよび要素のコンテンツを構成する引数を取ります。
XMLFOREST。各引数パラメータをXMLに変換し、変換後の引数の連結結果であるXMLフラグメントを戻します。
XMLSEQUENCE。入力としてXMLTypeインスタンスを取ってXMLTypeでトップレベル・ノードのVARRAYを戻すか、入力としてREFCURSORインスタンス(およびオプションでXMLFormatオブジェクトのインスタンス)を取り、カーソルの行ごとにXML文書をXMLSequence型として戻します。XMLTRANSFORM。引数としてXMLTypeインスタンスとXSLスタイルシートを取り、そのスタイルシートをインスタンスに適用してXMLTypeを戻します。
いくつかの言語では、実行時にデータ型を変更したり、プログラムに変数の型を確認させることができます。たとえば、C言語にはunionキーワードおよびvoid *ポインタがあり、Javaにはtypeof演算子およびNumberなどのラッパー型があります。Oracle Databaseには、すべての型のデータを保持できる変数および列を作成し、データ値をテストして基礎となる表現を判断できる機能が含まれています。これらの機能を使用すると、表の単一の列で、数値、文字列およびオブジェクトをそれぞれ別の行に表現できます。
SYS.ANYDATA組込みデータ型を使用すると、すべてのスカラー型またはオブジェクト型の値を表現できます。この型はオブジェクト型で、すべての型のスカラー値を取り込み、値をスカラーまたはオブジェクトに戻すメソッドが含まれています。同様に、SYS.ANYDATASET組込みデータ型を使用すると、すべてのコレクション型の値を表現できます。
型に関する情報を処理および確認するには、SYS.ANYTYPEをDBMS_TYPESパッケージと組み合せて使用します。例3-4のプログラムは、表内の基となる型が異なるデータを表し、各列の基となる型を解析して、それぞれの値を適切に処理します。
-- This example defines and executes a PL/SQL procedure that -- uses methods built into SYS.ANYDATA to access information about -- data stored in a SYS.ANYDATA table column. DROP TYPE Employee_type FORCE; DROP TABLE mytab; CREATE OR REPLACE TYPE Employee_type AS OBJECT ( empno NUMBER, ename VARCHAR2(10) ); / CREATE TABLE mytab ( id NUMBER, data SYS.ANYDATA ); INSERT INTO mytab VALUES (1, SYS.ANYDATA.ConvertNumber(5)); INSERT INTO mytab VALUES (2, SYS.ANYDATA.ConvertObject(Employee_type(5555, 'john'))); COMMIT; CREATE OR REPLACE PROCEDURE p IS CURSOR cur IS SELECT id, data FROM mytab; v_id mytab.id%TYPE; v_data mytab.data%TYPE; v_type SYS.ANYTYPE; v_typecode PLS_INTEGER; v_typename VARCHAR2(60); v_dummy PLS_INTEGER; v_n NUMBER; v_employee Employee_type; non_null_anytype_for_NUMBER exception; unknown_typename exception; BEGIN OPEN cur; LOOP FETCH cur INTO v_id, v_data; EXIT WHEN cur%NOTFOUND; /* The typecode is a number that signifies what type is represented by v_data. GetType also produces a value of type SYS.AnyType with methods you can call to find precision and scale of a number, length of a string, and so on. */ v_typecode := v_data.GetType ( v_type /* OUT */ ); /* Now we compare the typecode against constants from DBMS_TYPES to see what kind of data we have, and decide how to display it. */ CASE v_typecode WHEN DBMS_TYPES.TYPECODE_NUMBER THEN IF v_type IS NOT NULL -- This condition should never happen, but we check just in case. THEN RAISE non_null_anytype_for_NUMBER; END IF; -- For each type, there is a Get method. v_dummy := v_data.GetNUMBER ( v_n /* OUT */ ); DBMS_OUTPUT.PUT_LINE ( TO_CHAR(v_id) || ': NUMBER = ' || To_Char(v_n) ); WHEN DBMS_TYPES.TYPECODE_OBJECT THEN v_typename := v_data.GetTypeName(); -- An object type's name is qualified with the schema name. IF v_typename NOT IN ( 'HR.EMPLOYEE_TYPE' ) -- If we encounter any object type besides EMPLOYEE_TYPE, raise an exception. THEN RAISE unknown_typename; END IF; v_dummy := v_data.GetObject ( v_employee /* OUT */ ); DBMS_OUTPUT.PUT_LINE ( To_Char(v_id) || ': user-defined type = ' || v_typename || ' ( ' || v_employee.empno || ', ' || v_employee.ename || ' )' ); END CASE; END LOOP; CLOSE cur; EXCEPTION WHEN non_null_anytype_for_NUMBER THEN RAISE_Application_Error ( -20000, 'Paradox: the return AnyType instance FROM GetType ' || 'should be NULL for all but user-defined types' ); WHEN unknown_typename THEN RAISE_Application_Error ( -20000, 'Unknown user-defined type ' || v_typename || ' - program written to handle only HR.EMPLOYEE_TYPE' ); END; /
例3-4の問合せとプロシージャを実行すると、例3-5のような出力が生成されます。
SQL> SELECT t.data.gettypename() AS "Type Name" FROM mytab t; Type Name -------------------------------------------------------------------------------- SYS.NUMBER HR.EMPLOYEE_TYPE SQL> EXEC p; 1: NUMBER = 5 2: user-defined type = HR.EMPLOYEE_TYPE ( 5555, john )
OCIType、OCIAnyDataおよびOCIAnyDataSetインタフェースを使用すると、OCIインタフェースを介して同じ機能にアクセスできます。
Oracle Database内の表の列は、ANSI/ISOデータ型、DB2データ型およびSQL/DSデータ型を使用して定義できます。Oracle Databaseはそのようなデータ型を内部的に変換して、Oracleデータ型にします。
表3-7に、ANSIデータ型の変換を示します。ANSI/ISOデータ型のNUMERIC、DECIMALおよびDECは、固定小数点数のみを指定できます。これらのデータ型に対して、s のデフォルトは0です。
表3-8に、DB2データ型とSQL/DSデータ型の変換を示します。
IBM社の製品SQL/DSとDB2のTIME、GRAPHIC、VARGRAPHICおよびLONG VARGRAPHICデータ型には、対応するOracleデータ型がないため使用できません。
Oracle Expression Filterの機能により、条件式をデータとしてデータベースに格納できます。Expression Filterは、VARCHAR2列に制約を設定して、格納された値が有効なSQL WHERE句の式になるようにするメカニズムを提供します。このメカニズムでは、条件式で参照できる属性のセットも識別されます。
たとえば、各行に株式取引の口座名義人のデータが保持されるように表tradersを作成するとします。各投資家が関心を持っている株式に関する情報を条件式として格納する列を定義できます。手順は次のとおりです。
tradersを作成します。
CREATE TABLE traders ( name VARCHAR2(50), email VARCHAR2(50), interest VARCHAR2(50) );
tickerを作成します。
CREATE OR REPLACE TYPE ticker AS OBJECT ( symbol VARCHAR2(20), price NUMBER, change NUMBER );
tickerデータ型に基づいて属性セットtickerを作成します。
BEGIN DBMS_EXPFIL.CREATE_ATTRIBUTE_SET( attr_set => 'ticker', from_type => 'YES' ); END;
trader.interestに格納された式セットに属性セットを関連付けます。
BEGIN DBMS_EXPFIL.ASSIGN_ATTRIBUTE_SET (attr_set => 'ticker', expr_tab => 'traders', expr_col => 'interest'); END;
このコードにより、列に有効な条件式が格納されるようにする制約がinterest列に設定されます。
INSERT INTO traders (name, email, interest) VALUES ('Vishu', 'vishu@abc.com', 'symbol = ''ABC'' AND price > 25');
EVALUATE演算子を使用して、指定したデータ項目をTRUEと評価する条件式を識別します。たとえば、次の問合せでは、指定した株価(symbol='ABC', price=31, change=5.2)に関心を持っている投資家が戻されます。
SELECT Name, Email FROM Traders WHERE EVALUATE ( interest, 'symbol=>''ABC'', price=>31, change=>5.2' ) = 1;
このタイプの問合せを高速化するには、オプションでinterest列にOracle Expression Filter索引を作成できます。
データベース表の各行は、ROWIDと呼ばれるアドレスを持っています。疑似列ROWIDを問い合せると、行アドレスを確認できます。この疑似列の値は、各行のアドレスを表す文字列です。これらの文字列のデータ型はROWIDまたはUROWIDです。また、ROWIDデータ型の実際の列を含む表およびクラスタを作成することもできます。Oracle Databaseでは、この種の列の値が有効なROWIDであるという保証はありません。
ROWID値は、次の理由からアプリケーション開発に重要です。
Oracle Databaseデータベース内の各表は、ROWIDという名前の疑似列を持っています。行が長すぎて単一のデータ・ブロックに格納できない場合、ROWIDによって最初の行断片が識別されます。通常、ROWIDは一意ですが、同じデータ・ブロック内に存在し、異なるクラスタ化表に存在する行の場合、異なる行が同じROWIDを持つ可能性があります。
次のSQL文は、問合せを満たすhr.employees表の行のROWID疑似列を戻し、これをt_tab表に挿入します。
CREATE TABLE t_tab (col1 ROWID); INSERT INTO t_tab SELECT ROWID FROM hr.employees WHERE employee_id = 7499;
索引構成表でも外部表でもない表の場合、ROWID疑似列の値のデータ型はROWIDです。このデータ型には、拡張形式と制限付き形式があります。
内部的に、ROWIDは、データベース・サーバーが行にアクセスするために必要な情報を保持する構造体です。制限付きの内部ROWIDは、ほとんどのプラットフォームでは6バイトです。制限付きROWIDは、それぞれ次のデータを含みます。
制限付きROWID疑似列は18文字の文字列形式で、16進数でコード化されたROWIDのデータ・ブロック、行およびデータ・ファイル・コンポーネントとともにクライアント・アプリケーションに戻されます。
拡張ROWIDデータ型は、制限付きROWIDのデータとデータ・オブジェクト番号を含みます。データ・オブジェクト番号は、各データベース・セグメントに割り当てられる識別番号です。拡張内部ROWIDは、ほとんどのプラットフォームでは10バイトです。
拡張ROWID疑似列のデータは、18文字の文字列形式(たとえば、AAAA8mAALAAAAQkAAA)でクライアント・アプリケーションに戻されます。この文字列は、4つの部分からなる形式、OOOOOOFFFBBBBBBRRRの拡張ROWIDのコンポーネントをbase 64にエンコードしたものを表します。拡張ROWIDを直接使用することはできません。パッケージDBMS_ROWIDを使用すると、拡張ROWIDの内容を解析できます。このパッケージのファンクションは、制限付きROWIDから直接使用可能な情報を抽出し、拡張ROWID固有の情報とともに提供します。
一部のクライアント・アプリケーションでは、バイナリ形式のROWIDを使用します。たとえば、OCIおよび一部のプリコンパイラ・アプリケーションでは、バインドまたは定義のコールで3GL構造体に対してROWIDデータ型をマップできます。バイナリROWIDのサイズは、拡張および制限付きROWIDのサイズと同じです。拡張ROWID に関する情報は、制限付きROWID構造体の未使用フィールドに入っています。
拡張バイナリROWIDの形式は、Cの構造体で表すと、次のようになります。
struct riddef { ub4 ridobjnum; /* data obj#--this field is unused in restricted ROWIDs */ ub2 ridfilenum; ub1 filler; ub4 ridblocknum; ub2 ridslotnum; }
一部の表の行は、物理的または永続的でないアドレス、あるいはOracle Databaseで生成されたものではないアドレスを持っています。たとえば、索引構成表の行アドレスは索引リーフに格納されますが、これは移動できます。Oracleでは、この種の表は論理ROWIDと呼ばれる論理行ID付きで提供されます。ゲートウェイを介してアクセスされるDB2の表のような外部表のROWIDは、標準Oracle Database ROWIDではありません。Oracleでは、外部表とともに外部ROWIDと呼ばれる識別子が提供されます。
Oracle Databaseでは、索引構成表と外部表のアドレスはユニバーサルROWID(UROWID)を使用して格納されます。どちらのタイプのUROWIDも、ヒープ構成表の物理ROWIDと同様にROWID疑似列に格納されます。
論理ROWIDは表の主キーに基づいて作成されます。主キーに変更がないかぎり、論理ROWIDは変更されません。索引構成表のROWID疑似列は、UROWIDデータ型です。この疑似列には、ヒープ構成表のROWID疑似列と同様に(SELECT ... ROWID文を使用して)アクセスできます。索引構成表のROWIDを格納する場合は、表に対してUROWID型の列を定義し、その列にROWID疑似列の値を取り出すことができます。
Oracle Databaseでは、あるデータ型のデータを処理する箇所で、別のデータ型のデータを処理できる場合があります。一般には、1つの式に異なるデータ型の値を含めることはできません。しかし、Oracle Databaseでは、各種SQL関数によって、データを必要なデータ型に自動的に変換できます。
Oracle Databaseが、代入する値のデータ型を代入先のデータ型に変換できる場合、代入のデータ型変換は正常に行われます。
次の例では、次のように宣言されたパブリック変数および表を持つパッケージを想定しています。
CREATE PACKAGE Test_Pack AS var1 CHAR(5); END; CREATE TABLE Table1_tab (col1 NUMBER);
variable := expression expressionのデータ型は、variableのデータ型と同じか、そのデータ型に変換可能である必要があります。たとえば、次に示す代入では、指定されているデータがストアド・プロシージャ本体内で自動的に変換されます。
VAR1 := 0;
INSERT INTO Table1_tab VALUES (expression1, expression2, ...) expression1とexpression2、および後に続くデータ型は、Table1_tab中の対応する列のデータ型と同じか、またはそのデータ型に変換可能である必要があります。たとえば、Table1_tabに対して発行された次のINSERT文では、指定されているデータが自動的に変換されます。
INSERT INTO Table1_tab VALUES ( ' 19 ' );
UPDATE Table1_tab SET column = expression expressionのデータ型は、columnのデータ型と同じか、またはそのデータ型に変換可能である必要があります。たとえば、Table1_tabに対して発行された次のUPDATE文では、指定されているデータが自動的に変換されます。
UPDATE Table1_tab SET col1 = ' 30 ' ;
SELECT column INTO variable FROM Table1_tab columnのデータ型は、variableのデータ型と同じか、またはそのデータ型に変換可能である必要があります。たとえば、Oracle Databaseでは、表から選択されたデータは、次の文の変数に代入される前に、自動的に変換されます。
SELECT Col1 INTO Var1 FROM Table1_tab WHERE Col1 = 30;
式の評価では、Oracle Databaseは割当ての場合と同じ変換を自動的に行うことができます。式は、その内容に基づいて特定の型に変換されます。たとえば、算術演算子へのオペランドはNUMBERに変換され、文字列関数へのオペランドはVARCHAR2に変換されます。
Oracle Databaseは、次のような変換を自動的に行うことができます。
文字列が有効な数値を表している場合にのみ、CHARからNUMBERへの変換が正常に行われます。文字列がNLS_DATE_FORMAT初期化パラメータで指定されたセッションのデフォルト形式を満たす場合にのみ、CHARからDATEへの変換が正常に行われます。
一般的な式は次のとおりです。
commission + '500'
bonus > salary / '10'
MOD (counter, '2')
WHERE句の条件
WHERE hiredate = TO_DATE('1997-01-01','yyyy-mm-dd')
WHERE句の条件
WHERE rowid = 'AAAAaoAATAAAADAAA'
通常、割当て変換規則が適用されないところでデータ型変換が必要になると、Oracle Databaseは、式評価規則を使用します。
次のような割当ての場合、
variable := expression
Oracle Databaseは、式変換規則を最初に使用して、expressionを評価します。expressionは単純な式でも複雑な式でもかまいません。評価が正常に行われると、結果として単一の値およびデータ型が戻されます。その後、Oracle Databaseは、割当て変換規則を使用して、割当て先の変数にこの値を割り当てようとします。
|
![]() Copyright © 2006 Oracle Corporation. All Rights Reserved. |
|