SQL存储过程校验表重复值:打印错误后如何继续WHILE循环
存储过程修改方案(检测全表重复值+键名合规校验)
你原有代码的问题出在键不匹配的分支里用了BREAK,会直接终止整个循环,只要改成跳过当前表、继续执行下一个游标即可满足需求,具体修改如下:
修改要点
- 删除异常分支里的
BREAK关键字,替换为游标下探+CONTINUE逻辑,避免死循环同时不中断整体遍历 - 合并错误打印信息,直观展示异常表名和预期键名
- 新增非Dim/Fact前缀表的兼容判断,避免空键名导致后续SQL执行报错
- 可选新增重复值过滤条件,只留存出现次数大于1的重复键,减少临时表冗余数据
修改后完整代码
WHILE @@FETCH_STATUS = 0 BEGIN DECLARE @campo VARCHAR(100) = NULL DECLARE @sqlCommand NVARCHAR(MAX) = '' -- 建议用NVARCHAR适配动态SQL规范 -- 按规则生成对应键名 IF @table LIKE 'Dim%' SET @campo = SUBSTRING(@table, 4, LEN(@table)-3) + 'Key' -- 修正SUBSTRING长度参数,避免生成多余字符 ELSE IF @table LIKE 'Fact%' SET @campo = SUBSTRING(@table, 5, LEN(@table)-4) + 'Key' ELSE BEGIN -- 非维度/事实表可按需选择抛出提示或者直接跳过 PRINT '警告:表 ' + @table + ' 不属于Dim/Fact类型,跳过检测' FETCH NEXT FROM mycursor INTO @table CONTINUE END -- 校验表中是否存在符合规则的键 IF NOT EXISTS( SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @table AND COLUMN_NAME = @campo AND TABLE_SCHEMA = 'dev_dwh' ) BEGIN RAISERROR ('错误:表 %s 的键命名不符合规则,预期键名为 %s', 16, 6, @table, @campo) -- 先拉取下一个游标,再跳过当前表后续逻辑 FETCH NEXT FROM mycursor INTO @table CONTINUE END -- 统计重复值,默认只保留重复的记录(可按需去掉HAVING条件保留全量统计) SET @sqlCommand = 'INSERT INTO #BaseData (TableName, KeyValue, KeyValueCount) SELECT '''+ @table+ ''' AS TableHere, '+@campo +', COUNT('+@campo +') AS COUNTVALUE FROM [dev_dwh].[' + @table + '] GROUP BY '+@campo +' HAVING COUNT('+@campo +') > 1' EXEC sp_executesql @sqlCommand -- 推荐用sp_executesql替代直接EXEC,安全性和性能更优 FETCH NEXT FROM mycursor INTO @table END
注意事项
如果不需要过滤非重复值,把动态SQL里的HAVING子句删掉即可;如果需要对非Dim/Fact类型的表也做处理,可以自行补充对应前缀的键名生成规则。
内容的提问来源于stack exchange,提问作者Jason_mils
相关产品推荐
相关产品推荐

