我在SQL Server 2005中有以下SQL,但是当我运行它时,我收到一条错误,指出“无效的列名'ExpIsLocalTime'(ln 7):
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'ExpIsLocalTime' AND Object_ID = Object_ID(N'[dbo].[tbl_SessionsAvailable]'))
BEGIN
ALTER TABLE dbo.tbl_SessionsAvailable ADD
ExpIsLocalTime bit NOT NULL CONSTRAINT DF_tbl_SessionsAvailable_ExpIsLocalTime DEFAULT (0)
UPDATE dbo.tbl_SessionsAvailable
SET ExpIsLocalTime = 1
END
GO
这将在一个可能多次运行的脚本文件中,所以我试图确保UPDATE
只运行一次。 BEGIN / END有什么延迟执行DDL语句吗?
答案 0 :(得分:1)
执行UPDATE
的SQL查询是指尚未创建的列。在编译时,SQL Server检测到该列不存在,因此它会向您显示错误“无效的列名称'ExpIsLocalTime'”。
为了在此查询中包含UPDATE
,您需要将其封装在动态SQL查询中。换句话说,就像这样:
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'ExpIsLocalTime' AND Object_ID = Object_ID(N'[dbo].[tbl_SessionsAvailable]'))
BEGIN
ALTER TABLE dbo.tbl_SessionsAvailable ADD
ExpIsLocalTime bit NOT NULL CONSTRAINT DF_tbl_SessionsAvailable_ExpIsLocalTime DEFAULT (0)
DECLARE @SQL NVARCHAR(1000)
SELECT @SQL = N'UPDATE dbo.tbl_SessionsAvailable SET ExpIsLocalTime = 1'
EXEC sp_executesql @SQL
END
GO
我们在维护表的SQL脚本中遇到了同样的问题。创建表后,如果我们稍后添加一个列,我们必须使用动态SQL来避免这些编译错误。
答案 1 :(得分:0)
另一个可能更简单的解决方案是在Alter语句之后使用GO语句。这会将DDL发送到服务器。然后运行其余的SQL。如果您使用的是sqlcmd osql或SSMS,则此方法应该有效。