在 Java 1.7.0 下运行的 SQL-Server (MSSQL-JDBC 3.0) 中的日期列检索为过去 2 天

发布于 2024-12-09 05:17:36 字数 2296 浏览 0 评论 0原文

使用 Microsoft JDBC-Driver 从 SQLServer2008 检索 DATE 类型的列时,出现奇怪的效果在官方 Oracle JDK 1.7.0 下运行时为 3.0 版。主机操作系统是 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)”

我找不到任何与我的谷歌问题相关的内容,所以我假设它要么是愚蠢的我被忽视或者还没有人使用 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 那么...我们昨天切换了生产服务器(我修复了应用程序依赖于驱动程序特性的两个地方),到目前为止我们没有任何问题。

I have strange effects when retrieving columns of type DATE from SQLServer2008 using the Microsoft JDBC-Driver version 3.0 when running under the official Oracle JDK 1.7.0. Host OS is Windows Server 2003.

All Date columns are retrieved as two days in the past with respect to the value actually stored in the column.

I cooked up a minimal code example the test this out (Test table and data):

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);
        }
    }

}

Running this code on above configuration prints: "2011-10-08 (raw: 2011-10-08)".
Under JRE 1.6.0_27 it prints: "2011-10-10 (raw: 2011-10-10)"

I could not find anything that seems to relate to my problem with google, so I'm assuming that its either something stupid I overlooked or nobody is using Java7 yet.

Can anybody confirm this problem? What are my alternatives if I still want to use Java7?

Edit: The problem occurs even when running with -Xint, so its not caused by Hotspot bugs.

Edit2: Old drivers (Microsoft 1.28) work properly with JDK1.7.0 (we were using that driver until maybe two years ago, I think).
jTDS also works perfectly fine with the example. I am considering switching to jTDS, but I am reluctant to do so because I have not the faintest idea what the effects on our productive environment may be. Ideally it should just work, but that what I believed when I switched my dev box to Java7, too.
There is one pretty fat database in the production environment, that is too big to create a copy of, for testing (or rather our server has so little disk left). So setting up a test environment for that one app is not straigthforward, I would have to stitch up a shrinked database for that.

Edit3: jTDS has its own set of catches attached. I found a behavioral difference that breaks one of our applications. ResultSet.getObject() returns different object types for SmallInt columns depending on driver (Short vs Integer). Also jTDS does not implement JDBC4 Connection interface, Connect.isValid() is not supported.

Edit4: I noticed last week that MSSQL-JDBC 3.0 refuses to connect to any DB after I updated to JDK1.6.0_29. jTDS it is then... we switched the productive server yesterday (I fixed tow places where the application was relying on peculiarities of the driver), and so far we had have no problems.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

书间行客 2024-12-16 05:17:36

感谢您的反馈。 Microsoft JDBC Driver for SQL Server 尚不支持 JRE 1.7。

我们意识到我们的 JDBC 驱动程序和 JDBC 驱动程序之间存在 getDate 问题。 JRE 1.7,我们正在考虑发布修补程序,以便客户能够使用 JRE 1.7 继续对我们的驱动程序进行非生产测试。

一旦修复程序可用,我们将在博客上发布该修复程序的链接。
http://blogs.msdn.com/b/jdbcteam/

修补程序是现已推出。 http://blogs.msdn.com/b/jdbcteam/archive/2012/01/20/hotfix-available-for-date-issue-when-using-jre-1-7.aspx< /a>

我们的博客还包含有关 JRE 1.6u29 和 JRE 已知问题的信息。 1.6u30。

沙米莎·雷迪
程序管理器 - Microsoft JDBC Driver for SQL Server

Thank you for your feedback. The Microsoft JDBC Driver for SQL Server does not yet support JRE 1.7.

We are aware of the getDate issue between our JDBC driver & JRE 1.7 and we are looking into publishing a hotfix to enable customers to move forward with non-production testing of our driver with JRE 1.7.

We will publish a link to the hotfix on our blog once available.
http://blogs.msdn.com/b/jdbcteam/

The hotfix is now available. http://blogs.msdn.com/b/jdbcteam/archive/2012/01/20/hotfix-available-for-date-issue-when-using-jre-1-7.aspx

Our blog also contains information on the known issues with JRE 1.6u29 & 1.6u30.

Shamitha Reddy
Program Manager - Microsoft JDBC Driver for SQL Server

镜花水月 2024-12-16 05:17:36

我不太能给你答案。但是,我已经按照您的描述重新创建了您的情况。在jdk1.7下运行时与jdbc驱动程序v3.101和v3.202以及v4.ctp3相同。然而,MS 的 v2 驱动程序在 jdk1.6 和 jdk1.7 下都给出了您预期的答案。如果您需要快速修复并且可以迁移到较旧的 jdbc 驱动程序,那么这可能适合您。

其他想法是关于 MS jdbc 驱动程序如何处理日期以及 SQL Server 和 jvm 之间日期对象的转换。由于日期的存储没有时区,因此驱动程序对 Date 对象的解释基于运行 jdbc 驱动程序的计算机的默认时区。例如,如果您存储“2011-10-11 12:00”的小日期并从默认时区设置为 GMT-7 的计算机检索它,则 Date 对象的最终 UTC 时间将为“2011-10” -11 19:00'。 jdk1.7 中可能存在一些变化,影响驱动程序中的此转换过程,从而导致严重偏移。您可以尝试使用 ResultSet.getDate(column, Calendar) 方法来查看具有特定时区的日历是否可以为您提供所需的结果,或者有助于理解为什么您会在转换中看到奇怪的偏移量。

I don't quite have an answer for you. But, I've recreated your situation as you described. It is the same with the jdbc driver v3.101 and v3.202 and v4.ctp3 when run under jdk1.7. However, the v2 driver from MS gives your expected answer both under jdk1.6 and jdk1.7. If you need a quick fix and can move to an older jdbc driver, that may work for you.

Other thoughts are on how the MS jdbc driver handles dates and conversion of Date objects between SQL Server and the jvm. Since the storage of the date is without a time zone, the interpretation of the Date object by the driver is based on the default time zone for the machine running the jdbc driver. For instance, if you store a smalldate of '2011-10-11 12:00' and retrieve it from a machine with the default time zone set to GMT-7 then the resulting UTC time of the Date object would be '2011-10-11 19:00'. It could be that there is some change in jdk1.7 that impacts this conversion process in the driver resulting in a wild offset. You might experiment with the ResultSet.getDate(column, Calendar) method to see if a Calendar with a specific time zone gets you the result you want or helps make sense of why you are seeing the strange offset in the conversion.

眼前雾蒙蒙 2024-12-16 05:17:36

我没有 SQL Server 设置,但我无法在带有 JDK 1.7.0 的 Windows 7 x64 上使用 PostgreSQL 9.0 和 MySQL 5.1 重现您的问题。所以JDK 1.7.0可以排除嫌疑。我的印象是 SQL Server JDBC 驱动程序应该归咎于此。我建议改用 jTDS JDBC 驱动程序。与 MS 提供的 SQL Server JDBC 驱动程序相比,它一直因其更好的性能和稳定性而受到称赞。

I don't have a SQL Server setup, but I can't reproduce your problem with PostgreSQL 9.0 and MySQL 5.1 on Windows 7 x64 with JDK 1.7.0. So JDK 1.7.0 can be excluded from being suspect. I have the impression that the SQL Server JDBC driver is to blame here. I'd suggest to use the jTDS JDBC driver instead. It has always been praised for its better performance and stability as opposed to the MS-provided SQL Server JDBC driver.

北恋 2024-12-16 05:17:36

可以在此处找到来自 Microsoft 支持的热补丁的信息和下载链接:

http://support.microsoft.com/ kb/2652061

我遇到了同样的问题,日期会晚两天,这个热补丁修复了它。

Information and download link for the hotpatch from Microsoft Support can be found here:

http://support.microsoft.com/kb/2652061

I was experiencing the same issue, where the date would be off by two days, and this hotpatch fixed it.

绮筵 2024-12-16 05:17:36

这也是 OpenJDK 1.6.0_20 中的一个问题。但是,mssql 驱动程序可以与 Suns JRE 1.6.0_16 配合使用。

This is also an issue in OpenJDK 1.6.0_20. However, the mssql driver works fine with Suns JRE 1.6.0_16.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文