【问题标题】:Escape variable in sqlcmd / Invoke-SqlCmdsqlcmd / Invoke-SqlCmd 中的转义变量
【发布时间】:2016-05-11 11:19:27
【问题描述】:

我正在使用 powershell 并使用 Invoke-SqlCmd。我能够将变量传递给 SQL:

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

Invoke-SqlCmd `
    -ServerInstance 'localhost' `
    -Database 'master' `
    -Username 'matthew' `
    -Password 'qwerty' `
    -Query 'SELECT $(MyVariable) AS foo' `
    -Variable $variables

这让我按预期返回hello。但是,如果我有一个值包含等于 (=) 的变量:

$variables = @("MyVariable='aGVsbG8NCg=='") # base64 encoded 'hello'

它给了我以下错误:

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

我找不到任何关于 sqlcmdInvoke-SqlCmd 的文档,说明我应该如何正确转义值。

如何转义发送到sqlcmd / Invoke-SqlCmd 的变量?

【问题讨论】:

  • 不仅-Variable有嵌入=的问题,它也没有参数化SQL命令。它将name=value 子句中= 之后的任何内容替换到SQL 文本中,这就是您需要将value 放在单引号中的原因——它们没有被特殊处理,它们只是被转储到SQL 中.如果参数值来自外部,您必须自己将其转义以使其成为有效且安全的 SQL 字符串文字,并用单引号完成,然后再将其传递给 Invoke-SqlCmd

标签: sql-server windows powershell sqlcmd invoke-sqlcmd


【解决方案1】:

使用CHAR(61) 代替等号。

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

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

【讨论】:

    【解决方案2】:

    我还发现自己需要传递一个 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 脚本,以确保替换正确发生。

    请务必使用您的变量独有的替换标记,这样您就不会在查询中意外地将有效文本替换为“=”。

    【讨论】:

    • 是否可以将变量传递给 -InputFile ?
    【解决方案3】:

    我最近遇到了这个问题,并成功使用了 TheMadTechnician 的答案:

    Replace Single Quotes in PowerShell Or Excel CSV

    答案是在你的字符串中创建子表达式来替换' 用''。

    Invoke-Sqlcmd -ServerInstance "$SQLServer" -Database "$SqlDB" -query "INSERT INTO dbo.ecca_sw_standard_2 (name, version, product_id) VALUES (N'$($CSVAppName -replace "'", "''")', N'$($CSVVersion -replace "'", "''")' , N'$($CSVAppID -replace "'", "''")')"

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

    【讨论】:

    • 尽管这可能会解决 OP 的问题,但为了将来仅参考链接答案,请写下解决问题的组件。如果链接断开,答案仍然存在。
    【解决方案4】:

    在调查后使用一些反思

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

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

    我对其他尝试使用 Invoke-SqlCmd 的人的建议是节省您的时间和理智,而只需使用开源替代品 Invoke-SqlCmd2

    微软,请修复。

    【讨论】:

    • 感谢马修挖掘并找到根本原因。这节省了我尝试整理代码以使其与 Invoke-Sqlcmd 一起工作的时间,因为我知道不会有一个干净的解决方案。
    猜你喜欢
    • 2013-05-15
    • 1970-01-01
    • 1970-01-01
    • 2012-09-18
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多