当使用 SQLServer2008 从 SQLServer2008 检索 DATE 类型的列时,出现奇怪的效果在官方 Oracle JDK 1.7.0 下运行时。主机操作系统是Windows Server 2003。
所有日期列均检索为two相对于列中实际存储的值而言的过去天数。
我编写了一个最小的代码示例来测试它(测试表和数据):
CREATE TABLE Java7DateTest (
dateColumn DATE
);
INSERT INTO Java7DateTest VALUES('2011-10-10');
Code:
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)”
我在谷歌上找不到任何与我的问题相关的东西,所以我假设它要么是我忽略的愚蠢的东西,要么还没有人使用Java7。
有人可以确认这个问题吗?如果我仍然想使用 Java7,我有什么选择?
编辑:即使使用 -Xint 运行时也会出现问题,因此它不是由热点错误引起的。
Edit2:旧驱动程序(Microsoft 1.28)可以与 JDK1.7.0 正常工作(我认为我们直到大约两年前才使用该驱动程序)。
jTDS 在该示例中也能完美运行。我正在考虑改用 jTDS,但我不愿意这样做,因为我完全不知道这会对我们的生产环境产生什么影响。理想情况下它应该可以工作,但是当我将我的开发盒切换到 Java7 时我也相信这一点。
生产环境中有一个相当庞大的数据库,太大而无法创建用于测试的副本(或者更确切地说,我们的服务器只剩下很少的磁盘了)。因此,为该应用程序设置测试环境并不简单,我必须为此缝合一个缩小的数据库。
Edit3:jTDS 有其自己的附加捕获集。我发现一种行为差异破坏了我们的一个应用程序。 ResultSet.getObject() 根据驱动程序返回 SmallInt 列的不同对象类型(Short 与 Integer)。此外,jTDS 不实现 JDBC4 Connection 接口,不支持 Connect.isValid()。
Edit4:我上周注意到,在我更新到 JDK1.6.0_29 后,MSSQL-JDBC 3.0 拒绝连接到任何数据库。 jTDS 那么...我们昨天切换了生产服务器(我修复了应用程序依赖于驱动程序特性的两个地方),到目前为止我们没有任何问题。