【问题标题】:If condition in SQLCMD script in sql database projectsql 数据库项目中的 SQLCMD 脚本中的 if 条件
【发布时间】:2017-08-03 11:10:00
【问题描述】:

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

预部署脚本

:setvar Environment Production

部署后脚本

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

任何想法,你的方法是什么?

【问题讨论】:

  • @Mufflix,您不能在 SQL Server VIEW 中使用 IF 条件。
  • @Venu 我知道,但是如何在 SQLCMD 中使用条件?因为我对生产和开发有不同的看法。
  • 你是说你有VIEWSQLCMD模式的SQL Server,它必须根据环境来决定执行哪个语句?我不相信。
  • @Venu 为什么不呢,不然怎么办?
  • 你无法用视图解决这个问题。您可能需要创建过程。我在下面添加了详细信息作为答案。

标签: sql-server visual-studio tsql deployment sqlcmd


【解决方案1】:

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

不要 这样做 这个!!

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

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


也就是说,您只需将需要自己批处理的对象的定义埋在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;

【讨论】:

    【解决方案2】:

    你不能写成:

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

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

    【讨论】:

    • 我在其他地方使用了这种技术,但我在省略 LinkedServer 地址时遇到了问题,我更新了问题。另外我认为这是一种解决方法而不是解决方案,因为将来它可能是更复杂的 sql 查询,但是谢谢!
    【解决方案3】:

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

    该过程可能如下所示。

    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
    

    【讨论】:

    • 我只需要更新现有的部署脚本,它将根据环境执行 SQL 查询。我不想更改我的数据库架构。 sql server 不知道开发服务器,我相信“创建过程查询”无论如何都会失败。
    【解决方案4】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-19
      • 2012-05-17
      • 2011-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多