在正式的Oracle JDK 1.7.0下运行时,使用Microsoft JDBC-Driver 3.0版从SQLServer2008检索DATE类型的列时,会产生奇怪的效果。主机操作系统是Windows Server 2003。
所有日期栏,为检索两个天过去相对于实际存储在列中的值。
我准备了一个最小的代码示例,将其测试出来(测试表和数据):
CREATE TABLE Java7DateTest (
dateColumn DATE
);
INSERT INTO Java7DateTest VALUES('2011-10-10');
码:
public class Java7SQLDateTest {
public static void main(final String[] argv) {
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection connection = DriverManager.getConnection(
"jdbc:sqlserver://192.168.0.1:1433;databaseName=dbNameHere",
"user", "password");
PreparedStatement statement = connection.prepareStatement("SELECT * FROM Java7DateTest");
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
final java.sql.Date date = resultSet.getDate("dateColumn");
final String str = resultSet.getString("dateColumn");
System.out.println(date + " (raw: " + str + ")");
}
resultSet.close();
statement.close();
connection.close();
} catch (final Throwable t) {
throw new RuntimeException(t.getMessage(), t);
}
}
}
在上述配置上运行此代码将显示:“ 2011-10-08(原始:2011-10-08)”。在JRE 1.6.0_27下打印:“ 2011-10-10(原始:2011-10-10)”
我找不到与我的Google问题有关的任何内容,因此我假设它要么是我忽略的愚蠢行为,要么是没有人在使用Java7。
有人可以确认这个问题吗?如果我仍然想使用Java7,还有哪些选择?
编辑:即使使用-Xint运行,也会出现问题,因此它不是由Hotspot错误引起的。
Edit2:旧的驱动程序(Microsoft 1.28)可以与JDK1.7.0一起正常工作(我认为直到两年前我们才使用该驱动程序)。jTDS在该示例中也可以很好地工作。我正在考虑切换到jTDS,但我不愿意这样做,因为我没有最模糊的想法,这可能会对我们的生产环境造成什么影响。理想情况下,它应该可以正常工作,但是那也是我将开发箱切换到Java7时所相信的。生产环境中有一个漂亮的胖数据库,它太大了,无法创建一个副本进行测试(或者我们的服务器只剩下很少的磁盘)。因此,为该应用程序设置测试环境并非难事,我将不得不为此缩减一个缩小的数据库。
Edit3:jTDS附带了自己的一组捕获。我发现行为上的差异破坏了我们的应用程序之一。ResultSet.getObject()根据驱动程序(Short与Integer)为SmallInt列返回不同的对象类型。另外,jTDS不实现JDBC4 Connection接口,不支持Connect.isValid()。
Edit4:我上周注意到,在我更新到JDK1.6.0_29之后,MSSQL-JDBC 3.0拒绝连接到任何数据库。现在是jTDS了……我们昨天切换了生产服务器(我固定了两个应用程序依赖于驱动程序特性的地方),到目前为止,我们还没有遇到任何问题。
我还没有答案。但是,我已经按照您的描述重新创建了您的情况。在jdk1.7下运行时,与jdbc驱动程序v3.101,v3.202和v4.ctp3相同。但是,MS的v2驱动程序在jdk1.6和jdk1.7下都能提供预期的答案。如果您需要快速修复并可以使用旧的jdbc驱动程序,则可能对您有用。
关于MS jdbc驱动程序如何处理日期以及SQL Server和jvm之间的Date对象转换的其他想法。由于日期的存储没有时区,因此驱动程序对Date对象的解释是基于运行jdbc驱动程序的计算机的默认时区。例如,如果您存储了一个小日期'2011-10-11 12:00',并从默认时区设置为GMT-7的计算机上检索到该日期,则Date对象的最终UTC时间将为'2011-10 -11 19:00'。jdk1.7中的某些更改可能会影响驱动程序中的此转换过程,从而导致大量偏移。您可以尝试使用ResultSet.getDate(column,
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句