java sql server 存储过程 com.microsoft.sqlserver.jdbc.SQLServerException: 该语句没有返回结果集。

网上找到的解决办法大多是:
在sql语句前面加上
SET NOCOUNT ON
比如我的sql语句原来是exec C_GetSysAlarm ?
现在要改成SET NOCOUNT ON exec C_GetSysAlarm ?

也可以在存储过程中加入以下语句

set nocount on

### 异常原因分析 在使用 JDBC 连接 SQL Server 数据库时,遇到 `com.microsoft.sqlserver.jdbc.SQLServerException: 必须执行该语句才能获得结果` 异常,通常是因为以下几种情况: 1. **触发器未设置 `SET NOCOUNT ON`**:当表中存在触发器且未配置 `SET NOCOUNT ON` 时,SQL Server 会在执行插入、更新或删除操作时返回额外的结果,从而导致 JDBC 驱动程序无法正确获取主键值。 2. **批量插入时获取自增主键问题**:SQL ServerJDBC 驱动仅支持返回最后一个插入记录的主键值,而 MyBatis Plus 的 `saveBatch()` 方法期望获取所有插入记录的主键。由于 SQL Server 不支持批量返回主键,因此会抛出异常[^1]。 3. **存储过程未设置 `SET NOCOUNT ON`**:如果调用存储过程时未添加 `SET NOCOUNT ON`,SQL Server 可能会返回额外的信息,导致驱动程序认为没有执行有效的查询或更新操作,从而引发此异常[^3]。 ### 解决方案 #### 1. 在触发器中添加 `SET NOCOUNT ON` 若数据库表存在触发器,并且插入或更新操作触发了该触发器,则需要在触发器的开头添加 `SET NOCOUNT ON`,以防止其返回额外的结果[^2]。例如: ```sql CREATE TRIGGER trg_YourTriggerName ON YourTableName AFTER INSERT AS BEGIN SET NOCOUNT ON; -- 触发器逻辑 END ``` #### 2. 使用单条插入代替批量插入 由于 SQL ServerJDBC 驱动不支持批量插入后返回多个主键值,可以将 `saveBatch()` 拆分为多个 `save()` 调用,逐条插入数据。这样可以确保每条插入操作都能正确获取主键值[^2]。示例代码如下: ```java for (YourEntity entity : entityList) { yourMapper.insert(entity); } ``` #### 3. 修改 SQL存储过程前添加 `SET NOCOUNT ON` 对于涉及插入、更新或删除操作的 SQL 语句存储过程,在其前面添加 `SET NOCOUNT ON`,以避免返回影响行数等多余信息。例如: ```sql SET NOCOUNT ON; EXEC YourStoredProcedure @param1 = 'value'; ``` 或者在存储过程中直接设置: ```sql CREATE PROCEDURE YourStoredProcedure AS BEGIN SET NOCOUNT ON; -- 存储过程逻辑 END ``` #### 4. 确保正确处理插入语句并关闭自动提交(如适用) 在某些情况下,JDBC 的 `Statement` 或 `PreparedStatement` 对象可能未正确执行插入语句,或者事务管理配置不当。应确保在插入操作完成后调用 `executeUpdate()` 并正确提交事务,尤其是在手动控制事务的情况下。 #### 5. 升级 JDBC 驱动版本 检查当前使用的 JDBC 驱动是否为最新版本,部分旧版本可能存在兼容性问题。建议升级至最新的 Microsoft JDBC Driver for SQL Server,以获得更好的功能支持和稳定性。 --- ### 总结 `com.microsoft.sqlserver.jdbc.SQLServerException: 必须执行该语句才能获得结果` 主要与 SQL Server 返回结果的方式有关。通过合理使用 `SET NOCOUNT ON`、避免使用不支持的功能(如批量插入获取主键)以及确保正确的 SQL 和事务处理方式,可以有效解决此类问题。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值