1

我在 Visual Studio 中有一个数据库项目,我试图每晚自动部署到测试环境。为此,我使用了 TFS,它利用 PowerShell 脚本运行“ SqlPackage.exe ”来部署白天发生的任何更改。

我的一些 proc 包含在作为代理作业步骤的一部分的脚本内运行的逻辑,并包含以下代码(在动态 SQL 中):

$(ESCAPE_SQUOTE(JOBID))

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

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

这是一个已知问题,似乎不受支持。它似乎是“SQLCmd”命令将 $( 字符误解为变量的函数:

“覆盖发布操作期间使用的 SQL 命令 (sqlcmd) 变量的值。”

那么我该如何解决呢?您无法禁用变量似乎是“sqlcmd”的一个主要限制,我没有看到支持该参数的参数......

更新 1

似乎通过您可以通过提供“-x”参数( SourceDocumentation )来禁用“sqlcmd”中的变量替换:

-x(禁用变量替换)

不过,仍然看不到从“SqlPackage.exe”中执行此操作的方法。

4

3 回答 3

2

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

DECLARE @query nvarchar(256) = N'... $' + N'(ESCAPE_SQUOTE(JOBID)) ...';
EXEC sp_executesql @query
于 2018-12-21T00:55:52.983 回答
0

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

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

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

于 2019-09-16T13:23:20.620 回答
0

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

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

于 2017-07-17T14:59:14.467 回答