Skip to content

BulkCopy won't accept a LocalTime/LocalDateTime instances of 100ns precision #1376

@Arthurm1

Description

@Arthurm1

Driver version

8.3.1.jre14-preview

SQL Server version

Microsoft SQL Server 2019 (RTM-CU4) (KB4548597) - 15.0.4033.1 (X64) Mar 14 2020 16:10:35 Copyright (C) 2019 Microsoft Corporation Developer Edition (64-bit) on Linux (Ubuntu 18.04.4 LTS)

Client Operating System

Windows 10 with Docker

JAVA/JVM version

JDK 14

Problem description

  1. Expected behaviour:
    The driver should be able to bulk insert LocalTime/LocalDateTime instances of up to 100ns precision e.g. 2020-07-01 12:23:45.1234567
  2. Actual behaviour:
    Throws an exception.
  3. Error message/stack trace:
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Received an invalid column length from the bcp client for colid XX.
	at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:262)
	at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onEOF(tdsparser.java:283)
	at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:129)
	at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:37)
	at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:26)
	at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.doInsertBulk(SQLServerBulkCopy.java:1589)
	at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy$1InsertBulk.doExecute(SQLServerBulkCopy.java:662)
	at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7349)
	at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:3181)
	at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.sendBulkLoadBCP(SQLServerBulkCopy.java:696)
	at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.writeToServer(SQLServerBulkCopy.java:1654)
	at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.writeToServer(SQLServerBulkCopy.java:619)
  1. Any other details that can be helpful:
    The SQLServerBulkCopy class handles 1000ns precision fine e.g. 2020-07-01 12:23:45.123456 but not 100ns. The reason is that the bulk insert code calls the toString method on LocalTime/LocalDateTime to convert the data before sending. If you look at the docs for LocalTime#toString you can see it will output the ns portion with trailing zeros for each scientific unit...
HH:mm:ss.SSS
HH:mm:ss.SSSSSS
HH:mm:ss.SSSSSSSSS

so once LocalTime/LocalDateTime hits 100ns precision the toString method will add 2 trailing zeros e.g. 2020-07-01 12:23:45.123456700 which BCP doesn't seem to like.

The String conversion is done here

A workaround is to pass the data as a String without trailing zeros instead of using the LocalTime/LocalDateTime types.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions