JDBC调用SQLServerBulkCopy批量插入中文问题

竹林依旧宁静 2020-05-19 09:57:56
目前利用JDBC调用SQLServerBulkCopy实现批量数据插入SQL Server2012,目标表字段类型为VARCHAR(50)时,字段长度够长,写入中文时报错,驱动包版本为mssql-jdbc-6.2.2.jre8.jar,请大家帮忙解决一下,报错信息为:com.microsoft.sqlserver.jdbc.SQLServerException: 从 bcp 客户端收到一个对 colid 11 无效的列长度。
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:258)
at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onEOF(tdsparser.java:256)
at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:108)
at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:28)
at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.doInsertBulk(SQLServerBulkCopy.java:1611)
at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.access$200(SQLServerBulkCopy.java:58)
at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy$1InsertBulk.doExecute(SQLServerBulkCopy.java:709)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7151)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2478)
at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.sendBulkLoadBCP(SQLServerBulkCopy.java:739)
at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.writeToServer(SQLServerBulkCopy.java:1684)
at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.writeResultSet(SQLServerBulkCopy.java:645)
at com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.writeToServer(SQLServerBulkCopy.java:594)
at com.miextreme.test.sqlserver.task.WriteTask.insertBatch(WriteTask.java:284)
at com.miextreme.test.sqlserver.task.WriteTask.run(WriteTask.java:154)

java代码如下:
private CachedRowSetImpl getCachedRowSet() throws SQLException {
Connection connection = instance.getConnection();
PreparedStatement prepareStatement = connection.prepareStatement("SELECT * FROM [cfa_personbase_info] WHERE 1 = 0");
ResultSet targetTableResultSet = prepareStatement.executeQuery();

CachedRowSetImpl cachedRowSet = new CachedRowSetImpl();
cachedRowSet.populate(targetTableResultSet);

if (prepareStatement != null) {
prepareStatement.close();
prepareStatement = null;
}
if (connection != null) {
connection.close();
connection = null;
}

return cachedRowSet;
}

private void insertIntoCachedRowSet(CachedRowSetImpl cachedRowSet, Map<String, Object> rowData) throws SQLException {
// 移动指针到"插入行"
cachedRowSet.moveToInsertRow();

// 插入行
Set<String> columnSet = rowData.keySet();
Iterator<String> columnIterator = columnSet.iterator();
while (columnIterator.hasNext()) {
String columnName = columnIterator.next();
Object columnValue = rowData.get(columnName);
if (columnValue == null) {
cachedRowSet.updateNull(columnName);
} else {
cachedRowSet.updateObject(columnName, columnValue);
}
}
cachedRowSet.insertRow();

// 移动指针到当前行
cachedRowSet.moveToCurrentRow();
}

private void insertBatch(CachedRowSetImpl cachedRowSet, int batchSize) throws SQLException {
// 目标源URL
StringBuffer connectionUrl = new StringBuffer("jdbc:sqlserver://127.0.0.1:1433;databaseName=tar_test;user=sa;password=sa");

// BulkCopyOptions
SQLServerBulkCopyOptions copyOptions = new SQLServerBulkCopyOptions();
copyOptions.setKeepIdentity(true);
copyOptions.setBatchSize(batchSize);
copyOptions.setUseInternalTransaction(true);
copyOptions.setBulkCopyTimeout(3600);

// BulkCopy
SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(connectionUrl.toString());
bulkCopy.setBulkCopyOptions(copyOptions);
bulkCopy.setDestinationTableName("[cfa_personbase_info]");
bulkCopy.addColumnMapping("personid", "personid");
bulkCopy.addColumnMapping("gonghao", "gonghao");
bulkCopy.addColumnMapping("name", "name");
bulkCopy.addColumnMapping("cardtype", "cardtype");
bulkCopy.addColumnMapping("cardid", "cardid");
bulkCopy.addColumnMapping("birthday", "birthday");
bulkCopy.addColumnMapping("sex", "sex");
bulkCopy.addColumnMapping("getjobtime", "getjobtime");
bulkCopy.addColumnMapping("workingyears", "workingyears");
bulkCopy.addColumnMapping("nationlity", "nationlity");
bulkCopy.addColumnMapping("birthplace", "birthplace");
bulkCopy.addColumnMapping("nation", "nation");
bulkCopy.addColumnMapping("polity", "polity");
bulkCopy.addColumnMapping("foreignlang", "foreignlang");
bulkCopy.addColumnMapping("highestdegree", "highestdegree");
bulkCopy.addColumnMapping("highstudy", "highstudy");
bulkCopy.addColumnMapping("technicrank", "technicrank");
bulkCopy.addColumnMapping("address", "address");
bulkCopy.addColumnMapping("postcode", "postcode");
bulkCopy.addColumnMapping("telephone", "telephone");
bulkCopy.addColumnMapping("cellphone", "cellphone");
bulkCopy.addColumnMapping("email", "email");
bulkCopy.addColumnMapping("linkman", "linkman");
bulkCopy.addColumnMapping("linkmanphone", "linkmanphone");
bulkCopy.addColumnMapping("addressbirth", "addressbirth");
bulkCopy.addColumnMapping("familyinfo", "familyinfo");
bulkCopy.addColumnMapping("updatedate", "updatedate");
bulkCopy.addColumnMapping("updatetime", "updatetime");
bulkCopy.addColumnMapping("modifyid", "modifyid");
bulkCopy.addColumnMapping("modifytype", "modifytype");
bulkCopy.addColumnMapping("modifystate", "modifystate");
bulkCopy.addColumnMapping("modifyuser", "modifyuser");
bulkCopy.writeToServer(cachedRowSet);
cachedRowSet.close();
bulkCopy.close();
}
...全文
478 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_46434575 2021-12-15
  • 打赏
  • 举报
回复

这个问题解决了嘛,我好像也有同样的问题,字段长度够,但是依然无法写入中文

  • 打赏
  • 举报
回复 4

试试这个版本9.2.1.jre8

qq_19135573 2022-03-22
  • 举报
回复
@丑团外卖饱了么 大佬牛逼
summer_21 2022-09-23
  • 举报
回复
@丑团外卖饱了么 膜拜大佬,顶顶顶
竹林依旧宁静 2020-05-19
  • 打赏
  • 举报
回复
竹林依旧宁静 2020-05-19
  • 打赏
  • 举报
回复
竹林依旧宁静 2020-05-19
  • 打赏
  • 举报
回复
Oracle官方11g 最新版jdbc驱动。 新特性:   1、支持JDK6,支持JDBC 4.0,新的java.sql.SQLXML类型没有被支持,是使用ojdbc6.jar来支持。J2SE 5.0 和 JDBC 3.0 全面支持使用ojdbc5.jar。   2.不再支持oracle.jdbc.driver。从9.0.1开始的每个release都推荐使用oracle.jdbc。这一天终于到来,在11g中,引用oracle.jdbc.driver不再通过编译。   3.j2se 1.2,1.3,1.4不再支持。11R1不再包括这些版本的jar和zip,如果仍然使用这些版本,可以继续使用10gR2的jdbc。   4.11gR1 Thin driver支持AES加密算法,SHA1 hash算法,RADIUS, KERBEROS,SSL认证机制.   5.支持ANYDATE和ANYTYPE类型。这两种类型自9i引入,11R1前,程序员只能通过PL/SQL操作。   6.高级队列支持。11R1提供了访问AQ的高性能接口。   7.支持数据库变更通知。   8.Thin和OCI的数据库启动和关闭。11R1提供了这样的方法来启动和关闭数据库。   9.新的工厂方法。Oracle JDBC 11R1 oracle.jdbc.OracleConnection提供了创建Oracle对象的工厂方法。   包括ARRAY, BFILE, DATE, INTERVALDS, NUMBER, STRUCT, TIME,TIMESTAMP,TIMESTAMP等。   ojdbc5.jar: 适用于jdk5   ojdbc6.jar: 适用于jdk6   ***_g.jar 只是用javac -g编译,生成所有调试信息,其它全一样   ---------------------------------------------------   总体讲新版本的JDBC驱动 性能强、很多bug被发现并已解决。   我遇到的,之前使用ojdbc14.jar(不记得哪个版本了)批量插入10万条,实际只插入了3万多条,其它的丢失了,换ojdbc6.jar后,一次commit批量插入100万条也OK了。   尽量使用和数据库版本一致的驱动,有bug时,换高版本的JDBC驱动试试 。

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