Полная информация (и она более сложная, чем описанная здесь и может зависеть от того, какая конкретная версия драйверов Oracle используется) содержится в ответе Ричарда Йи - [ссылка на Nabble устарела]
Быстрый захват до истечения срока действия ...
Roger,
Смотри: 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 не включает информацию о времени. Был также случай, когда СУБД не поддерживала тип SQL TIMESTAMP, поэтому не было проблем с отображением DATE в Timestamp.
В 9.2 добавлена поддержка TIMESTAMP для RDBMS. Разница между DATE и TIMESTAMP заключается в том, что TIMESTAMP включает наносекунды, а DATE - нет. Итак, начиная с 9.2, DATE отображается на Date, а TIMESTAMP отображается на Timestamp. К сожалению, если вы полагались на значения DATE для хранения информации о времени, возникла проблема.
Существует несколько способов решения этой проблемы:
Измените ваши таблицы, чтобы использовать TIMESTAMP вместо DATE. Это, вероятно, редко возможно, но это лучшее решение, когда оно есть.
Измените ваше приложение, чтобы использовать defineColumnType для определения столбцов как TIMESTAMP, а не DATE. Есть проблемы с этим, потому что вы действительно не хотите использовать defineColumnType, если не обязаны (см. Что такое defineColumnType и когда я должен его использовать?).
Измените ваше приложение, чтобы использовать getTimestamp вместо getObject. Это хорошее решение, когда это возможно, однако многие приложения содержат общий код, основанный на getObject, поэтому это не всегда возможно.
Установить свойство соединения V8Compatible. Это говорит драйверам 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 для получения правильного сопоставления. Совместимость с V8 настоятельно не рекомендуется. Вы не должны использовать это вообще. Если вы установите значение true, это ничего не повредит, но вы должны прекратить его использование.
Хотя он редко использовался таким образом, V8Compatible существовал не для устранения проблемы DATE to Date, а для поддержки совместимости с базами данных 8i. 8i (и более старые) базы данных не поддерживают тип TIMESTAMP. Установка V8Compatible не только заставляла SQL DATE отображаться в метку времени при чтении из базы данных, но также приводила к тому, что все метки времени конвертировались в SQL DATE при записи в базу данных. Поскольку 8i не поддерживается, драйверы JDBC 11.1 не поддерживают этот режим совместимости. По этой причине V8Compatible не поддерживается.
Как упоминалось выше, драйверы 11.1 по умолчанию преобразуют SQL DATE в метку времени при чтении из базы данных. Это всегда было правильно, и изменение в 9i было ошибкой. Драйверы 11.1 вернулись к правильному поведению. Даже если вы не установили V8Compatible в своем приложении, вы не должны видеть никакой разницы в поведении в большинстве случаев. Вы можете заметить разницу, если вы используете getObject для чтения столбца DATE. Результатом будет отметка времени, а не дата. Так как Timestamp является подклассом Date, это обычно не проблема. Вы можете заметить разницу, если вы полагались на преобразование DATE в Date для усечения компонента времени или если вы делали toString для значения. В противном случае изменение должно быть прозрачным.
Если по какой-то причине ваше приложение очень чувствительно к этому изменению, и вы просто должны иметь поведение 9i-10g, есть свойство соединения, которое вы можете установить. Установите для mapDateToTimestamp значение false, и драйвер вернется к поведению по умолчанию 9i-10g и отобразит DATE на Date.
Если возможно, вы должны изменить тип столбца на TIMESTAMP вместо DATE.
-Ричард
Роджер Восс писал:
Я разместил следующий вопрос / проблему на stackoverflow, поэтому, если кто-то знает решение, было бы неплохо увидеть его ответ там:
Проблема преобразования Oracle SQL DATE с использованием iBATIS через Java JDBC
Вот описание проблемы:
В настоящее время я борюсь с проблемой преобразования sql DATE в Oracle, используя iBATIS из Java.
Я использую тонкий драйвер Oracle JDBC ojdbc14 версии 10.2.0.4.0. iBATIS версия 2.3.2. Java 1.6.0_10-rc2-b32.
Проблема вращается вокруг столбца типа DATE, который возвращается этим фрагментом SQL:
ВЫБРАТЬ *
FROM TABLE (pk_invoice_qry.get_contract_rate (?,?,?,?,?,?,?,?,?,?)) Заказ от from_date
Вызов процедуры пакета возвращает курсор ref, помещенный в TABLE, туда, где затем легко прочитать набор результатов, как если бы это был запрос select к таблице.
В 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 г., 23:59 PST
Но вместо этого:
1229414400000 миллисекунд с начала эпохи
Вторник, 16 декабря 2008 г., 12:00:00 по тихоокеанскому времени
(как экземпляр класса java.sql.Date)
Независимо от того, что я пытаюсь, я не могу предоставить полную точность этого столбца DATE, который будет возвращен через Java JDBC и iBATIS.
Из чего отображается iBATIS:
FROM_DATE: 2008-12-03: класс java.sql.Date
Текущее отображение iBATIS таково:
Я также пробовал:
* * Или тысяча семьдесят-девять
Но все попытки сопоставления дают одинаковое усеченное значение Date. Как будто JDBC уже нанес ущерб потере точности данных еще до того, как iBATIS коснулся их.
Очевидно, что я теряю некоторую точность своих данных, проходя через JDBC и iBATIS, чего не происходит, когда я остаюсь в PL / SQL Developer, использующем тот же фрагмент SQL, что и тестовый скрипт. Совсем неприемлемо, очень расстраивает и в конечном итоге очень пугает.