部署包含 $(ESCAPE_SQUOTE()) 的 SQL 更改

Deploying SQL Changes Containing $(ESCAPE_SQUOTE())

我有一个 Database project in Visual Studio that I am attempting to deploy automatically to a test environment nightly. To accomplish this I am using TFS which leverages a PowerShell script to run "SqlPackage.exe" 来部署白天发生的任何更改。

我的某些过程包含 运行 脚本内部的逻辑,该脚本是代理作业步骤的一部分,并且包含 following code(在动态 SQL 中):

$(ESCAPE_SQUOTE(JOBID))

部署影响此过程的更改时,出现以下问题:

SQL Execution error: A fatal error occurred. Incorrect syntax was encountered while $(ESCAPE_SQUOTE( was being parsed.

这是一个 known issue, it appears as though that is not supported. It appears to be a function of the "SQLCmd" command misinterpreting the $( characters as a variable:

"override the value of a SQL command (sqlcmd) variable used during a publish action."

那么我该如何解决这个问题呢?不能禁用变量似乎是 "sqlcmd" 的主要限制,我没有看到支持该参数的参数...

更新 1

似乎可以通过向 "sqlcmd" 提供 "-x" 参数来禁用变量替换 (Source, Documentation):

-x (disable variable substitution)

尽管 "SqlPackage.exe" 仍然没有找到执行此操作的方法。

解决此问题的一种方法是将“$(ESCAPE_SQUOTE(JOBID))”字符串重构为标量函数,然后设置 PowerShell 脚本以直接调用 "Sqlcmd" 命令"Create/Alter" 的“-x”参数表示 运行 "SqlPackage.exe" 之前的函数。

在 PowerShell 中看起来像这样:

$sql = @"
USE $database
GO

CREATE FUNCTION [dbo].[GetJobID] ()
RETURNS NVARCHAR(MAX)
AS
BEGIN
    RETURN '$(ESCAPE_SQUOTE(JOBID))'
END

GO
"@;

Sqlcmd -S $servername -U $username -P $password -Q $sql -x; 

这是一个非常糟糕的解决方法,但它确实完成了任务。真的希望有更好的东西。

似乎 sqlcmd 寻找 $( 作为标记,所以将这两个字符分开就足够了。您可以使用动态查询执行此操作,该查询仅将查询分成两个字符串:

DECLARE @query nvarchar(256) = N'... $' + N'(ESCAPE_SQUOTE(JOBID)) ...';
EXEC sp_executesql @query

我提出另一种解决方法 我的工作有一个步骤 运行 : DTEXEC.exe /SERVER "$(ESCAPE_NONE(SRVR))"

我只需要在之前添加一个 SQLCMD 变量: :setvar SRVR "$(ESCAPE_NONE(SRVR))"

这样,令牌被视为 SQLCMD 变量 $(SRVR) 并被请求的值替换