完全な情報 (ここで説明されているよりも複雑で、使用されている Oracle ドライバーの特定のバージョンに依存する可能性があります) は、Richard Yee の回答 (現在期限切れになっている Nabble へのリンク) にあります。
nabble から有効期限が切れる前にクイック グラブ...
ロジャー、参照: http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-faq-090281.html#08_01
具体的には: 単純なデータ型 DATE と TIMESTAMP で何が起こっているのでしょうか? このセクションでは、単純なデータ型について説明します。:-)
9.2 より前では、Oracle JDBC ドライバーは DATE SQL タイプを java.sql.Timestamp にマップしていました。Oracle DATE SQL 型には、java.sql.Timestamp と同様に日付と時刻の両方の情報が含まれているため、これにはある程度の意味がありました。java.sql.Date へのより明白なマッピングは、java.sql.Date に時刻情報が含まれていないため、やや問題がありました。また、RDBMS が TIMESTAMP SQL 型をサポートしていなかったため、DATE を Timestamp にマッピングしても問題はありませんでした。
9.2 では、TIMESTAMP サポートが RDBMS に追加されました。DATE と TIMESTAMP の違いは、TIMESTAMP にはナノ秒が含まれ、DATE には含まれないことです。そのため、9.2 以降、DATE は Date にマップされ、TIMESTAMP は Timestamp にマップされます。残念ながら、時間情報を含めるために DATE 値に依存していた場合、問題があります。
この問題に対処するには、いくつかの方法があります。
DATE の代わりに TIMESTAMP を使用するようにテーブルを変更します。これはおそらくめったに可能ではありませんが、可能な場合は最善の解決策です。
アプリケーションを変更して、defineColumnType を使用して列を DATE ではなく TIMESTAMP として定義します。これには問題があります。なぜなら、必要でない限り defineColumnType を使用したくないからです (defineColumnType とは何か、いつ使用する必要があるかを参照してください)。
getObject ではなく getTimestamp を使用するようにアプリケーションを変更します。可能であればこれは良い解決策ですが、多くのアプリケーションには getObject に依存する汎用コードが含まれているため、常に可能であるとは限りません。
V8Compatible 接続プロパティを設定します。これにより、JDBC ドライバーは新しいマッピングではなく古いマッピングを使用するようになります。このフラグは、接続プロパティまたはシステム プロパティとして設定できます。DriverManager.getConnection または OracleDataSource.setConnectionProperties に渡される java.util.Properties オブジェクトに接続プロパティを追加して、接続プロパティを設定します。システム プロパティを設定するには、Java コマンド ラインに -D オプションを含めます。
java -Doracle.jdbc.V8Compatible="true" MyApp Oracle JDBC 11.1 では、この問題が修正されています。このリリース以降、ドライバーはデフォルトで SQL DATE 列を java.sql.Timestamp にマップします。正しいマッピングを取得するために V8Compatible を設定する必要はありません。V8Compatible は非推奨です。絶対に使用しないでください。true に設定しても問題はありませんが、使用を中止する必要があります。
そのように使用されることはほとんどありませんでしたが、V8Compatible は DATE to Date の問題を修正するためではなく、8i データベースとの互換性をサポートするために存在していました。8i (およびそれ以前) のデータベースは、TIMESTAMP タイプをサポートしていませんでした。V8Compatible を設定すると、データベースからの読み取り時に SQL DATE がタイムスタンプにマップされるだけでなく、データベースへの書き込み時にすべてのタイムスタンプが SQL DATE に変換されます。8i はサポートされなくなったため、11.1 JDBC ドライバーはこの互換モードをサポートしません。このため、V8Compatible はサポートされなくなりました。
前述のように、11.1 ドライバーはデフォルトで、データベースから読み取るときに SQL DATE を Timestamp に変換します。これは常に正しいことであり、9i での変更は間違いでした。11.1 ドライバーは正しい動作に戻りました。アプリケーションで V8Compatible を設定していなくても、ほとんどの場合、動作に違いは見られません。getObject を使用して DATE 列を読み取ると、違いに気付く場合があります。結果は、日付ではなくタイムスタンプになります。Timestamp は Date のサブクラスであるため、これは通常問題になりません。違いに気付くのは、DATE から Date への変換に依存して時間コンポーネントを切り捨てた場合、または値に対して toString を実行した場合です。それ以外の場合、変更は透過的でなければなりません。
何らかの理由でアプリがこの変更に非常に敏感で、単に 9i-10g の動作が必要な場合は、設定できる接続プロパティがあります。mapDateToTimestamp を false に設定すると、ドライバーはデフォルトの 9i-10g の動作に戻り、DATE を Date にマップします。
可能であれば、列の型を DATE ではなく TIMESTAMP に変更してください。
-リチャード
Roger Voss は次のように書いています: 私は以下の質問/問題を stackoverflow に投稿しました。
Java JDBC経由でiBATISを使用したOracle SQL DATE変換の問題
問題の説明は次のとおりです。
私は現在、Java から iBATIS を使用して Oracle sql DATE 変換の問題に取り組んでいます。
Oracle JDBC シン ドライバー ojdbc14 バージョン 10.2.0.4.0 を使用しています。iBATIS バージョン 2.3.2。Java 1.6.0_10-rc2-b32。
この問題は、次の SQL スニペットによって返される DATE 型の列に関係しています。
SELECT * FROM TABLE(pk_invoice_qry.get_contract_rate(?,?,?,?,?,?,?,?,?,?)) 日付順
パッケージ プロシージャ コールは、TABLE にラップされている ref カーソルを返します。これにより、テーブルに対する選択クエリであるかのように、結果セットを簡単に読み取ることができます。
PL/SQL Developerでは、返される列の1つであるSQL DATE型のFROM_DATEは、時刻までの精度を持っています:
Tue Dec 16 23:59:00 PST 2008
しかし、iBATIS と JDBC を介してこれにアクセスすると、値は現在までの精度しか保持されません。
Tue Dec 16 12:00:00 AM PST 2008
これは、次のように表示するとより明確になります。
エポックから 1229500740000 ミリ秒 2008 年 12 月 16 日火曜日午後 11:59:00 PST
しかし、代わりにこれを取得します: エポックから 1229414400000 ミリ秒 2008 年 12 月 16 日火曜日 12:00:00 AM PST (クラス java.sql.Date のインスタンスとして)
何を試しても、Java JDBC および iBATIS を介して返されるこの DATE 列の完全な精度を公開することはできません。
iBATIS のマッピング元は次のとおりです。
FROM_DATE : 2008-12-03 : クラス java.sql.Date
現在の iBATIS マッピングは次のとおりです。
私も試しました:
また
ただし、試行されたすべてのマッピングは、切り捨てられた同じ Date 値を生成します。あたかも、iBATIS が触れる前に、JDBC がデータの精度を失うという損害をすでに受けているかのようです。
明らかに、JDBC と iBATIS を使用することでデータの精度がいくらか失われていますが、これは、テスト スクリプトと同じ SQL スニペットを実行している PL/SQL Developer にとどまっている場合には発生しません。まったく受け入れられず、非常にイライラし、最終的には非常に恐ろしい.