简体   繁体   English

如何转义单引号或双引号的更新查询?

[英]how to escape single or double quotes for update query?

I have a query to update status field with error 我有一个查询以错误更新状态字段

$error = "g is not a valid value for this element. An error occurred while parsing the 'SynchronizeSecurity' element at line 14, column 46 ('http://schemas.microsoft.com/analysisservices/2003/engine' namespace) under Envelope/Body/Execute/Command/Synchronize/SynchronizeSecurity."

Function Query($Query) {
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection 
$SqlConnection.ConnectionString = "Server=$Server;Initial Catalog=$Database;Integrated Security=SSPI" 
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand 
$SqlCmd.Connection = $SqlConnection 
$SqlCmd.CommandText = $Query 
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter 
$SqlAdapter.SelectCommand = $SqlCmd 
$DataSet = New-Object System.Data.DataSet 
$a=$SqlAdapter.Fill($DataSet)
$SqlConnection.Close() 
$DataSet.Tables[0] }

#Updating status field
Query "UPDATE [$Table]
SET [status] = '$error'
WHERE [db_name] = '$DB' AND [server] = '$server[-1])'"

The update doesn't work. 更新不起作用。 I debugged and found out that it has to do with single quotes. 我调试并发现它与单引号有关。 If I paste the error content directly in the table, it pastes in just fine. 如果我将错误内容直接粘贴到表中,则粘贴得很好。

I made sure that its not a code issue, so I set the error text to "Hi" and "testing" and both times it update the table with those texts just fine. 我确保它不是代码问题,因此我将错误文本设置为“ Hi”和“ testing”,并且两次都使用这些文本更新表就很好了。

So now I am positive whats happening is that since the SET requires wrapping the field text in single quotes, and my error contains single quotes 'SynchronizeSecurity' , its somehow conflicting and thus not updating the table with the error message. 因此,现在我可以肯定的是,由于SET要求将字段文本用单引号引起来,并且我的错误包含单引号'SynchronizeSecurity' ,因此它在某种程度上会发生冲突,因此不会使用错误消息更新表。

How can I circumvent this? 我该如何规避? Maybe, how would a backtick work in this query? 也许,反引号在此查询中如何工作?

There are a few problems with what you've written: 您编写的内容存在一些问题:

  • you've written code that is intended to retrieve result data from the database but then you've called it and passed in an update query - separate the two; 您已经编写了用于从数据库中检索结果数据的代码,但是随后您调用了该代码并传递了一个更新查询-将两者分开; update queries should be run using ExecuteNonQuery and do not require a dataadapter 更新查询应使用ExecuteNonQuery运行,并且不需要数据适配器

  • you haven't properly parameterized your query, you've just used string concatenation/interpolation to build the query string and this is fraught with security risks and unintended consequences such as the quotes issue you see here 您尚未正确设置查询参数,只是使用字符串串联/插值来构建查询字符串,这充满了安全风险和意外后果,例如您在此处看到的引号问题

All the advice in the comments about swapping single and double quotes etc is misdirected, and is just a band aid on a gaping wound; 评论中有关交换单引号和双引号等的所有建议都被误导了,仅是在大伤口上的创可贴。 use parameters and you can insert whatever value variable contents you like. 使用参数,您可以插入任何喜欢的值变量内容。 https://bobby-tables.com has some background info on why it's important and examples for c# - very close to PS. https://bobby-tables.com上有一些背景信息,说明了为什么它很重要以及C#的示例-非常接近PS。 https://powershellstation.com/2009/09/15/executing-sql-the-right-way-in-powershell/ Has some relevant advice. https://powershellstation.com/2009/09/15/executing-sql-the-right-way-in-powershell/有一些相关建议。 I don't do powershell so I'm not going to try and wrap this up in a function (I'll probably make a lot of syntax errors - writing this on a phone without the help of an IDE) with a parameters dictionary/array argument that is populated in a loop, so I'll leave that as an exercise for the reader. 我不使用powershell,所以我不会尝试将其包装在带有参数字典/的函数中(我可能会犯很多语法错误-在没有IDE的情况下将其写在手机上)循环中填充的数组参数,因此我将其留给读者练习。 Check that 2009 blog article for the basic methodology ;) and remember this advice here that you don't need a sqladapter to run updating queries etc. You might hence want to put two functions (QuerySelect and QueryNonSelect) and put some logic in along the lines of "if sql string starts with SELECT call QuerySelect else call QueryNonSelect" so QueryNonSelect can do all your update/delete/merge/create etc 请查看2009年博客文章中的基本方法;),并在此记住此建议,您不需要sqladapter来运行更新查询等。因此,您可能需要放置两个函数(QuerySelect和QueryNonSelect),并在其中添加一些逻辑。 “如果sql字符串以SELECT开头的行,则调用QuerySelect,否则调用QueryNonSelect”,因此QueryNonSelect可以完成所有的更新/删除/合并/创建等

Your code needs to be more like: 您的代码必须更像:

$SqlConnection = New-Object System.Data.SqlClient.SqlConnection 
$SqlConnection.ConnectionString = "Server=$Server;Initial Catalog=$Database;Integrated Security=SSPI" 
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand 
$SqlCmd.Connection = $SqlConnection 
$SqlCmd.CommandText = "update a set b=@c where d=@e"
$SqlCmd.Parameters.AddWithValue("@b", $error)
$SqlCmd.Parameters.AddWithValue("@e", $dbnameorwhatever)
$SqlCmd.ExecuteNonQuery()

Final pointers: 最终提示:

  • Use @parameters in your sql string. 在您的sql字符串中使用@parameters。
  • Column and table names cannot be @parameterized (cannot say "update @tablename set @columnname = @value1" - the only valid parameter here is @value1. 不能对列和表名进行@参数化(不能说“ update @tablename set @columnname = @ value1”-这里唯一有效的参数是@ value1。
  • Populate the sqlcmd's Parameters collection. 填充sqlcmd的Parameters集合。
  • Run the query using the appropriate method - consider using a dataadapter for anything that returns rows. 使用适当的方法运行查询-考虑将dataadapter用于返回行的任何内容。 use ExecuteNonQuery for anything that makes changes 使用ExecuteNonQuery进行任何更改

    There are reasons to avoid AddWithValue ( https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/ ) but it's a useful convenience method when first setting out and also for me writing code to you on a cellphone.. consider that blog and update your coding as necessary 有理由避免使用AddWithValue( https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/ ),但这是首次使用时的一种有用的便捷方法也是我在手机上写代码给您的。.考虑该博客并根据需要更新您的编码

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

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