如何通过JDBC获取SQL Server批量插入的成功行数?
解决Java执行BULK INSERT后获取插入行数的问题
我明白你遇到的困扰了——在SSMS里能正常拿到插入行数,但用Java的executeQuery就报错,这是因为executeQuery只适合执行纯查询语句(比如SELECT),而BULK INSERT属于数据操作语句,本身不会返回结果集,直接用它自然会触发"Statement did not return a result set"错误。
下面给你两种可行的解决办法:
方法一:使用execute()方法处理复合语句
execute()方法可以兼容既包含数据操作又包含查询的语句,它会返回一个布尔值表示是否有结果集。我们可以把BULK INSERT和SELECT @@ROWCOUNT放在同一个批处理里执行,然后获取结果集里的行数:
Statement stmt = sqlConnection.createStatement(); // 用分号分隔两个操作,确保在同一个会话中执行 boolean hasResultSet = stmt.execute("BULK INSERT schema1.table1 FROM 'd:\\temp1\\file1.tab'; SELECT @@ROWCOUNT"); if (hasResultSet) { ResultSet rs = stmt.getResultSet(); if (rs.next()) { int insertedRows = rs.getInt(1); System.out.println("成功插入的记录数:" + insertedRows); } rs.close(); } stmt.close();
这里一定要注意:必须把两个操作放在同一个语句里执行,因为@@ROWCOUNT只会保存上一条SQL语句的影响行数,如果分开执行,中间可能被其他隐性操作覆盖,导致拿到错误的数值。
方法二:用存储过程封装操作
如果觉得直接写复合语句不够优雅,也可以把逻辑封装到SQL Server的存储过程里,再用CallableStatement调用并获取结果:
1. 先创建存储过程
CREATE PROCEDURE BulkInsertTabFile @FilePath NVARCHAR(255) AS BEGIN SET NOCOUNT ON; BULK INSERT schema1.table1 FROM @FilePath; SELECT @@ROWCOUNT AS InsertedCount; END
2. Java代码调用存储过程
String sql = "{CALL BulkInsertTabFile(?)}"; CallableStatement cstmt = sqlConnection.prepareCall(sql); cstmt.setString(1, "d:\\temp1\\file1.tab"); boolean hasResultSet = cstmt.execute(); if (hasResultSet) { ResultSet rs = cstmt.getResultSet(); if (rs.next()) { int insertedRows = rs.getInt("InsertedCount"); System.out.println("成功插入的记录数:" + insertedRows); } rs.close(); } cstmt.close();
这种方式更适合复用逻辑,也能让Java代码结构更整洁。
最后提个小提醒:要确保SQL Server的服务账户有访问d:\temp1\file1.tab这个文件的权限,不然BULK INSERT本身可能会执行失败哦。
内容的提问来源于stack exchange,提问作者Paresh
相关产品推荐
相关产品推荐

