sql 数据库项目中的 SQLCMD 脚本中的 If 条件

If condition in SQLCMD script in sql database project

我在 Visual Studio 中创建了 Sql 服务器数据库项目,我想知道是否可以使用类似这样的东西

预部署脚本

:setvar Environment Production

post部署脚本

IF '$(Environment)' = 'Production'
BEGIN
    ALTER VIEW [dbo].[vwTable]
    AS
        SELECT Col1, Col2 FROM Production.database.dbo.Table1
    GO
END
ELSE
BEGIN
    ALTER VIEW [dbo].[vwTable]
    AS
        SELECT Col2, Col3, Col4 FROM LinkedServer.Development.database.dbo.Table2
    GO
END

错误是:Alter view must be the only statement in the batch.

或更简单的版本

ALTER VIEW [dbo].[vwTable]
AS
IF '$(Environment)' = 'Production'
    SELECT Col1, Col2 FROM Production.database.dbo.Table1
ELSE
    SELECT Col2, Col3, Col4 FROM LinkedServer.Development.database.dbo.Table2
GO

错误是:Incorrect syntax near IF. Expecting Select or With

知道吗,你的方法是什么?

你不能写成:

ALTER VIEW [dbo].[vwTable] AS SELECT Col1, Col2 FROM $(Environment).database.dbo.Table1 GO

您也应该能够控制不同的列,因为我相信命令变量只是在脚本运行之前将文本植入脚本。

您应该使用 Procedure 而不是 View 和传递环境的参数。 ALTER VIEW 语句必须是批处理的第一条语句,因此您不能以这种方式使用它。即使您以某种方式执行 ALTER VIEW 语句,您也无法创建 VIEW. As a view is a plainT-SQLand cannot understandSQLCMD` commands/variables .

程序可能如下所示。

CREATE PROCEDURE [dbo].[usp_Results_Based_On_Environment] (@pEnvironment varchar(50))
AS
BEGIN
    IF @pEnvironment = 'Production'
        SELECT Col1, Col2 FROM Production.database.dbo.Table1
    ELSE
        SELECT Col2, Col3, Col4 FROM LinkedServer.Development.database.dbo.Table2
END
GO

这不完全是我想做的,但它也帮助我解决了问题。 可以包含文件,但我需要在发布前手动 comment/uncomment 特定行。

:r .\included\production.views.script.sql
--:r .\included\development.views.script.sql

该文件还可以包含许多 GO 语句。

有一种方法可以做到这一点,但该信息必须首先以:

不要   do   这个!!

您的对象定义确实需要在所有环境中都相同。元数据(如在配置数据中)可以不同,但​​不是对象定义。否则你就是在为失败做好准备(更不用说下一个接管这件事的不幸的人了)。这是不可维护的。使用链接服务器和不使用链接服务器在性能、功能和安全性方面存在差异。在您当前的设置中,针对此代码完成的任何 QA 都是无效的,因为它甚至无法在每个环境中测试相同的东西。

但是,可以理解存在需要处理的特定于环境的差异。在这种情况下,您应该在每个环境中有不同的链接服务器定义。在一个或多个环境中不需要链接服务器?没关系,只需创建一个指向它当前所在实例的 "loop back" 链接服务器。


也就是说,您只需要将需要自己批处理的对象的定义埋入 EXEC,例如:

IF ('$(Environment)' = 'Production')
BEGIN
    EXEC(N'ALTER VIEW [dbo].[vwTable]
           AS
           SELECT Col1, Col2
           FROM Production.database.dbo.Table1;');
END
ELSE
BEGIN
    EXEC(N'ALTER VIEW [dbo].[vwTable]
           AS
           SELECT Col2, Col3, Col4
           FROM LinkedServer.Development.database.dbo.Table2;');
END;