Драйвер JDBC сопоставляет дату с java.util.Timestamp, которая преобразуется в datetime2 в sqlserver, вызывая проблемы при сравнении данных

Я использую среду Spring Batch в своем продукте. Это чтение некоторых данных из базы данных mssqlserver, обработка данных и обновление обработанных данных в той же таблице с использованием первичного ключа в предложенииwhere. Драйвер mssql-jdbc появляется для связи с базами данных.

Это схема моей таблицы Таблица образцов CREATE TABLE( col1 datetime NOT NULL первичный ключ, col2 варчар(50), col3 варчар(50) )

Это данные в моей таблице

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

И когда Spring Framework выполняет запрос на обновление, то на стороне базы данных в профилировщике sqlserver ниже выполняется запрос. 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'

Есть ли какой-нибудь способ остановить это преобразование datetime в datetime2 при выполнении с использованием jdbc в sqlserver.

Вы уверены? почему оно не будет соответствовать после неявного преобразования

siggemannen 25.04.2024 13:45

Пожалуйста, Прочтите перед публикацией.... (Запрос exec sp_executesql ... '2024-04-28 20:18:43.7033333' упоминается два раза с разным описанием)

Luuk 25.04.2024 13:45

@siggemannen да, не совпадает

Aayushi Gupta 25.04.2024 13:52

@Luuk да, я знаю об этом. Я прочитал свой вопрос, и здесь нет никакой двусмысленности.

Aayushi Gupta 25.04.2024 13:55

Интересная проблема, я думаю, вы можете использовать следующее исправление github.com/microsoft/mssql-jdbc/pull/1687, чтобы использовать datetimeParameterType в строке подключения, чтобы использовать datetime вместо datetime2, что должно решить вашу проблему.

siggemannen 25.04.2024 14:20

@siggemannen, это не сработало. Моя строка подключения = "jdbc:sqlserver://localhost:port;databaseName=dbname;datetim‌​eParameterType=datet‌​ime" И я попробовал с mssql-jdbc-12.2.0.jre8.jar и mssql-jdbc-12.6.0 .jre8.jar. Проблема все еще сохраняется.

Aayushi Gupta 26.04.2024 15:53

@siggemannen, это сработало, спасибо за помощь. Когда я перепроверил все, я обнаружил, что новые драйверы не отображаются.

Aayushi Gupta 26.04.2024 20:26
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
87
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это работает в 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>

Может быть, у вас происходит что-то еще?

Другие вопросы по теме