JDBC驱动程序将Timestamp作为datetime2发送,导致where子句失败

时间:2014-04-24 15:08:29

标签: java sql-server sql-server-2008 jdbc

我们最近将我们的开发数据库从SQL Server 2005移到了SQL Server 2008 R2,我们遇到了以下情况。

如果我们插入带有DATETIME列的记录,然后我们尝试在where子句中使用此插入时间,则查询有时不返回任何结果,这是因为DATETIME数据类型发生的舍入。

以下是如何复制此行为的示例:

import java.sql.*;
public class JDBCTest {
    public static void main( String args[] )
    {
        try
        {
            // Load the database driver
            Class.forName( "com.microsoft.sqlserver.jdbc.SQLServerDriver" ) ;

            // Get a connection to the database
            Connection conn = DriverManager.getConnection("jdbc:sqlserver://DEVENV;user=?;" +
                    "password=?;databaseName=jdbctest" ) ;
            //Insert
            PreparedStatement ps = conn.prepareStatement( "INSERT INTO dbo.test VALUES  (?)" ) ;

            java.util.Date date= new java.util.Date();
            java.sql.Timestamp currentTimestamp= new java.sql.Timestamp(date.getTime());
            ps.setTimestamp(1, currentTimestamp );

            ps.execute();
            ps.close() ;


            PreparedStatement psSel = conn.prepareStatement( "SELECT * FROM test WHERE date = ?" ) ;
            psSel.setTimestamp(1,currentTimestamp);

            ResultSet rs = psSel.executeQuery() ;
            if (rs.next()){
                while( rs.next() ) System.out.println( rs.getString("id") + " " + rs.getString("date") ) ;
            }
            else {
                System.out.println("NO RESULTS!");
            }

            rs.close() ;
            psSel.close() ;
            conn.close() ;
        }
        catch( Exception e )
        {
            System.out.println( e ) ;
        }
    }
}

使用SQL事件探查器,我们看到执行了以下操作:

declare @p1 int
set @p1=1
exec sp_prepexec @p1 output,N'@P0 datetime2',N'INSERT  INTO dbo.test VALUES  (@P0)        ','2014-04-24 09:49:41.3360000'
select @p1

在数据库中,这是插入的记录:

  

2014-04-24 09:49:41.337

执行where时,会将以下内容发送到数据库:

declare @p1 int
set @p1=0
exec sp_prepexec @p1 output,N'@P0 datetime2',N'SELECT * FROM test WHERE date = @P0        ','2014-04-24 09:49:41.3360000'
select @p1

SELECT不返回任何数据。问题是由于某种原因,JDBC驱动程序将参数作为DATETIME2发送,然后引擎比较DATETIME和DATETIME2而不考虑DATETIME的舍入,因此where子句失败。

使用SQL Server 2005时,行为是预期的行为,因为在2008版本中引入了DATETIME2。

到目前为止,我们提出的解决方案是隐式地将参数转换为DATETIME。从长远来看,将数据库DATETIME列更改为DATETIME2,但同时最后一个解决方案是不可行的。

此问题是否有解决方法?

0 个答案:

没有答案