Ответ 1
Полная информация (и она более сложная, чем описано здесь, и может зависеть от того, какая именно версия драйверов Oracle используется) в ответе Ричарда Йи здесь - [теперь истек срок действия ссылки на Nabble]
Быстрый захват до истечения срока его действия...
Roger, См.: http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-faq-090281.html#08_01
В частности: Простые типы данных Что происходит с DATE и TIMESTAMP? Этот раздел посвящен простым типам данных.: -)
До 9.2 драйверы JDBC Oracle сопоставили тип DATE SQL с java.sql.Timestamp. Это сделало определенный смысл, потому что тип SQL DATE SQL содержит информацию о дате и времени, как и java.sql.Timestamp. Более очевидное сопоставление с java.sql.Date было несколько проблематичным, поскольку java.sql.Date не включает информацию о времени. Кроме того, СУБД не поддерживало тип SQL TIMESTAMP, поэтому не было проблемы с отображением DATE в Timestamp.
В 9.2 поддержка СУБД TIMESTAMP была добавлена в СУБД. Разница между DATE и TIMESTAMP заключается в том, что TIMESTAMP включает наносекунды, а DATE - нет. Итак, начиная с 9.2, DATE сопоставляется с Date и TIMESTAMP сопоставляется с Timestamp. К сожалению, если вы полагались на значения DATE, чтобы содержать информацию о времени, возникает проблема.
Существует несколько способов решения этой проблемы:
Измените свои таблицы, чтобы использовать TIMESTAMP вместо DATE. Это, вероятно, редко возможно, но это лучшее решение, когда оно есть.
Измените приложение, чтобы использовать defineColumnType для определения столбцов как TIMESTAMP, а не DATE. Есть проблемы с этим, потому что вы действительно не хотите использовать defineColumnType, если вам не нужно (см. Что такое defineColumnType и когда я должен его использовать?).
Измените приложение, чтобы использовать getTimestamp, а не getObject. Это хорошее решение, когда это возможно, однако многие приложения содержат общий код, который полагается на getObject, поэтому это не всегда возможно.
Задайте свойство V8Compatible connection. Это говорит о том, что драйверы JDBC используют старое сопоставление, а не новое. Вы можете установить этот флаг как свойство соединения или системное свойство. Вы устанавливаете свойство соединения, добавляя его в объект java.util.Properties, переданный в DriverManager.getConnection или в OracleDataSource.setConnectionProperties. Вы устанавливаете системное свойство, включая параметр -D в вашей командной строке java.
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 сопоставляться с Timestamp при чтении из базы данных, но также приводила к тому, что все временные метки были преобразованы в SQL DATE при записи в базу данных. Поскольку 8i деспопортируется, 11.1 JDBC-драйверы не поддерживают этот режим совместимости. По этой причине V8Compatible не поддерживается.
Как упоминалось выше, драйверы 11.1 по умолчанию конвертируют SQL DATE в Timestamp при чтении из базы данных. Это всегда было правильным делом, и изменение в 9i было ошибкой. Драйверы 11.1 вернулись к правильному поведению. Даже если вы не установили V8Compatible в своем приложении, вы не должны видеть различий в поведении в большинстве случаев. Вы можете заметить разницу, если вы используете getObject для чтения столбца DATE. Результатом будет Timestamp, а не Date. Поскольку Timestamp является подклассом Date, это обычно не проблема. Если вы заметили, что разница заключается в том, что вы полагались на преобразование из DATE в Date, чтобы усечь компонент времени, или если вы делаете toString по значению. В противном случае изменение должно быть прозрачным.
Если по какой-то причине ваше приложение очень чувствительно к этому изменению, и вы просто должны иметь поведение 9i-10g, есть свойство соединения, которое вы можете установить. Установите mapDateToTimestamp в false, и драйвер вернется к поведению 9i-10g по умолчанию и карте DATE в Date.
Если возможно, вы должны изменить свой тип столбца на TIMESTAMP вместо DATE.
-Ричард
Роджер Восс писал: Я отправил следующий вопрос/проблему в stackoverflow, поэтому, если кто-нибудь знает разрешение, было бы хорошо, если бы он ответил там:
Проблема преобразования Oracle SQL DATE с использованием iBATIS через Java JDBC
Здесь описание проблемы:
В настоящее время я борюсь с проблемой преобразования данных SQL в Oracle с использованием iBATIS из Java.
Я использую тонкий драйвер Oracle JDBC ojdbc14 версии 10.2.0.4.0. iBATIS версия 2.3.2. Java 1.6.0_10-rc2-b32.
Проблема вращается вокруг столбца типа DATE, возвращаемого этим фрагментом SQL:
SELECT * FROM TABLE (pk_invoice_qry.get_contract_rate (?,?,?,?,?,?,?,?,?,?)) Order by_date
Вызов процедуры пакета возвращает курсор ref, который обертывается в TABLE, где легко читается набор результатов, как если бы это был запрос выбора к таблице.
В PL/SQL Developer один из возвращаемых столбцов, FROM_DATE, типа SQL DATE, имеет точность до времени суток:
Tue Dec 16 23:59:00 PST 2008
Но когда я получаю доступ к этому через iBATIS и JDBC, значение сохраняет только точность до дня:
Tue Dec 16 12:00:00 AM PST 2008
Это становится яснее, когда отображается так:
Должно быть: 1229500740000 миллисекунд с эпохи Вторник, 16 декабря 2008 г. 11:59:00 PM PST
Но вместо этого: 1229414400000 миллисекунд с эпохи Вторник, 16 декабря 2008 г. 12:00:00 AM PST (как экземпляр класса java.sql.Date)
Независимо от того, что я пытаюсь, я не могу показать полную точность этого столбца DATE, который будет возвращен через Java JDBC и iBATIS.
То, что iBATIS отображает, таково:
FROM_DATE: 2008-12-03: класс java.sql.Date
Текущее отображение iBATIS:
Я также пробовал:
или
Но все попытки сопоставления дают одно и то же усеченное значение даты. Как будто JDBC уже допустил повреждение потери точности данных, прежде чем iBATIS даже коснется его.
Ясно, что я теряю часть своей точности данных, просматривая JDBC и iBATIS, чего не происходит, когда я остаюсь в PL/SQL Developer, использующем тот же фрагмент SQL в качестве теста script. Неприемлемый вообще, очень расстраивающий, и в конечном счете очень страшный.