简体   繁体   English

sqlcmd / Invoke-SqlCmd 中的转义变量

[英]Escape variable in sqlcmd / Invoke-SqlCmd

I am using powershell and using Invoke-SqlCmd .我正在使用 powershell 并使用Invoke-SqlCmd I am able to pass variables to SQL:我能够将变量传递给 SQL:

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

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

This gives me back hello as expected.这让我按预期回复hello However, if I have a variable with a value containing an equals ( = ):但是,如果我有一个包含等于 ( = ) 的值的变量:

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

It gives me the following error:它给了我以下错误:

The format used to define the new variable for Invoke-Sqlcmd cmdlet is invalid.用于为Invoke-Sqlcmd cmdlet 定义新变量的格式无效。 Please use the 'var=value' format for defining a new variable.请使用“var=value”格式来定义新变量。

I could not find any documentation on either sqlcmd or Invoke-SqlCmd on how I should escape values properly.我在sqlcmdInvoke-SqlCmd上找不到任何关于如何正确转义值的文档。

How do I escape variables sent to sqlcmd / Invoke-SqlCmd ?如何转义发送到sqlcmd / Invoke-SqlCmd

After investigating using some reflection on在调查使用一些反思之后

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

Looking at ExecutionProcessor 's constructor, the following lines reveal the problem that it will fail if there are more than one equals sign in the variable definition.查看ExecutionProcessor的构造函数,以下几行揭示了如果变量定义中有多个等号它会失败的问题。

My recommendation for anyone else trying to use Invoke-SqlCmd is to save your time and sanity and just use the open source alternative Invoke-SqlCmd2 instead.我对尝试使用Invoke-SqlCmd其他人的建议是节省您的时间和理智,而只使用开源替代Invoke-SqlCmd2

Microsoft, please fix.微软,请修复。

Use CHAR(61) to replace the equal sign.使用CHAR(61)替换等号。

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

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

I also found myself needing to pass a base64 encoded piece of information which had those pesky '='s in them.我还发现自己需要传递一条 base64 编码的信息,其中包含那些讨厌的“=”。 What worked for me was adding a replacement token into the variable array that I pass to the query and then using SQL's REPLACE function in my query to replace my token with an '=' sign.对我有用的是将替换标记添加到我传递给查询的变量数组中,然后在我的查询中使用 SQL 的 REPLACE 函数用“=”符号替换我的标记。

So you can update your code to look like this:因此,您可以将代码更新为如下所示:

$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

The downside to this solution is that you need to be proactive with it's application.此解决方案的缺点是您需要主动使用它的应用程序。 You need to know ahead of time which variables might have an 'equals sign' in them and then update not only your powershell code, but also your SQL scripts to make sure that the replacement happens correctly.您需要提前知道哪些变量中可能有“等号”,然后不仅要更新您的 powershell 代码,还要更新您的 SQL 脚本,以确保替换正确进行。

Just be sure to use a replacement token that is unique to your variables so you don't accidentally replace valid text with '=' in your queries.请务必使用变量唯一的替换标记,以免在查询中意外将有效文本替换为“=”。

I encounted this issue recently and had success using the answer from TheMadTechnician at:我最近遇到了这个问题,并成功使用了 TheMadTechnician 的答案:

Replace Single Quotes in PowerShell Or Excel CSV 在 PowerShell 或 Excel CSV 中替换单引号

The answer is to create sub expressions in your string to replace ' with ''.答案是在字符串中创建子表达式以将 ' 替换为 ''。

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 "'", "''")')"

This way when the string is expanded it will be appropriately escaped for SQL insertion.这样,当字符串被扩展时,它会被适当地转义以进行 SQL 插入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM