プライマリ・コンテンツに移動
Oracle® Database SQL言語リファレンス
11gリリース2 (11.2)
B56299-08
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

データ型の比較規則

ここでは、Oracle Databaseが各データ型の値を比較する方法について説明します。

数値

大きい値は小さい値よりも大きいとみなされます。すべての負の数は、0(ゼロ)およびすべての正の数より小さいとみなされます。したがって、-1は100より小さく、-100は-1より小さいとみなされます。

浮動小数点値NaN(非数値)は、その他の数値よりも大きく、NaNとは等しいとみなされます。


関連項目:

比較セマンティクスの詳細は、「数値の優先順位」および「浮動小数点数」を参照してください。

日付値

後の日付は前の日付よりも大きいとみなされます。たとえば、29-MAR-2005(2005年3月29日)に相当する日付は05-JAN-2006(2006年1月5日)に相当する日付よりも小さく、05-JAN-2006 1:35pm(2006年1月5日午後1時35分)に相当する日付は05-JAN-2005 10:09am(2005年1月5日午前10時9分)に相当する日付よりも大きいとみなされます。

文字値

文字値は、2つのメジャーに基づいて比較されます。

  • バイナリ・ソートまたは言語ソート

  • 空白埋め比較セマンティクスまたは非空白埋め比較セマンティクス

次の項で、2つのメジャーについて説明します。

バイナリ比較または言語比較

デフォルトのバイナリ比較では、Oracleは、データベース・キャラクタ・セット内の文字の数値コードを連結した値に従って文字列を比較します。第1の文字の数値が第2の文字の数値よりも大きい場合、第1の文字は第2の文字よりも大きいとみなされます。Oracleは、空白はどの文字よりも小さいとみなします。これは、ほぼすべてのキャラクタ・セットでいえることです。

次に、一般的なキャラクタ・セットを示します。

  • 7ビットASCII(情報交換用米国標準コード)

  • EBCDICコード(拡張2進化10進コード)

  • ISO 8859/1(国際標準化機構)

  • JEUC日本語拡張UNIX

数値コードのバイナリ順序と、比較する文字の言語順序が一致していない場合は、言語比較が有効です。NLS_SORTパラメータにBINARY以外の設定があり、NLS_COMPパラメータがLINGUISTICに設定されている場合は言語比較が使用されます。言語ソートでは、すべてのSQLのソートおよび比較がNLS_SORTによって指定された言語規則に基づいて行われます。


関連項目:

言語ソートについては、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照してください。

空白埋め比較セマンティクスおよび非空白埋め比較セマンティクス

空白埋め比較セマンティクスでは、2つの値の長さが異なる場合、Oracleはまず短い方の値の最後に空白を追加して、2つの値が同じ長さになるようにします。次に、その2つの値を、最初に異なる文字まで1文字ずつ比較します。最初に異なる文字の位置で、大きい方の文字を持つ値の方が大きいとみなされます。2つの値に異なる文字がない場合、その2つの値は等しいとみなされます。この規則では、2つの値の後続空白数のみが異なる場合、その2つの値は等しいとみなされます。Oracleでは、比較する両方の値が、CHARデータ型、NCHARデータ型、テキスト・リテラルのいずれかの式の場合、またはUSERファンクションの戻り値の場合のみ空白埋め比較セマンティクスを使用します。

非空白埋め比較セマンティクスでは、Oracleは、2つの値を、最初に異なる文字まで1文字ずつ比較します。最初に異なる文字の位置で、大きい方の文字を持つ値の方が大きいとみなされます。長さが異なる2つの値を短い方の値の最後まで比較して、すべて同じ文字だった場合、長い方の値が大きいとみなされます。同じ長さの2つの値に異なる文字がない場合、その2つの値は等しいとみなされます。Oracleでは、比較する片方または両方の値がVARCHAR2データ型またはNVARCHAR2データ型の場合、非空白埋め比較セマンティクスを使用します。

これらの異なる比較セマンティクスを使用して2つの文字値を比較した場合、その結果が異なることもあります。次の表に、それぞれの比較セマンティクスを使用して5組の文字を比較した結果を示します。通常、空白埋め比較と非空白埋め比較の結果は同じです。表に示されている最後の比較では、空白埋め比較と非空白埋め比較の違いが明確になっています。

