Skip to content

Commit 08ba857

Browse files
authored
Add support for InputStream data type using setBinaryStream() for bulk copy for batch insert API (#2826)
* Added support for InputStream data type using setBinaryStream() for bulk copy for batch insert API * Added proper comments
1 parent 65e1929 commit 08ba857

File tree

2 files changed

+64
-3
lines changed

2 files changed

+64
-3
lines changed

src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkBatchInsertRecord.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package com.microsoft.sqlserver.jdbc;
77

8+
import java.io.InputStream;
89
import java.math.BigDecimal;
910
import java.math.RoundingMode;
1011
import java.sql.Types;
@@ -132,10 +133,10 @@ private Object convertValue(ColumnMetadata cm, Object data) throws SQLServerExce
132133
case Types.VARBINARY:
133134
case Types.LONGVARBINARY:
134135
case Types.BLOB: {
135-
if (data instanceof byte[]) {
136+
if (data instanceof byte[] || data instanceof InputStream) {
136137
/*
137-
* if the binary data comes in as a byte array through setBytes through Bulk Copy for Batch Insert
138-
* API, don't turn the binary array into a string.
138+
* if the binary data comes in as a byte array or Input Stream through setBytes()/setBinaryStream()
139+
* through Bulk Copy for Batch Insert API, don't turn the binary array into a string.
139140
*/
140141
return data;
141142
} else {

src/test/java/com/microsoft/sqlserver/jdbc/preparedStatement/BatchExecutionWithBulkCopyTest.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77
import static org.junit.jupiter.api.Assertions.assertNotNull;
88
import static org.junit.jupiter.api.Assertions.assertTrue;
99

10+
import java.io.ByteArrayInputStream;
11+
import java.io.InputStream;
1012
import java.lang.reflect.Field;
1113
import java.lang.reflect.Method;
1214
import java.math.BigDecimal;
1315
import java.math.RoundingMode;
16+
import java.nio.charset.StandardCharsets;
1417
import java.sql.BatchUpdateException;
1518
import java.sql.Connection;
1619
import java.sql.Date;
@@ -1696,6 +1699,63 @@ private void getCreateTableWithStringData() throws SQLException {
16961699
}
16971700
}
16981701

1702+
/**
1703+
* Test bulk insert with InputStream data when useBulkCopyForBatchInsert is true.
1704+
* Added support for InputStream data type with bulk copy batch insert.
1705+
*
1706+
* @throws Exception
1707+
*/
1708+
@Test
1709+
public void testBulkCopyBatchInsertForInputStreamData() throws Exception {
1710+
String tableName = RandomUtil.getIdentifier("BulkTableForInputStream");
1711+
String insertSQL = "INSERT INTO " + AbstractSQLGenerator.escapeIdentifier(tableName) +
1712+
" (Id, Data) VALUES (?, ?)";
1713+
String selectSQL = "SELECT Id, Data FROM " + AbstractSQLGenerator.escapeIdentifier(tableName);
1714+
1715+
try (Connection connection = PrepUtil.getConnection(connectionString + ";useBulkCopyForBatchInsert=true;");
1716+
Statement stmt = connection.createStatement();
1717+
SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) connection.prepareStatement(insertSQL)) {
1718+
1719+
getCreateTableInputStream(tableName);
1720+
1721+
String data = "Sample string to be inserted as binary data.";
1722+
byte[] bytes = data.getBytes(StandardCharsets.UTF_8);
1723+
InputStream inputStream = new ByteArrayInputStream(bytes);
1724+
1725+
pstmt.setObject(1, 1);
1726+
pstmt.setBinaryStream(2, inputStream);
1727+
1728+
pstmt.addBatch();
1729+
pstmt.executeBatch();
1730+
1731+
// Validate inserted data
1732+
try (ResultSet rs = stmt.executeQuery(selectSQL)) {
1733+
assertTrue(rs.next());
1734+
1735+
assertEquals(1, rs.getInt(1));
1736+
byte[] retrievedBytes = rs.getBytes(2);
1737+
String retrievedData = new String(retrievedBytes, StandardCharsets.UTF_8);
1738+
assertEquals(data, retrievedData);
1739+
1740+
}
1741+
} finally {
1742+
try (Statement stmt = connection.createStatement()) {
1743+
TestUtils.dropTableIfExists(AbstractSQLGenerator.escapeIdentifier(tableName), stmt);
1744+
}
1745+
}
1746+
}
1747+
1748+
private void getCreateTableInputStream(String tableName) throws SQLException {
1749+
try (Statement stmt = connection.createStatement()) {
1750+
TestUtils.dropTableIfExists(AbstractSQLGenerator.escapeIdentifier(tableName), stmt);
1751+
String createTableSQL = "CREATE TABLE " + AbstractSQLGenerator.escapeIdentifier(tableName) + " (" +
1752+
"Id INT PRIMARY KEY, " +
1753+
"Data VARBINARY(MAX) NULL" + ")";
1754+
1755+
stmt.execute(createTableSQL);
1756+
}
1757+
}
1758+
16991759
@BeforeAll
17001760
public static void setupTests() throws Exception {
17011761
setConnection();

0 commit comments

Comments
 (0)