1

我在尝试在 SQL Server 2008 中使用 timestamp2 而不是 Timestamp 时遇到了一些麻烦。显然,rs.getTimestamp 在 timestamp 和 timestamp2 之间的行为非常不同。但是,我找不到任何文件说明应该有区别,或者我应该使用不同的东西。我想知道我是否只是做错了什么。

环境:

  • 在 SQL Express 2008 (10.0) 和 SQL Server 2008 R2 (10.5) 上都试过了。
  • sqljdbc4.jar 版本 3.0,大小为 537,303 字节,CRC-32=a0aa1e25,MD5=402130141d5f2cee727f4371e2e8fd8a。
  • Java 1.6

这是一个演示问题的单元测试。唯一的“魔法”是“Db.getConnection()”,您可以用适当的代码替换它。datetime 和 datetime2 的测试相同,但 datetime2 测试失败,日期早于 2 天。我将数据库中的所有时间都视为 GMT/UTC,并且我没有尝试将时区信息添加到 datetime2 数据的数据库数据中。

    private void testTimestamp(TimeZone gmtTz, Connection conn, String query,
                    Calendar expectedCal) throws SQLException
    {
            PreparedStatement stmt = conn.prepareStatement(query);
            ResultSet rs = stmt.executeQuery();
            while (rs.next())
            {
                    // Note the expectedCal has a GMT timezone.
                    Date actualTs = rs.getTimestamp("dt", expectedCal);

                    // Just print out the time difference
                    long diff = actualTs.getTime() - expectedCal.getTimeInMillis();
                    System.out.println("Diff=" + diff);

                    // Do the test to make sure they are the same
                    // In practice, this succeeds for datetime and fails for datetime2
                    Assert.assertEquals(expectedCal.getTimeInMillis(), actualTs.getTime());
            }
    }

    @Test
    public void testDateTime() throws SQLException
    {
            Connection conn = Db.getConnection();
            TimeZone gmtTz = TimeZone.getTimeZone("GMT");
            String query;

            Calendar expectedCal = Calendar.getInstance(gmtTz);
            expectedCal.clear();
            expectedCal.set(2011, 10, 02, 11, 17);

            query = "select CAST('2011-11-02 11:17:00' as datetime) as dt";
            testTimestamp(gmtTz, conn, query, expectedCal);

            query = "select CAST('2011-11-02 11:17:00.0000000' as datetime2) as dt";
            testTimestamp(gmtTz, conn, query, expectedCal); // results in an error
    }

我唯一的选择是切换回时间戳吗?

编辑:对于未来的 Google 员工,使用 sqljdbc4.jar 3.0 版,测试在 Linux 上失败,但在 Windows 上通过。我还没有尝试过 SQL Server 2012 附带的 sqljdbc4.jar 4.0 版。

4

2 回答 2

4

如果您使用带有 Microsoft JDBC 3.0 驱动程序的 Sun JRE 1.7,请参阅此博客文章http://blogs.msdn.com/b/jdbcteam/archive/2012/01/20/hotfix-available-for-date-issue-when -使用-jre-1-7.aspx

如果您觉得您在我们的驱动程序中发现了错误,您可以通过 Microsoft Connect 报告它。 https://connect.microsoft.com/SQLServer

于 2012-04-19T20:31:54.027 回答
3

我记得没有听到关于官方 SQL Server 驱动程序和首选 JTDS 的好消息(尽管我似乎找不到那个链接)。我个人会使用 JTDS(当然要经过严格的测试)或回到不会引起问题的版本。我没有使用过 SQL Server,但从外观上看,这似乎datetime2是首选的数据类型,所以我宁愿不恢复。选项(d)实际上不是一个好的选项 IMO。:)

于 2011-11-03T16:22:50.597 回答