JDBC 驱动程序将日期映射到 java.util.Timestamp,该时间戳在 sqlserver 中转换为 datetime2,导致数据比较出现问题

问题描述 投票:0回答:1

我在我的产品中使用 Spring Batch 框架。它从 mssqlserver 数据库中读取一些数据,处理数据并使用 where 子句中的主键更新同一个表中处理后的数据。 mssql-jdbc 驱动程序正在用于与数据库通信。

这是我的表的架构 创建表样本表( col1 日期时间 NOT NULL 主键, col2 varchar(50), col3 varchar(50) )

这是我表中的数据

col1                    |col2   |col3
2024-04-28 20:18:43.703 name    lastname

当 Spring 框架执行更新查询时,下面的 sqlserver profiler 中的数据库端是正在执行的查询。

exec sp_executesql N'update sampletable set col2=@P0 where col1=@P1 ',N'@P0 nvarchar(4000),@P1 datetime2',N'xxxxxxx','2024-04-28 20:18:43.7030000'

并且它不会更新任何行,因为隐式转换后 '2024-04-28 20:18:43.7030000' 与 '2024-04-28 20:18:43.703' 不匹配。

我们知道“从 SQL Server 2016 开始,datetime 到 datetime2(反之亦然)的转换/比较过程已被修改。

我们还尝试将 datetime 值转换为 datetime2 并传入查询,但这也没有帮助。这是我们在转换后创建的查询

exec sp_executesql N'update sampletable set col2=@P0 where col1=@P1 ',N'@P0 nvarchar(4000),@P1 datetime2',N'xxxxxxx','2024-04-28 20:18:43.7033333'

在 sqlserver 中使用 jdbc 执行时,有什么方法可以停止这种 datetime 到 datetime2 的转换。

sql-server spring-batch jdbctemplate mssql-jdbc
1个回答
0
投票

这适用于 12.2.0:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;

import org.junit.Test;

public class JDBCTest
{
    @Test
    public void testJdbc_default() throws Exception
    {
        Connection c = DriverManager
                .getConnection(
                        "jdbc:sqlserver://localhost;databaseName=;integratedSecurity=true;"
                            + "encrypt=false;lastUpdateCount=false;");
        PreparedStatement ps = c.prepareStatement("select convert(varchar(30), ?, 121)");
        ps.setTimestamp(1, Timestamp.valueOf("2024-04-28 20:18:43.703"));
        ps.execute();
        ResultSet rs = ps.getResultSet();
        rs.next();
        System.out.println(rs.getString(1)); //2024-04-28 20:18:43.7030000
    }

    @Test
    public void testJdbc_datetime() throws Exception
    {
        Connection c = DriverManager
                .getConnection(
                        "jdbc:sqlserver://localhost;databaseName=;integratedSecurity=true;"
                            + "encrypt=false;lastUpdateCount=false;datetimeParameterType=datetime");
        PreparedStatement ps = c.prepareStatement("select convert(varchar(30), ?, 121)");
        ps.setTimestamp(1, Timestamp.valueOf("2024-04-28 20:18:43.703"));
        ps.execute();
        ResultSet rs = ps.getResultSet();
        rs.next();
        System.out.println(rs.getString(1)); //2024-04-28 20:18:43.703
    }

    @Test
    public void testJdbc_datetime2() throws Exception
    {
        Connection c = DriverManager
                .getConnection(
                        "jdbc:sqlserver://localhost;databaseName=;integratedSecurity=true;"
                            + "encrypt=false;lastUpdateCount=false;datetimeParameterType=datetime2");
        PreparedStatement ps = c.prepareStatement("select convert(varchar(30), ?, 121)");
        ps.setTimestamp(1, Timestamp.valueOf("2024-04-28 20:18:43.703"));
        ps.execute();
        ResultSet rs = ps.getResultSet();
        rs.next();
        System.out.println(rs.getString(1)); //2024-04-28 20:18:43.703000
    }
}

波姆:

<dependency>
  <groupId>com.microsoft.sqlserver</groupId>
  <artifactId>mssql-jdbc</artifactId>
  <version>12.2.0.jre8</version>
</dependency>

也许你还有其他事情发生?

© www.soinside.com 2019 - 2024. All rights reserved.