前几天我遇到了一个类似的问题,一些日期的时间组件被截断了。
我们把问题缩小到Oracle驱动程序版本的差异。
在Oracle的常见问题解答中有一个关于此问题的部分:
select sysdate from dual; ...while(rs.next())
在9201之前,这将返回:
sysdate的getObject: java.sql.Timestamp <<<<
sysdate的getDate: java.sql.Date
sysdate的getTimestamp: java.sql.Timestamp
从9201开始,将返回以下内容:
sysdate的getObject: java.sql.Date <<<<
sysdate的getDate: java.sql.Date >>没有更改
sysdate的getTimestamp: java.sql.Timestamp >>没有更改
注意:java.sql.Date没有时间部分,而java.sql.Timestamp有。
随着数据类型映射的更改,当JDBC驱动程序从8i/9iR1升级到920x JBDC驱动程序时,一些应用程序将失败和/或生成不正确的结果。为了在升级后保持兼容性并使应用程序正常工作,提供了一个兼容性标志。现在开发人员有一些选择:
1. 使用oracle.jdbc.V8Compatible标志。
默认情况下,JDBC驱动程序不会检测数据库版本。要更改处理TIMESTAMP数据类型的兼容性标志,请设置连接属性oracle.jdbc.V8Compatible为“true”,驱动程序将像8i、901x、9200一样处理TIMESTAMP。
默认情况下,标志设置为“false”。在OracleConnection构造函数中,驱动程序获取服务器版本并相应地设置兼容性标志。
java.util.Properties prop=newjava.util.Properties()
prop.put("oracle.jdbc.V8Compatible","true")
prop.put("user","scott")
prop.put("password","tiger")
String url="jdbc:oracle:thin:@host:port:sid"
Connection conn = DriverManager.getConnection(url,prop)
使用 JDBC 10.1.0.x 版本时,可以使用以下系统属性代替连接属性:java -Doracle.jdbc.V8Compatible=true......注意:此标志仅为客户端标志,用于管理时间戳和日期映射。它不会影响任何数据库特性。
2. 当处理日期和时间戳列数据类型时,请相应地使用 set/getDate 和 set/getTimestamp。
9i 服务器支持日期和时间戳列类型,DATE 映射到 java.sql.Date,TIMESTAMP 映射到 java.sql.Timestamp。
因此,对于我的情况,我有如下代码:
import java.util.Date
Date d = rs.getDate(1)
在使用9i时,我得到了一个java.sql.Timestamp(它是java.util.Date的子类),所以一切都很好,我有了小时和分钟。
但是在使用10g时,相同的代码现在得到了一个java.sql.Date(也是java.util.Date的子类,因此仍然可以编译),但是HH:MM被截断了!
第二个解决方案对我来说非常简单-只需将getDate替换为getTimestamp,你就应该没问题了。我想那是一个坏习惯。