部署包含 $(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) 并被请求的值替换
我有一个 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) 并被请求的值替换