这对我来说一直是一个令人讨厌的问题,我很想知道这些SQL Batch命令无法正常工作的原因。
我有一张表用于保存系统的配置设置。添加新设置后,我们会向表中添加一个新字段。在更新期间,我需要使用相同的脚本更改服务器上的大量数据库。通常,它们都处于相同的状态,我可以执行以下操作:
Alter Table Configuration Add ShowClassesInCheckin bit;
GO
Update Configuration Set ShowClassesInCheckin=ShowFacilitiesInCheckin;
GO
这很好用。但是,有时一个或两个数据库会更新,所以我想编写条件逻辑,只有在该字段尚不存在时才进行这些更改:
if Not Exists(select * from sys.columns where Name = N'ShowClassesInCheckin' AND Object_ID = Object_ID(N'Configuration'))
BEGIN
Alter Table Configuration Add ShowClassesInCheckin bit;
Update Configuration Set ShowClassesInCheckin=ShowFacilitiesInCheckin;
END;
GO
在这种情况下,我收到一个错误:“无效的列名'ShowClassesInCheckin'”现在,这是有道理的,因为在调用Update之前批处理表没有在批处理中进行调用(如果没有Alter和Update之间的“GO”。但这没有帮助......我仍然不知道如何实现我的目标......
答案 0 :(得分:5)
整个SQL脚本在执行之前进行解析。在解析阶段,该列将不存在,因此解析器会生成错误。在执行脚本的第一行之前引发错误。
解决方案是动态SQL:
exec (N'Update Configuration Set ShowClassesInCheckin=ShowFacilitiesInCheckin;')
在达到exec
之前不会对此进行解析,到那时,该列将存在。
答案 1 :(得分:0)
应该有效的替代方案是重新引入go。这意味着您需要使用其他内容作为更新的条件,可能基于数据库名称。
if Not Exists(select * from sys.columns where Name = N'ShowClassesInCheckin' AND Object_ID = Object_ID(N'Configuration'))
BEGIN
Alter Table Configuration Add ShowClassesInCheckin bit;
END;
GO
if *new condition here*
BEGIN
Update Configuration Set ShowClassesInCheckin=ShowFacilitiesInCheckin;
END;
GO