Changed behaviour of java.sql.Date after OJBC client upgrade
从11.2.0版升级到12.1.0版之后,我在将java.sql.date对象绑定到PreparedStatement时遇到了不同的行为。
在准备好的语句中,主机变量"f.plan_date=?"应该与java.util.date对象的值绑定,该值是代码中其他地方获得的输入。Oracle表中的列数据类型为"日期",只应考虑日期部分-时间不相关。
我以以下方式翻译java.sql.date对象中的java.util.date对象:statementRegisterJobs.setDate(3, new java.sql.Date(planDate.getTime()));。
这对11.2.0客户机很好。然而,在升级到12.1.0之后,事情往往会出错。不再检索任何记录。经过数小时的调试,我发现这个问题与日期变量有关。以下工作方式将我的记录返回:江户十一〔一〕号
有人能解释一下这种行为吗?日期对象最终可以有一个时间组件,我有一种未定义的感觉,这可能与问题有关。另一方面,无论对象是如何构造的,以下各项都应该说明java.sql.date中忽略了时间组件…
- 在java. SQLDATA的Java 6 API中,我发现了以下语句:"此方法被弃用,不应该使用,因为SQL日期值没有时间组件。"(方法"GethOrthSe()))。因此,这意味着在将java.util.date转换为java.sql.date时忽略时间方面。
- 这由构造函数文档中的信息确认:"使用给定的毫秒时间值构造日期对象。如果给定的毫秒值包含时间信息,则驱动程序将时间组件设置为默认时间区(运行应用程序的Java虚拟机的时区)对应于零GMT的时间。
- 此外,我无法从java.sql.date对象中获得可能的时间方面:toString()只给出日期,gethours()抛出异常。
- 这与JDBC客户机中的更新有什么关系?
感谢您的任何想法:)非常感谢。
- 只是一些基本的想法:我们也处理日期,但是首先实例化一个公历日历,将所有时间片段设置为0,并用setTimestamp(...)初始化这个对象中准备好的语句。很好用,但数据库不是ora,而是mysql。
- 可能更有用的方法是引用构造函数的文档,它以一种迂回的方式表示时间被剥夺了。您是否验证了参数在Oracle端的实际时间?是计划日期时间(如果有),还是时区问题?
- 在数据库中,只存储一个日期,而不存储时间。我想那时可能是默认的00:00:00。(如果我用toad检查字段信息,则会标记"空时间"。)
- 约会总是有时间的,即使是午夜。我在问数据库所看到的绑定值是什么。您可以查询EDOCX1[1]并绑定相同的plandate值,然后查看返回的内容,以及与您在plandate中期望的内容的比较情况。
- 在定义了以下变量之后:java.util.Date utilDate = new Date();、java.sql.Date sqlDate1 = new java.sql.Date(utilDate.getTime());和java.sql.Date sqlDate2 = java.sql.Date.valueOf("2014-08-27");并将它们与您提出的声明(SELECT to_char(?, 'YYYY-MM-DD HH24:MI:SS') testDate FROM dual结合起来,我想我对这个问题有了更多的了解。
- 使用11.2.0客户端,结果是"2014-08-27 00:00:00:00"两次。使用12.1.0客户端,sqldate2的结果是"2014-08-27 00:00:00",sqldate1的结果是"2014-08-27 14:47:29"。所以新客户会考虑时间-这对我来说是意想不到的行为,你呢?
- 我无法将此行为与java.sql.date(构造函数)的api中所述的行为匹配:"使用给定的毫秒时间值构造日期对象。如果给定的毫秒值包含时间信息,则驱动程序将时间组件设置为默认时间区(运行应用程序的Java虚拟机的时区)对应于零GMT的时间。
- @alexpoole时间在java.sql.Date中没有被剥夺,这取决于驱动程序;如果Oracle驱动程序没有这样做,这是驱动程序中的一个错误。
- JDBC驱动程序发生了变化,驱动程序开始以java.sql.Timestamp的形式从DATE列返回值,因为否则时间部分会丢失(java.sql.Date删除时间)。但这一变化发生在10.x驱动程序中的某个地方,而不是从11.x到12.x,您可以告诉驱动程序通过提供连接参数将DATE处理为"实际"日期。参见jdbc常见问题解答:oracle.com/technetwork/database/enterprise edition/…
- @马克罗特韦尔:那不是由司机决定的。检查javadocs中的java.sql.Date。它们清楚地指出:"为了符合SQL日期的定义,java.sql.date实例包装的毫秒值必须通过在与实例关联的特定时区中将小时、分钟、秒和毫秒设置为零来"规范化"。
- @一匹没有名字但司机仍然需要在当地时区将时间设置为00:00,当它收到一个java.sql.Date而不是一个java.sql.Timestamp时。注意,JDBCAPI文档有时会令人困惑,因为它同时面向驱动程序开发人员和JDBC用户。"零ing"行为也在java.sql.Date构造函数中指定。
opposed to the Java API是美国java.sql.date when creating a模式,通过在对象的显示时间值的时间似乎milliseconds to be stored in the object and is not to when using the 12.1.0 defaulted零ojdbc司机。P></
This is the测试集上:P></
1 2 3
| java. util. Date utilDate = new Date();
java. sql. Date sqlDate1 = new java. sql. Date(utilDate. getTime());
java. sql. Date sqlDate2 = java. sql. Date. valueOf("2014-08-27"); |
这些由the following statement(SELECT to_char(?, 'YYYY-MM-DD HH24:MI:SS') testDate FROM dual),都有binded sqldate1和sqldate2和下面的结果。P></
与11.2.0驱动程序版本P></
- sqldate1:2014-08-27 00:00:00
- sqldate2:2014-08-27 00:00:00
与12.1.0驱动程序版本P></
- sqldate1:2014-08-27 14:47:29
- sqldate2:2014-08-27 00:00:00
this is not in line with the documentation in the API:P></
If the given milliseconds value contains time information, the driver
will set the time components to the time in the default time zone (the
time zone of the Java virtual machine running the application) that
corresponds to zero GMT.
不管一个人多,这个问题可以knowing fix the by the time of the SQL信息forcing to be午夜日期对象。P></
- 您可能还需要考虑向Oracle提交一份bug报告。
- 下面是Oracle论坛上相关的threda:community.oracle.com/thread/3826309?start=0&tstart=0显然是故意的,不被视为错误…