空白埋め比較 非空白埋め比較
'ac' > 'ab' 'ac' > 'ab'
'ab' > 'a  ' 'ab' > 'a   '
'ab' > 'a' 'ab' > 'a'
'ab' = 'ab' 'ab' = 'ab'
'a ' = 'a' 'a ' > 'a'

ASCIIとEBCDICのキャラクタ・セットの一部を表3-8表3-9に示します。大文字と小文字は同じではありません。キャラクタ・セットの照合順番は、特定の言語の言語順序と一致しない場合があります。

表3-8 ASCIIキャラクタ・セット

記号 10進値 記号 10進値

空白

32

;

59

!

33

<


60

"

34

=


61

#


35

>

62

$


36

?

63

%


37

@


64

&


38

A-Z

65-90

'

39

[


91

(

40

\


92

)

41

]


93

*


42

^


94

+


43

_


95

,

44

'

96

-

45

a-z

97-122

.

46

{


123

/


47

|


124

0-9

48-57

}


125

:

58

~

126


表3-9 EBCDICキャラクタ・セット

記号 10進値 記号 10進値

空白

64

%


108

¢


74

_


109

.

75

>

110

<


76

?

111

(

77

:

122

+


78

#


123

|


79

@


124

&


80

'

125

!

90

=


126

$


91

"

127

*


92

a-i

129-137

)

93

j-r

145-153

;

94

s-z

162-169

ÿ


95

A-I

193-201

-

96

J-R

209-217

/


97

S-Z

226-233


オブジェクト値

オブジェクト値は、MAPORDERの2つの比較ファンクションのいずれかを使用して比較されます。どちらのファンクションでもオブジェクト型インスタンスは比較されますが、両者は別のものです。これらのファンクションは、他のオブジェクト型と比較するオブジェクト型の一部として指定される必要があります。


関連項目:

MAPメソッドとORDERメソッド、およびこれらのメソッドが戻す値の詳細は、「CREATE TYPE」を参照してください。

VARRAYとネストした表

ネストした表の比較の詳細は、「比較条件」を参照してください。

データ型の優先順位

Oracleでは、データ型の優先順位によって、暗黙的にデータ型を変換するかどうかを判断します(次の項を参照)。Oracleデータ型の優先順位は、次のとおりです。

  • 日時および期間データ型

  • BINARY_DOUBLE

  • BINARY_FLOAT

  • NUMBER

  • 文字データ型

  • その他のすべての組込みデータ型

データ変換

一般に、式には異なるデータ型の値を含めることができません。たとえば、式では10に5を掛けた値に'JAMES'を加えることはできません。ただし、Oracleでは値をあるデータ型から別のデータ型へ変換する場合の、暗黙的な変換と明示的な変換をサポートしています。

暗黙的なデータ変換と明示的なデータ変換

次の理由から、暗黙的な変換または自動変換ではなく、明示的な変換を指定することをお薦めします。

  • 明示的なデータ型変換ファンクションを使用すると、SQL文がわかりやすくなります。

  • 暗黙的なデータ型変換(特に列値のデータ型が定数に変換される場合)は、パフォーマンスに悪影響を及ぼす可能性があります。

  • 暗黙的な変換はその変換が行われるコンテキストに依存し、どんな場合でも同様に機能するとはかぎりません。たとえば、日時値からVARCHAR2型へ値を暗黙的に変換すると、NLS_DATE_FORMATパラメータに指定されている値によっては、予期しない年が戻される場合があります。

  • 暗黙的な変換のアルゴリズムは、ソフトウェア・リリースやOracle製品の変更によって変更されることがあります。明示的な変換を指定しておくと、その動作は将来的にも確実になります。

  • 索引式で暗黙的なデータ型変換が発生した場合、その索引が変換前のデータ型に対して定義されているために、Oracle Databaseがその索引を使用しないことがあります。これは、パフォーマンスに悪影響を与えるおそれがあります。

暗黙的なデータ変換

あるデータ型から別のデータ型への変換が意味を持つ場合、Oracle Databaseは値を自動的に変換します。

表3-10に、Oracleの暗黙的な変換のマトリックスについて示します。この表は、変換の方向または変換されるコンテキストにかかわらず、すべての可能な変換を示します。詳細は、表の後の説明を参照してください。

