前几天我遇到了一个类似的问题,时间部分从某些日期被截断。
我们将其缩小到 Oracle 驱动程序版本的差异。
在 Oracle 的常见问题解答中有一个关于此的部分:
select sysdate from dual; ...while(rs.next())
在 9201 之前,这将返回: getObject for sysdate : java.sql.Timestamp <<<< getDate for sysdate : java.sql.Date getTimetamp for sysdate : java.sql.Timestamp
从 9201 开始,将返回以下内容
getObject for sysdate : java.sql.Date <<<<< getDate for sysdate :java.sql.Date >> 没有变化 getTimetamp for sysdate :java.sql.Timestamp >> 没有变化
注意: java.sql.Date 没有时间部分,而 java.sql.Timestamp 有。
随着数据类型映射的这种变化,当 JDBC 驱动程序从 8i/9iR1 升级到 920x JBDC 驱动程序时,某些应用程序将失败和/或生成不正确的结果。为了保持兼容性并在升级后保持应用程序正常工作,提供了一个兼容性标志。开发人员现在有一些选择:
- 使用 oracle.jdbc.V8Compatible 标志。
JDBC Driver 默认不检测数据库版本。要更改处理 TIMESTAMP 数据类型的兼容性标志,连接属性
'oracle.jdbc.V8 兼容'
可以设置为“true”,并且驱动程序的行为与 8i、901x、9 200 中的行为相同(相对于 TIMESTAMP)。
默认情况下,该标志设置为“假”。在 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。在相应地处理 Date 和 TimeStamp 列数据类型时使用 set/getDate 和 set/getTimestamp。
9i 服务器支持 Date 和 Timestamp 列类型 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 就可以了。我想那是个坏习惯。