つまり、OracleのタイムスタンプとOracleの日付は2つの異なるデータ型です。タイムスタンプを日付と比較するために、Oracleは変換を実行する必要があります-そのINTERNAL_FUNCTION()。興味深い設計上の決定は、Oracleが渡された値ではなくテーブル列を変換することです。これは、クエリがインデックスを使用しなくなったことを意味します。
SQL * Plusでシナリオを再現できたので、java.sql.Timestamp
を使用しても問題ありません。 。渡されたタイムスタンプを日付にキャストすると、問題は解決します...
SQL> explain plan for
2 select * from test1
3 where d1 > cast(to_timestamp('01-MAY-2011 00:00:00.000', 'DD-MON-YYYY Hh24:MI:SS.FF') as date)
4 and d2 > cast(to_timestamp('01-JUN-2011 23:59:59.999', 'DD-MON-YYYY Hh24:MI:SS.FF') as date)
5 /
Explained.
SQL> select * from table(dbms_xplan.display)
2 /
PLAN_TABLE_OUTPUT
-----------------------------------------------------------
Plan hash value: 1531258174
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 25 | 500 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST1 | 25 | 500 | 3 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T1_I | 1 | | 2 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------
2 - access("D1">CAST(TO_TIMESTAMP('01-MAY-2011 00:00:00.000','DD-MON-YYYY
Hh24:MI:SS.FF') AS date) AND "D2">CAST(TO_TIMESTAMP('01-JUN-2011
23:59:59.999','DD-MON-YYYY Hh24:MI:SS.FF') AS date) AND "D1" IS NOT NULL)
filter("D2">CAST(TO_TIMESTAMP('01-JUN-2011 23:59:59.999','DD-MON-YYYY
Hh24:MI:SS.FF') AS date))
18 rows selected.
SQL>
しかし、それがあなたに役立つとは思いません。代わりに日付を渡す方が簡単でしょう。
興味深いことに、日付列をタイムスタンプにキャストする関数ベースのインデックスを作成しても役に立ちません。 INTERNAL_FUNCTION()
呼び出しはCAST()
として認識されません インデックスは無視されます。 INTERNAL_FUNCTION()
を使用してインデックスを作成しようとしています ORA-00904を投げます。