一个BEGIN ... END块内的多个语句

问题描述 投票:3回答:3

在我的安装程序中,我必须对架构进行一些小改动:

IF NOT EXISTS (SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[UserProfiles]') AND name = 'AllCheckboxesChecked')
BEGIN
  ALTER TABLE [dbo].[UserProfiles] ADD [AllCheckboxesChecked] [bit] CONSTRAINT [DF_UserProfiles_AllCheckboxesChecked] DEFAULT 0 NOT NULL
  UPDATE [dbo].[UserProfiles] SET [AllCheckboxesChecked]=1 WHERE [CheckedBoxes] LIKE '%#ALL#%'
END
GO

在SSMS中,这可以工作,但在高级安装程序中没有,它失败并显示AllCheckboxesChecked列不存在的错误消息。所以我尝试过:

IF NOT EXISTS (SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[UserProfiles]') AND name = 'AllCheckboxesChecked')
BEGIN
  ALTER TABLE [dbo].[UserProfiles] ADD [AllCheckboxesChecked] [bit] CONSTRAINT [DF_UserProfiles_AllCheckboxesChecked] DEFAULT 0 NOT NULL
  GO
  UPDATE [dbo].[UserProfiles] SET [AllCheckboxesChecked]=1 WHERE [CheckedBoxes] LIKE '%#ALL#%'
END
GO

但是这也会引发语法错误(不是在SSMS中,只在AdvInst中),所以我想在BEGIN ... END块中不允许使用GO。连接配置如下:

Connection type: Microsoft SQL Server / MSDE
Connection mode: ODBC Driver
ODBC Driver: SQL Server
Use 64-bit ODBC resource: No

如果安装程序在列尚不存在的DB上运行,我可以采取哪些步骤来创建列并使用正确的值填充?

sql-server tsql advanced-installer
3个回答
7
投票

column doesn't exist错误是由于现有对象上发生的验证。由于表已经存在,解析器/编译器将验证该表是否包含所有引用的列。

为了解决对象验证的这些时间问题,您可以将语句括在EXEC中,直到运行时才会对其进行验证:

BEGIN
  ALTER TABLE [dbo].[UserProfiles]
    ADD [AllCheckboxesChecked] [bit]
    CONSTRAINT [DF_UserProfiles_AllCheckboxesChecked] DEFAULT 0
    NOT NULL;

  EXEC(N'UPDATE [dbo].[UserProfiles]
         SET [AllCheckboxesChecked]=1
         WHERE [CheckedBoxes] LIKE ''%#ALL#%''');
END;

0
投票

GO语句是批处理终止符,批处理中的项只能在批处理结束时提交,可以在下一个GO语句中或在脚本结束时到达。在您的情况下,包含ALTER COLUMN语句的批处理尚未提交,因此您会收到该列不存在的错误。您必须将脚本分为两部分。


0
投票

GO是一个批处理终止符 - 它特定于您使用的工具而不是SQL Server - 所以如果您放置

Statement1
GO
Statemetn2

这将作为两个单独的执行(批处理)发送到SQL Server。

基本上你将你的查询分成两批,第一批你没有关闭BEGIN块,而在第二批你没有开始END块!

© www.soinside.com 2019 - 2024. All rights reserved.