Sql server sqlcmd/Invoke sqlcmd中的转义变量

Sql server sqlcmd/Invoke sqlcmd中的转义变量,sql-server,windows,powershell,sqlcmd,invoke-sqlcmd,Sql Server,Windows,Powershell,Sqlcmd,Invoke Sqlcmd,我正在使用powershell和。我能够将变量传递给SQL: $variables = @( "MyVariable='hello'" ) Invoke-SqlCmd ` -ServerInstance 'localhost' ` -Database 'master' ` -Username 'matthew' ` -Password 'qwerty' ` -Query 'SELECT $(MyVariable) AS foo' ` -Varia

我正在使用powershell和。我能够将变量传递给SQL:

$variables = @( "MyVariable='hello'" )

Invoke-SqlCmd `
    -ServerInstance 'localhost' `
    -Database 'master' `
    -Username 'matthew' `
    -Password 'qwerty' `
    -Query 'SELECT $(MyVariable) AS foo' `
    -Variable $variables
这让我如期回复了
hello
。但是,如果我有一个变量,其值包含等于(
=
):

它给了我以下错误:

用于为
Invoke Sqlcmd
cmdlet定义新变量的格式无效。请使用“var=value”格式定义新变量

我找不到任何关于
sqlcmd
Invoke sqlcmd
如何正确转义值的文档


在使用一些反射进行调查之后,如何转义发送到
sqlcmd
/
调用sqlcmd

的变量

C:\Program Files(x86)\Microsoft SQL Server\120\Tools\PowerShell\Modules\SQLPS\Microsoft.SqlServer.Management.PSSnapins.dll

查看
ExecutionProcessor
的构造函数,以下几行揭示了一个问题,即如果变量定义中有多个等号,它将失败

我建议其他尝试使用
调用SqlCmd
的人节省时间和理智,只需使用开源替代方案即可


Microsoft,请修复。

我最近遇到了这个问题,并成功地使用了来自Mad技术人员的答案:

答案是在字符串中创建子表达式以替换' 带有“”

Invoke Sqlcmd-ServerInstance“$SQLServer”-Database“$SqlDB”-query”INSERT INTO dbo.ecca_sw_standard_2(名称、版本、产品id)值(N'$($CSVAppName-replace“,”),“'$($CSVVersion-replace“,”),“'$($CSVAppID-replace“,”),“)”)“

这样当 字符串被展开,它将被适当地转义以进行SQL插入


我还发现自己需要传递一段base64编码的信息,其中包含那些讨厌的“=”。对我有效的方法是将替换令牌添加到传递给查询的变量数组中,然后在查询中使用SQL的REPLACE函数将令牌替换为“=”符号

因此,您可以将代码更新为如下所示:

$equalsSignReplacement = '[EQUALSIGN]'
$myVariable = 'aGVsbG8NCg=='
$variables = 
    "EqualsSignReplacement=$($equalsSignReplacement)",
    "MyVariable=$($myVariable.Replace('=',$equalsSignReplacement))"

Invoke-SqlCmd `
    -ServerInstance 'localhost' `
    -Database 'master' `
    -Username 'matthew' `
    -Password 'qwerty' `
    -Query 'SELECT REPLACE('$(MyVariable)','$(EqualsSignReplacement)','=') AS foo' `
    -Variable $variables
此解决方案的缺点是,您需要对其应用程序采取主动。您需要提前知道哪些变量中可能有“等号”,然后不仅更新powershell代码,还更新SQL脚本,以确保正确进行替换

只需确保使用变量独有的替换标记,以免在查询中意外地将有效文本替换为“=”。

使用
CHAR(61)
替换等号

$variable = "'Hello=World'"
$variables = @( "MyVariable=$($variable.replace("=","'+CHAR(61)+'"))" )

Invoke-SqlCmd -ServerInstance 'localhost' -Database 'master' -Query 'SELECT $(MyVariable) AS foo' -Variable $variables

尽管这可能会解决OP的问题,但为了将来参考仅链接的答案,请写下解决问题的组件。如果链接出现故障,答案仍然有效。不仅
-Variable
与嵌入的
=
存在问题,而且它也不会参数化SQL命令。它将
name=value
子句中
=
后面的任何内容替换到SQL文本中,这就是为什么需要将
value
放在单引号中的原因-它们没有经过特殊处理,只是被转储到SQL中。如果参数值来自外部,则在将其传递给
Invoke SqlCmd
之前,您必须自己对其进行转义,使其成为有效且安全的SQL字符串文字,并使用单引号完成。感谢您进行挖掘并找到根本原因。这节省了我尝试重新整理代码以使其与Invoke Sqlcmd一起工作的时间,因为我知道不会有一个干净的解决方案。是否可以将变量传递到-InputFile?
$variable = "'Hello=World'"
$variables = @( "MyVariable=$($variable.replace("=","'+CHAR(61)+'"))" )

Invoke-SqlCmd -ServerInstance 'localhost' -Database 'master' -Query 'SELECT $(MyVariable) AS foo' -Variable $variables