Skip to content

[BUG] PreparedStatement.executeBatch() When the Insert Sql Column Name Case Mismatch, Throws SQLServerException "Unable to retrieve column metadata." #2588

Open
@wooln

Description

@wooln

Driver version

12.8.1

SQL Server version

Microsoft SQL Server 2019 (RTM-CU29) (KB5046365) - 15.0.4405.4 (X64) 
	Oct 23 2024 08:45:19 
	Copyright (C) 2019 Microsoft Corporation
	Developer Edition (64-bit) on Linux (Ubuntu 20.04.6 LTS) <X64>

Client Operating System

openSUSE Leap 15.6 x86_64

JAVA/JVM version

java version 22

Problem description

PreparedStatement.executeBatch(), when the insert sql column name case mismatch, Throws SQLServerException "Unable to retrieve column metadata."

  1. create table, c1 lower case.
    CREATE TABLE varchartable1 (c1 varchar(10))

  2. executeBatch

    Column name use lower case c1, succeed
    con.prepareStatement("INSERT INTO varchartable1 (c1) VALUES(?)")

    Column name use upper case C1, throws SQLServerException "Unable to retrieve column metadata."
    con.prepareStatement("INSERT INTO varchartable1 (C1) VALUES(?)")

The unit tests.

  1. succeed
@Test
public void testExecuteBatchColumnCaseMatching() throws Exception {
    String varcharTable1 = AbstractSQLGenerator.escapeIdentifier(RandomUtil.getIdentifier("varchartable1"));
    // Insert Timestamp using prepared statement when useBulkCopyForBatchInsert=true
    try (Connection con = DriverManager.getConnection(connectionString
            + ";useBulkCopyForBatchInsert=true;sendTemporalDataTypesAsStringForBulkCopy=false;")) {
        try (Statement statement = con.createStatement()) {
            TestUtils.dropTableIfExists(varcharTable1, statement);
            String createSql = "CREATE TABLE" + varcharTable1 + " (c1 varchar(10))";
            statement.execute(createSql);
        }
        try (PreparedStatement preparedStatement = con.prepareStatement("INSERT INTO " + varcharTable1 + "(c1) VALUES(?)")) {
            preparedStatement.setObject(1, "value1");
            preparedStatement.addBatch();
            preparedStatement.setObject(1, "value2");
            preparedStatement.addBatch();
            preparedStatement.executeBatch();
        }
    }
}
  1. throws SQLServerException "Unable to retrieve column metadata."
@Test
public void testExecuteBatchColumnCaseMismatch() throws Exception {
    String varcharTable1 = AbstractSQLGenerator.escapeIdentifier(RandomUtil.getIdentifier("varchartable1"));
    // Insert Timestamp using prepared statement when useBulkCopyForBatchInsert=true
    try (Connection con = DriverManager.getConnection(connectionString
            + ";useBulkCopyForBatchInsert=true;sendTemporalDataTypesAsStringForBulkCopy=false;")) {
        try (Statement statement = con.createStatement()) {
            TestUtils.dropTableIfExists(varcharTable1, statement);
            String createSql = "CREATE TABLE" + varcharTable1 + " (c1 varchar(10))";
            statement.execute(createSql);
        }
        // upper case C1
        try (PreparedStatement preparedStatement = con.prepareStatement("INSERT INTO " + varcharTable1 + "(C1) VALUES(?)")) {
            preparedStatement.setObject(1, "value1");
            preparedStatement.addBatch();
            preparedStatement.setObject(1, "value2");
            preparedStatement.addBatch();
            try {
                preparedStatement.executeBatch();
                fail("Should have failed");
            } catch (Exception ex) {
                assertInstanceOf(SQLServerException.class, ex);
                assertEquals("Unable to retrieve column metadata.", ex.getMessage());
            }
        }
    }
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status

Under Peer Review

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions