【问题标题】:How to use the SQL Server JDBC bulk copy API如何使用 SQL Server JDBC 大容量复制 API
【发布时间】:2017-04-29 22:09:00
【问题描述】:

我在尝试使用 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);
} 

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

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)

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

最后是我的 CSV 文件的一个小样本:

column1|test|1|testtest|test3
column2|test|2|testt46426est|test346
column3|test|3|test4test|test3426234

【问题讨论】:

    标签: java jdbc azure-sql-database bulkinsert sqlbulkcopy


    【解决方案1】:

    您没有将竖线字符指定为字段分隔符。请注意,它需要转义为"\\|",因为根据documentation

    为 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();
        }
    }
    

    【讨论】:

    • 谢谢,确实是这样。我为忘记分隔符而感到有点惭愧。您是否碰巧知道其他地方是否有关于此 API 的更详尽的文档?
    • 该文件是我目前找到的唯一参考资料。
    猜你喜欢
    • 2021-05-19
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 2016-08-09
    • 2017-10-05
    • 1970-01-01
    • 1970-01-01
    • 2013-06-21
    相关资源
    最近更新 更多