我在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"您无法禁用变量,我也看不到支持该变量的参数......
似乎你可以通过" sqlcmd"来禁用变量替换。喂它" -x"参数(Source,Documentation):
-x(禁用变量替换)
仍然没有从" SqlPackage.exe"中看到一种方法。虽然。
答案 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),并替换为请求的值