Пълната информация (и тя е по-сложна от описаната тук и може да зависи от това коя конкретна версия на драйверите на 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. Това имаше известен смисъл, тъй като SQL типът Oracle DATE съдържа информация за дата и час, както и java.sql.Timestamp. По-очевидното съпоставяне към java.sql.Date беше донякъде проблематично, тъй като java.sql.Date не включва информация за времето. Също така беше така, че RDBMS не поддържаше SQL типа TIMESTAMP, така че нямаше проблем с преобразуването на DATE в Timestamp.
В 9.2 поддръжката на TIMESTAMP беше добавена към RDBMS. Разликата между DATE и TIMESTAMP е, че TIMESTAMP включва наносекунди, а DATE не. И така, започвайки от 9.2, 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" MyAppOracle JDBC 11.1 коригира този проблем. Започвайки с това издание, драйверът съпоставя колоните на SQL DATE в java.sql.Timestamp по подразбиране. Не е необходимо да задавате V8Compatible, за да получите правилното съпоставяне. V8Compatible е силно отхвърлен. Не трябва да го използвате изобщо. Ако го зададете на true, няма да навреди нищо, но трябва да спрете да го използвате.
Въпреки че рядко се използваше по този начин, V8Compatible съществуваше не за отстраняване на проблема от DATE до дата, а за да поддържа съвместимост с бази данни 8i. 8i (и по-стари) бази данни не поддържат типа TIMESTAMP. Настройката V8Compatible не само накара SQL DATE да бъде съпоставена с Timestamp при четене от базата данни, но също така доведе до преобразуване на всички Timestamp в 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 и ще съпостави ДАТА с дата.
Ако е възможно, трябва да промените типа на колоната си на TIMESTAMP вместо DATE.
-Ричард
Роджър Вос написа:Публикувах следния въпрос/проблем в stackoverflow, така че ако някой знае решение, би било добре да види отговора там:
Проблем с преобразуването на Oracle SQL DATE при използване на iBATIS чрез Java JDBC
Ето описанието на проблема:
В момента се боря с проблем с преобразуването на Oracle sql DATE, използвайки iBATIS от Java.
Използвам тънкия драйвер на Oracle JDBC ojdbc14 версия 10.2.0.4.0. iBATIS версия 2.3.2. Java 1.6.0_10-rc2-b32.
Проблемът се върти около колона от тип DATE, която се връща от този фрагмент от SQL:
ИЗБЕРЕТЕ *ОТ ТАБЛИЦА(pk_invoice_qry.get_contract_rate(?,?,?,?,?,?,?,?,?,?)) поръчайте от_дата
Извикването на пакетната процедура връща 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 г., 23:59:00 PST
Но получаването на това вместо това:1229414400000 милисекунди от епохата вторник, 16 декември 2008 г. 00:00:00 PST (като екземпляр на клас java.sql.Date)
Каквото и да опитам, не мога да изложа пълната прецизност на тази колона ДАТА, която да бъде върната чрез Java JDBC и iBATIS.
Това, от което iBATIS картографира, е това:
FROM_DATE :2008-12-03 :клас java.sql.Date
Текущото съпоставяне на iBATIS е следното:
Опитах също:
или
Но всички опити за съпоставяне дават една и съща съкратена стойност за дата. Сякаш JDBC вече е нанесъл вредата от загубата на прецизност на данните, преди iBATIS дори да ги докосне.
Очевидно губя част от прецизността на данните си, преминавайки през JDBC и iBATIS, което не се случва, когато остана в PL/SQL Developer, изпълнявайки същия SQL фрагмент като тестов скрипт. Изобщо неприемливо, много разочароващо и в крайна сметка много страшно.