You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从.NET调用带游标SQL存储过程报「游标为只读」错误求助

游标报错"The cursor is READ ONLY"的问题原因与修复方案

问题核心原因

报错是SQL Server游标默认行为触发的,核心诱因有两个:

  1. 你的游标查询语句带了ORDER BY子句,SQL Server默认会为带排序的游标生成临时工作表来完成排序,此时游标自动被设为只读属性,即便你声明了FOR UPDATE也不会生效,无法通过WHERE CURRENT OF语法定位原表行完成更新。
  2. 如果你使用的临时表#Res没有创建主键或者唯一索引,游标无法唯一确定每一行的定位,也会被强制设为只读模式。

修复方法

方法1:显式指定游标为可更新类型

修改游标声明语句,明确指定游标为动态可更新类型,同时提前给临时表加唯一索引/主键:

  1. 在创建#Res表后添加主键:ALTER TABLE #Res ADD PRIMARY KEY (ArtId)
  2. 修改游标声明行代码为:
DECLARE CabCursor CURSOR DYNAMIC FOR 
SELECT ArtId from #Res 
WHERE TipoRegistro = 1 order by TipoRegistro, Año, NumSemana, ArtCodigo
FOR UPDATE OF ArtStockInicial, ArtStockFinal

方法2:规避游标定位更新逻辑(更推荐)

直接用取出的@idArt匹配更新临时表,完全不需要依赖游标自身的更新能力,也不会触发只读报错,代码兼容性和执行效率更高,只需修改UPDATE语句即可:

-- 把原来的WHERE CURRENT OF更新逻辑替换为按ArtId匹配
update #Res
set ArtStockInicial= @stockInicial, ArtStockFinal = @stockFinal
where ArtId = @idArt

修改后游标声明可以去掉FOR UPDATE子句,逻辑更简洁。

可选优化建议

如果业务逻辑允许,可以把逐行调用存储过程的游标逻辑改为集合操作,比如将CalcularExistenciasParaArticulo改造为表值函数,一次更新所有符合条件的行,避免游标带来的性能开销。

内容的提问来源于stack exchange,提问作者Joselz94

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 07:27:04