暗黙的な変換
暗黙変換とは、あるデータ型から別のデータ型への変換が意味を持つ場合、Oracle データベースは値を自動的に変換する仕組みであり、意味を成さない変換の場合にはエラーとなる。
暗黙変換も関数の一つ (CAST 関数) と考えることができるのでカラムに適用されるとインデックスが使用されなくなる。
条件述語(条件文)における暗黙変換には細心の注意を払い、変換したい方に対して 常に明示的 に変換する事を薦めます。
日付と文字列における暗黙変換
日付と文字列の比較ルール
日付と文字列を比較する場合には文字列を日付に変換してから比較する。もし文字列を日付に変換できない場合には ORA-01840 周辺の日付の指定項目に関するエラーや ORA-01861: リテラルが書式文字列と一致しません が発生する。
日付と文字列の演算ルール
・SYSDATE - '2002/12/01' ⇒ SYSDATE - TO_NUMBER('2002/12/01')
… 暗黙変換は数値なのでエラー
・WHERE dateColumn >= '2004/10/01'
⇒ WHERE dateColumn >= TO_DATE('RRRR/MM/DD', dateColumn')
RRRR[d]MM[d]DD はRRRR MM DD フォーマット(※)
[d]は日付書式用デリミタの任意の文字(省略可)
[d] = ['-'|'/'|','|'.'|';'|':']
暗黙変換には NLS_DATE_FORMAT 初期化パラメータ のフォーマットが利用される。
日付と数値における暗黙変換
日付と数値の演算ルール
日付 ± 数値 ⇒ 日付
日付の加算、減算ができるのは一般的によく知られた技法
・SYSDATE + 1.5 ⇒ SYSDATE + NUMTODSINTERVAL(1.5, 'DAY')
・SYSDATE + 1 ⇒ 明日の同じ時刻
・SYSDATE + 5/(24*60*60) ⇒ 5秒後
しかし、これは「旧式」の記法で今では INTERVAL 表記 を使う方がスマート(※)。
年〜月
・SYSDATE + INTERVAL '1-11' YEAR TO MONTH ⇒ 1年月11ヵ月後
・SYSDATE + INTERVAL '1' YEAR ⇒ 1年後
日付デリミタは'-'のみ有効('/'などは不可)
日〜秒
・SYSDATE + INTERVAL '1 23:25:59' DAY TO SECOND
・SYSDATE + INTERVAL '1' DAY
・SYSDATE + INTERVAL '100' DAY(3)
・SYSDATE + INTERVAL '5' SECOND
日付デリミタは日時の間は' '、時刻間は':'のみ有効('.'などは不可)
年〜月と日〜秒は、同一リテラルに記述できない。
(※ 要注意) ただし、INTERVAL による加減算は末日処理されないという最大かつ致命的な欠点もあるので注意する(場合によって ADD_MONTHS を使用する)。
以下の SQL はエラーになる。
SELECT
DATE '2000-01-31' + INTERVAL '1' MONTH
FROM DUAL ;
日付と日付の加算と減算
- 日付 - 日付 ⇒ 期間型 または 数値
- 日付 + 日付 ⇒ 許可されていないのでエラーになる。一方に期間型か数値を使わなければいけない。
数値と文字列における暗黙変換
数値と文字列の比較ルール
数値と文字列を比較する場合には 文字列を数値 に変換してから比較する。もし文字列を数値に変換できない場合には ORA-01722: 数値が無効です。 が発生する。
数値と文字列の演算ルール
・100 ⇔ '100'
・234 + '10E+2' ⇒ 234 + TO_NUMBER('10E+2') ⇒ 1234
・'-10' + '5' = ⇒ TO_NUMBER('-10') + TO_NUMBER('5') ⇒ -5
・5555 || '0' ⇒ 'TO_CHAR('5555') || '0' ⇒ '55550'
・'10a' + 5 ⇒ エラー(※ 10 + 5 = 15 にはならない )
・'1' = 2 ⇒ FALSE
・'X' = 1 ⇒ エラー(※ 'X' を数値に変換しようとするため ORA-01722 が発生する)
1 を '1' に変換はしない
数値と数値における暗黙変換
数値同士の間でも暗黙変換は発生する。
BINARY_DOUBLE と NUMBER を算術すると、BINARY_DOUBLE になる。
数値同士であっても、以下のような暗黙変換の優先順位がある。
BINARY_DOUBLE > BINARY_FLOAT > NUMBER の順となる。
数値の優先順位 | 数値のデータ型 |
1 | BINARY_DOUBLE |
2 | BINARY_FLOAT |
3 | NUMBER |
変換に関連 SQL 関数