【发布时间】:2015-05-04 16:56:27
【问题描述】:
我的 SQL Server 2008 R2 数据库是从我创建的 SSDT 项目中部署的。在这种情况下,一个奇怪的要求是将主键列之一更改为IDENTITY,具体取决于它的部署位置。我对这个要求并不疯狂,但这不是我的问题。
我所做的是设置一个部署后脚本,该脚本应该有条件地运行,具体取决于部署发生的位置。到目前为止,一切顺利。
在我的脚本中,我正在执行ALTER TABLE ADD 命令来设置一个新列,填充它并将其重命名为旧列。在此之后,我尝试对新列执行 UPDATE 并出现故障,因为该列不存在。我在ALTER TABLE ADD 命令下放了一个GO 语句,当我单独测试运行脚本时,这解决了问题,一切正常。
-- Add a clone of the ID column with no Identity constraint
ALTER TABLE Communication ADD CommunicationIdNoIdentity INT NOT NULL;
GO
UPDATE Communication
SET CommunicationIdNoIdentity = CommunicationID;
但是,在部署后脚本的上下文中,这似乎是不合法的。使用 GO 时,我会在此处收到构建错误:
错误:SQL72007:语法检查失败“出现意外的文件结尾”。在批次附近
我该如何解决这个问题?文件上的BuildAction 设置为“无”,我认为这是正确的。
更新:虽然错误来自子脚本,但我终于将其返回给父脚本。如果我这样做:
IF @IsDeploymentToDatacenter = 'TRUE'
:r .\FixIdColumnInCommunicationTable.SQL
它有效。如果我这样做(我最初的做法),它会因我描述的错误而失败,其中包括:
IF @IsDeploymentToDatacenter = 'TRUE'
BEGIN
:r .\FixIdColumnInCommunicationTable.SQL
END
【问题讨论】:
-
GO不是 SQL 语句或命令 - 它是 SQL Server Management Studio 使用的 分隔符 和因此在常规的通用 SQL 脚本中无效 -
您是否使用 sqlcmd 语法从主要的部署后脚本运行文件?如果不是,则 BuildAction 应该是 PostDeploy。
-
@marc_s 很好,那么我怎样才能让 ALTER 执行,以便在 UPDATE 运行时,该列在那里?不使用 GO 分隔。
-
@db_brad,我有主 PostDeploy.sql 使用“:r .\FixCommunication.sql”行运行它
-
所以我在这一切中学到的一点是,SQLCMD 中的 ":r" 命令实际上更像是一个宏。也就是说,您“运行”的文件实际上会扩展为父脚本。所以如果你在里面放一个“GO”应该没问题,但是如果你用BEGIN...END包围:r调用,它会出现故障,因为“GO”切断了BEGIN。
标签: tsql sql-server-2008-r2 sql-server-data-tools