表3-10 暗黙的な型変換のマトリックス

CHAR VARCHAR2 NCHAR NVARCHAR2 DATE DATETIME/INTERVAL NUMBER BINARY_FLOAT BINARY_DOUBLE LONG RAW ROWID CLOB BLOB NCLOB

CHAR

--

X

X

X

X

X

X

X

X

X

X

--

X

X

X

VARCHAR2

X

--

X

X

X

X

X

X

X

X

X

X

X

--

X

NCHAR

X

X

--

X

X

X

X

X

X

X

X

X

X

--

X

NVARCHAR2

X

X

X

--

X

X

X

X

X

X

X

X

X

--

X

DATE

X

X

X

X

--

--

--

--

--

--

--

--

--

--

--

DATETIME/ INTERVAL

X

X

X

X

--

--

--

--

--

X

--

--

--

--

--

NUMBER

X

X

X

X

--

--

--

X

X

--

--

--

--

--

--

BINARY_FLOAT

X

X

X

X

--

--

X

--

X

--

--

--

--

--

--

BINARY_DOUBLE

X

X

X

X

--

--

X

X

--

--

--

--

--

--

--

LONG

X

X

X

X

--

X脚注 1 

--

--

--

--

X

--

X

--

X

RAW

X

X

X

X

--

--

--

--

--

X

--

--

--

X

--

ROWID

--

X

X

X

--

--

--

--

--

--

--

--

--

--

--

CLOB

X

X

X

X

--

--

--

--

--

X

--

--

--

--

X

BLOB

--

--

--

--

--

--

--

--

--

--

X

--

--

--

--

NCLOB

X

X

X

X

--

--

--

--

--

X

--

--

X

--

--


脚注 1 LONGINTERVALに直接変換することはできませんが、TO_CHAR(interval)を使用してLONGVARCHAR2に変換し、そのVARCHAR2の値をINTERVALに変換できます。

暗黙的なデータ型変換は、次に示す規則によって決まります。

  • INSERTおよびUPDATE操作中に、Oracleは変更する列のデータ型に値を変換します。

  • SELECT FROM操作中に、Oracleは列からターゲット変数の型にデータを変換します。

  • 数値を操作する際、Oracleは、通常、最大容量を確保するために精度および位取りを調整します。この場合、このような操作によって変換された数値データ型は、基礎となる表に含まれる数値データ型と異なることがあります。

  • 数値と文字値を比較する場合、Oracleは文字データを数値に変換します。

  • 文字値またはNUMBERの値と浮動小数点数の値の間では、変換が正確に行われない場合があります。これは、文字型およびNUMBERでは10進精度で数値が示されるのに対し、浮動小数点数では2進精度が使用されているためです。

  • CLOB値をVARCHAR2などの文字データ型に変換する場合、またはBLOBRAWデータに変換する場合、変換するデータがターゲットのデータ型より大きいと、データベースはエラーを戻します。

  • タイムスタンプ値からDATE値への変換では、タイムスタンプ値の秒の小数部は切り捨てられます。この動作は、タイムスタンプ値の秒の小数部が丸められていた、以前のリリースのOracle Databaseの動作とは異なります。

  • BINARY_FLOATからBINARY_DOUBLEへの変換は正確に行われます。

  • BINARY_DOUBLEの値がBINARY_FLOATでサポートされている精度のビット数よりも多いビット数を使用している場合、BINARY_DOUBLEからBINARY_FLOATへの変換は正確に行われません。

  • DATEの値と文字の値を比較する場合、Oracleは文字データをDATEに変換します。

  • SQLファンクションまたは演算子に不当なデータ型の引数を指定して使用する場合、Oracleはその引数を正当なデータ型に変換します。

  • 代入を実行する場合、Oracleは等号(=)の右側の値を左側の代入ターゲットのデータ型に変換します。

  • 連結中に、Oracleは非文字データ型をCHARまたはNCHARに変換します。

  • 文字データ型と非文字データ型に対する演算処理および比較中に、Oracleはすべての文字データ型を数値、日付またはROWIDのいずれかの適切なデータ型に変換します。CHAR/VARCHAR2NCHAR/NVARCHAR2の演算処理では、OracleはNUMBERに変換します。

  • ほとんどのSQL文字ファンクションは、CLOBをパラメータとして指定できます。また、OracleはCLOBと文字型間で暗黙的な変換を実行します。このため、CLOBを使用できないファンクションは、暗黙的な変換を使用してCLOBを受け入れます。このような場合、Oracleはファンクションが起動される前にCLOBCHARまたはVARCHAR2に変換します。CLOBが4000バイトより大きい場合、Oracleは最初の4000バイトのみをCHARに変換します。

  • RAWまたはLONGRAWデータを文字データとの間で変換する場合、バイナリ・データは16進形式で表され、16進文字1文字ごとに4ビットのRAWデータを表します。詳細は、「RAWデータ型とLONG RAWデータ型」を参照してください。

  • CHARVARCHAR2NCHARNVARCHAR2の比較では、異なるキャラクタ・セットが必要な場合があります。このような場合のデフォルトの変換の方向は、データベース・キャラクタ・セットから各国語キャラクタ・セットです。表3-11に、異なるキャラクタ・タイプ間での暗黙的な変換の方向を示します。

