动态执行SQL时已检查列存在仍报Fråga5不存在的问题
解决SQL Server动态SQL中列已删除仍报错的问题
问题背景
提前删除了Fråga5列,通过动态SQL循环检查Fråga3到Fråga21列的存在性:
- 若列存在,打印计数器值和'HÄR'
- 同时关联临时表
#Donelist统计该列的非空行数,若计数大于0则打印'DÄR'
执行时循环到Fråga5时,即便已经通过IF EXISTS检查列存在性,仍报错Invalid column name 'Fråga5',导致SQL Server代理作业终止。
报错原因
SQL Server执行动态SQL时,会先编译整个批处理语句。哪怕IF EXISTS的判断结果为假,编译阶段仍会扫描整个语句中的对象,发现Fråga5不存在就直接抛出错误,不会进入IF分支的执行逻辑。
解决方案
方案1:嵌套动态SQL,延迟计数逻辑的编译
将内部的计数判断逻辑也封装到动态SQL中,确保只有当列存在时,才编译并执行统计语句,避免编译阶段检测到不存在的列。
修改后的代码:
ALTER TABLE dbo.tbl_TEMP_Temptable DROP COLUMN Fråga5 PRINT 'PRINT4' SET @RemoveColumnPart2COunter = 3 WHILE(@RemoveColumnPart2COunter <= 21) BEGIN PRINT @RemoveColumnPart2COunter SET @RemoveColumnPart2 = 'IF EXISTS(SELECT * FROM x.information_schema.columns WHERE TABLE_NAME = '+ CHAR(39)+'tbl_TEMP_Temptable'+ CHAR(39)+' AND COLUMN_NAME = '+ CHAR(39)+ 'Fråga'+@RemoveColumnPart2COunter + CHAR(39)+') BEGIN print '+CHAR(39) + @RemoveColumnPart2COunter+ ' HÄR'+CHAR(39)+' DECLARE @CountSQL NVARCHAR(MAX) SET @CountSQL = N''IF((SELECT COUNT(Fråga'+@RemoveColumnPart2COunter+') FROM dbo.tbl_TEMP_Temptable t INNER JOIN #Donelist d ON d.Utrustning = t.Utrustning) > 0 ) BEGIN print ''''DÄR'''' END'' EXEC sp_executesql @CountSQL END' EXEC (@RemoveColumnPart2) SET @RemoveColumnPart2COunter = @RemoveColumnPart2COunter + 1 END PRINT 'PRINT5'
方案2:提前过滤存在的列,避免处理无效列
先查询系统视图获取表中实际存在的FrågaX列,存入临时表后再循环处理,从根源上跳过不存在的列。
修改后的代码:
ALTER TABLE dbo.tbl_TEMP_Temptable DROP COLUMN Fråga5 PRINT 'PRINT4' -- 提前获取所有存在的Fråga列(3到21之间) CREATE TABLE #ExistingColumns (ColName NVARCHAR(100), Counter INT) INSERT INTO #ExistingColumns SELECT COLUMN_NAME, CAST(REPLACE(COLUMN_NAME, 'Fråga', '') AS INT) FROM x.information_schema.columns WHERE TABLE_NAME = 'tbl_TEMP_Temptable' AND COLUMN_NAME LIKE 'Fråga%' AND CAST(REPLACE(COLUMN_NAME, 'Fråga', '') AS INT) BETWEEN 3 AND 21 -- 用游标循环处理存在的列 DECLARE @Counter INT DECLARE col_cursor CURSOR FOR SELECT Counter FROM #ExistingColumns ORDER BY Counter OPEN col_cursor FETCH NEXT FROM col_cursor INTO @Counter WHILE @@FETCH_STATUS = 0 BEGIN PRINT @Counter PRINT CAST(@Counter AS VARCHAR) + ' HÄR' -- 动态生成并执行计数判断逻辑 DECLARE @CountSQL NVARCHAR(MAX) SET @CountSQL = N'IF((SELECT COUNT(Fråga'+CAST(@Counter AS VARCHAR)+') FROM dbo.tbl_TEMP_Temptable t INNER JOIN #Donelist d ON d.Utrustning = t.Utrustning) > 0 ) BEGIN print ''DÄR'' END' EXEC sp_executesql @CountSQL FETCH NEXT FROM col_cursor INTO @Counter END CLOSE col_cursor DEALLOCATE col_cursor DROP TABLE #ExistingColumns PRINT 'PRINT5'
方案对比
- 方案1:在原有逻辑基础上最小化修改,通过嵌套动态SQL延迟编译,适合快速调整现有代码
- 方案2:提前过滤无效列,逻辑更清晰,避免不必要的判断和编译,性能更优
内容的提问来源于stack exchange,提问作者Jonas
相关产品推荐
相关产品推荐

