SQL遍历表行校验visible值并批量更新的存储过程实现问题
需求实现方案
优先推荐:非游标集合操作实现
SQL是面向集合的查询语言,该需求不需要使用游标即可实现,代码更简洁、执行效率更高:
UPDATE t SET visible = 'yes' FROM 你的实际表名 t INNER JOIN ( -- 筛选出所有visible全为no的row SELECT [row] FROM 你的实际表名 GROUP BY [row] HAVING MAX(visible) = 'no' AND MIN(visible) = 'no' ) all_no_rows ON t.[row] = all_no_rows.[row]
逻辑说明:先按row分组,只要分组内visible的最大值和最小值都是no,就说明该分组下所有记录的visible都是no,再关联原表批量更新即可。
补全你的游标实现代码
如果你必须使用游标完成,可参考下面的补全代码:
CREATE PROCEDURE someProcedure AS BEGIN SET NOCOUNT ON; DECLARE @visible VARCHAR(5) DECLARE @column INT DECLARE @current_row INT -- 新增变量存储上一个处理的row,以及当前row是否全为no的标记 DECLARE @last_row INT = -1 DECLARE @is_all_no BIT = 1 -- 游标查询新增row字段,注意保留关键字用方括号包裹 DECLARE scan CURSOR FOR SELECT [row], [column], visible FROM [你的实际表名] ORDER BY [row], [column] OPEN scan -- 读取第一行数据 FETCH NEXT FROM scan INTO @current_row, @column, @visible WHILE @@FETCH_STATUS = 0 BEGIN -- 切换到新的row分组时,先处理上一个row的更新逻辑 IF @current_row != @last_row BEGIN -- 上一个row全为no时,批量更新该row下所有记录 IF @last_row != -1 AND @is_all_no = 1 BEGIN UPDATE [你的实际表名] SET visible = 'yes' WHERE [row] = @last_row END -- 重置标记,更新当前处理的row SET @is_all_no = 1 SET @last_row = @current_row END -- 只要当前记录visible不是no,标记该分组不是全no IF @visible != 'no' BEGIN SET @is_all_no = 0 END -- 读取下一行数据 FETCH NEXT FROM scan INTO @current_row, @column, @visible END -- 循环结束后处理最后一个row分组 IF @last_row != -1 AND @is_all_no = 1 BEGIN UPDATE [你的实际表名] SET visible = 'yes' WHERE [row] = @last_row END -- 释放游标资源 CLOSE scan DEALLOCATE scan END
注意事项
- 代码中的
你的实际表名需要替换为你真实的表名 row、column属于SQL保留关键字,作为字段名使用时必须用方括号包裹,避免语法报错
内容的提问来源于stack exchange,提问作者Eugen Gîrlescu
相关产品推荐
相关产品推荐