表3-11 異なるキャラクタ・タイプの変換方向


CHARへ VARCHAR2へ NCHARへ NVARCHAR2へ

CHARから

--

VARCHAR2

NCHAR

NVARCHAR2

VARCHAR2から

VARCHAR2

--

NVARCHAR2

NVARCHAR2

NCHARから

NCHAR

NCHAR

--

NVARCHAR2

NVARCHAR2から

NVARCHAR2

NVARCHAR2

NVARCHAR2

--


コレクションなどのユーザー定義型は暗黙的に変換できないため、CAST ... MULTISETを使用して明示的に変換する必要があります。

暗黙的なデータ変換の例

テキスト・リテラルの例 テキスト・リテラル'10'はCHARデータ型です。次の文のように数式で使用すると暗黙的にNUMBERデータ型に変換されます。

SELECT salary + '10'
  FROM employees;

文字値および数値の例 条件で文字値とNUMBER型の値を比較する場合、NUMBER型の値は文字値に変換されず、文字値が暗黙的にNUMBER型の値に変換されます。次の文では、'200'が暗黙的に200に変換されます。

SELECT last_name
  FROM employees
  WHERE employee_id = '200';

日付の例 次の文では、Oracleがデフォルトの日付書式'DD-MON-YY'を使用して、'24-JUN-06'をDATE値に暗黙的に変換します。

SELECT last_name
  FROM employees 
  WHERE hire_date = '24-JUN-06';

明示的なデータ変換

SQL変換ファンクションを使用すると、データ型の変換を明示的に指定できます。表3-12に、値をあるデータ型から別のデータ型に明示的に変換するSQLファンクションを示します。

Oracleが暗黙的なデータ型変換を行うことができる場合には、LONGおよびLONG RAWの値を指定できません。たとえば、ファンクションや演算子を含む式では、LONGLONG RAWの値を使用できません。LONGデータ型およびLONG RAWデータ型の制限については、「LONGデータ型」を参照してください。

表3-12 明示的な型の変換


CHAR、VARCHAR2、NCHAR、NVARCHAR2へ NUMBERへ Datetime/Intervalへ RAWへ ROWIDへ LONG、LONG RAWへ CLOB、NCLOB、BLOBへ BINARY_FLOATへ BINARY_DOUBLEへ

CHAR、VARCHAR2、NCHAR、NVARCHAR2から

TO_CHAR(文字)

TO_NCHAR(文字)

TO_NUMBER

TO_DATE

TO_TIMESTAMP

TO_TIMESTAMP_TZ

TO_YMINTERVAL

TO_DSINTERVAL

HEXTORAW

CHARTO­=ROWID

--

TO_CLOB

TO_NCLOB

TO_BINARY_FLOAT

TO_BINARY_DOUBLE

NUMBERから

TO_CHAR(数値)

TO_NCHAR(数値)

--

TO_DATE

NUMTOYM- INTERVAL

NUMTODS- INTERVAL

--

--

--

--

TO_BINARY_FLOAT

TO_BINARY_DOUBLE

Datetime Intervalから

TO_CHAR(日付)

