如何使用 SQL Server JDBC 批量复制 API

Kim*_*ist 5 java bulkinsert jdbc sqlbulkcopy azure-sql-database

我在尝试使用 SQL Server Bulk Copy API 和SQLServerBulkCSVFileRecord. 仅出于测试目的,我制作了一个仅包含nvarchar(500)列的表,并添加了元数据,如下所示:

fileRecord = new SQLServerBulkCSVFileRecord(csvPath, false);      

for(int i=1; i<=colCount; i++) {
    fileRecord.addColumnMetadata(i, null, java.sql.Types.NVARCHAR, 500, 0);
} 
Run Code Online (Sandbox Code Playgroud)

在使用带有 JDBC 的 Microsoft SQL 批量复制 API 后,我得到以下堆栈跟踪,但我找不到任何有关SQLServerBulkCSVFileRecord. 我不知道参数代表什么addColumnMetaData:我只是假设看这个例子,第一个参数代表列索引,然后显然第三个参数代表数据类型,第四个参数代表列的字节数(?)。

com.microsoft.sqlserver.jdbc.SQLServerException: Unicode data is odd byte size for column 1. Should be even byte size.
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:217)
    at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onEOF(tdsparser.java:251)
    at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:81)
    at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:36)
    at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.doInsertBulk(SQLServerBulkCopy.java:1433)
    at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.access$200(SQLServerBulkCopy.java:41)
    at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy$1InsertBulk.doExecute(SQLServerBulkCopy.java:666)
    at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:6276)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1793)
    at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.sendBulkLoadBCP(SQLServerBulkCopy.java:699)
    at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.writeToServer(SQLServerBulkCopy.java:1516)
    at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.writeToServer(SQLServerBulkCopy.java:616)
Run Code Online (Sandbox Code Playgroud)

我读到空行、非 CRLF 行结尾、编码等可能会产生影响,但我觉得我已经用尽了这些选项。

最后,这是我的 CSV 文件的一个小示例:

column1|test|1|testtest|test3
column2|test|2|testt46426est|test346
column3|test|3|test4test|test3426234
Run Code Online (Sandbox Code Playgroud)

Gor*_*son 6

您没有指定管道字符作为字段分隔符。请注意,它需要转义"\\|",因为根据文档

为 CSV 文件指定的分隔符不应出现在数据中的任何位置,如果它是 Java 正则表达式中的限制字符,则应正确转义。

我刚刚尝试了以下代码,它对我有用:

String csvPath = "C:/Users/Gord/Desktop/sample.txt";
SQLServerBulkCSVFileRecord fileRecord = 
        new SQLServerBulkCSVFileRecord(csvPath, null, "\\|", false);

int colCount = 5;
for (int i = 1; i <= colCount; i++) {
    fileRecord.addColumnMetadata(i, null, java.sql.Types.NVARCHAR, 50, 0);
}

try (SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(conn)) {
    bulkCopy.setDestinationTableName("dbo.so41144967");

    try {
        // Write from the source to the destination.
        bulkCopy.writeToServer(fileRecord);
    } catch (Exception e) {
        // Handle any errors that may have occurred.
        e.printStackTrace();
    }
}
Run Code Online (Sandbox Code Playgroud)