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

时间:2017-07-13 21:03:08

标签: sql-server visual-studio sqlcmd sqlpackage

我在Visual Studio中有Database project,我试图每晚自动部署到测试环境。为了实现这一点,我使用TFS,它利用PowerShell脚本运行" SqlPackage.exe"部署当天发生的任何更改。

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

$(ESCAPE_SQUOTE(JOBID))

在部署影响此proc的更改时,我遇到以下问题:

  

SQL执行错误:发生致命错误。语法不正确   遇到$(ESCAPE_SQUOTE(正在解析。

这是known issue,好像不支持。它似乎是" SQLCmd"命令误解$(字符为variable

  

"覆盖a期间使用的SQL命令(sqlcmd)变量的值   发布行动。"

那么我该如何解决这个问题呢?这似乎是" sqlcmd"您无法禁用变量,我也看不到支持该变量的参数......

更新1

似乎你可以通过" sqlcmd"来禁用变量替换。喂它" -x"参数(SourceDocumentation):

  

-x(禁用变量替换)

仍然没有从" SqlPackage.exe"中看到一种方法。虽然。

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

解决此问题的一种方法是将“$(ESCAPE_SQUOTE(JOBID))”字符串重构为标量函数,然后设置PowerShell脚本以直接调用“Sqlcmd”命令,并将“-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; 

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

答案 2 :(得分:0)

我提出了另一种解决方法 我的工作正在运行: DTEXEC.exe / SERVER“ $(ESCAPE_NONE(SRVR))”

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

通过这种方式,将分支视为SQLCMD变量$(SRVR),并替换为请求的值