TO_NCHAR (日時)

--

--

--

--

--

--

--

--

RAWから

RAWTOHEX

RAWTONHEX

--

--

--

--

--

TO_BLOB

--

--

ROWIDから

ROWIDTOCHAR

--

--

--

--

--

--

--

--

LONG/LONG RAWから

--

--

--

--

--

--

TO_LOB

--

--

CLOB、NCLOB、BLOBから

TO_CHAR

TO_NCHAR

--

--

--

--

--

TO_CLOB

TO_NCLOB

--

--

CLOB、NCLOB、BLOBから

TO_CHAR

TO_NCHAR

--

--

--

--

--

TO_CLOB

TO_NCLOB

--

--

BINARY_FLOATから

TO_CHAR(文字)

TO_NCHAR(文字)

TO_NUMBER

--

--

--

--

--

TO_BINARY_FLOAT

TO_BINARY_DOUBLE

BINARY_DOUBLEから

TO_CHAR(文字)

TO_NCHAR(文字)

TO_NUMBER

--

--

--

--

--

TO_BINARY_FLOAT

TO_BINARY_DOUBLE



関連項目:

すべての明示的な変換ファンクションの詳細は、「変換ファンクション」を参照してください。

データ変換のセキュリティ上の考慮事項

暗黙的な変換、または書式モデルを指定しない明示的な変換のいずれかによって日時値がテキストに変換される場合、書式モデルはグローバリゼーション・セッション・パラメータの1つによって定義されます。ソースのデータ型に応じて、パラメータ名はNLS_DATE_FORMATNLS_TIMESTAMP_FORMATまたはNLS_TIMESTAMP_TZ_FORMATです。これらのパラメータの値は、クライアント環境で、またはALTER SESSION文で指定できます。

書式モデルがセッション・パラメータに依存している場合、明示的な書式モデルが指定されていない変換が動的SQL文のテキストに連結される日時値に適用されると、データベースのセキュリティに悪影響を及ぼす可能性があります。動的SQL文は、実行のためにデータベースに渡される前にそのテキストがフラグメントから連結される文です。動的SQLは、組込みPL/SQLパッケージDBMS_SQLまたはPL/SQL文EXECUTE IMMEDIATEに関連付けられる場合が多いですが、動的に構成されたSQLテキストを引数として渡すことができる場所はこれらのみではありません。次に例を示します。

EXECUTE IMMEDIATE
'SELECT last_name FROM employees WHERE hire_date > ''' || start_date || '''';

start_dateのデータ型はDATEです。

前述の例では、start_dateの値はセッション・パラメータNLS_DATE_FORMATで指定された書式モデルを使用してテキストに変換されます。結果は、連結されてSQLテキストになります。日時書式モデルは、単純に二重引用符で囲んだリテラル・テキストで構成できます。したがって、セッションのグローバリゼーション・パラメータを明示的に設定できるすべてのユーザーが、前述の変換で生成されるテキストを決定できます。SQL文がPL/SQLプロシージャによって実行される場合、そのプロシージャはセッション・パラメータによるSQLインジェクションに対して脆弱になります。セッション自体より強い権限である定義者の権限でプロシージャが実行されると、ユーザーは機密データに不正にアクセスすることができます。


関連項目:

他の例およびこのセキュリティ・リスクを回避する場合の推奨事項については、『Oracle Database PL/SQL言語リファレンス』を参照してください。


注意:

このセキュリティ・リスクは、データベースまたはOCI日時ファンクションによってテキストに変換された日時値からSQLテキストを構成する中間層アプリケーションにも該当します。セッションのグローバリゼーション・パラメータがユーザー・プリファレンスから取得される場合、それらのアプリケーションは脆弱になります。

数値の暗黙的および明示的な変換でも、変換結果がセッション・パラメータNLS_NUMERIC_CHARACTERSに依存する場合があるため、類似した問題が発生する可能性があります。このパラメータは、小数点区切り文字および桁区切り文字を定義します。小数点区切りを一重引用符または二重引用符と定義すると、SQLインジェクションが発生する可能性があります。


関連項目:

  • セッションのグローバリゼーション・パラメータの詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照してください。

  • 書式モデルの詳細は、「書式モデル」を参照してください。