как избежать одинарные или двойные кавычки для обновления запроса? - PullRequest
0 голосов
/ 13 мая 2019

У меня запрос на обновление поля состояния с ошибкой

$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])'"

Обновление не работает. Я отладил и выяснил, что это связано с одинарными кавычками. Если я вставляю содержимое ошибки прямо в таблицу, она вставляется просто отлично.

Я удостоверился, что это не проблема кода, поэтому я установил текст ошибки «Привет» и «тестирование», и оба раза он обновлял таблицу с этими текстами просто отлично.

Так что теперь я уверен, что происходит потому, что SET требует заключить текст поля в одинарные кавычки, а моя ошибка содержит одинарные кавычки 'SynchronizeSecurity', что-то противоречит друг другу и, следовательно, не обновляет таблицу сообщением об ошибке.

Как я могу обойти это? Может быть, как будет работать обратный удар в этом запросе?

1 Ответ

2 голосов
/ 13 мая 2019

Есть несколько проблем с тем, что вы написали:

  • вы написали код, предназначенный для извлечения данных результатов из базы данных, но затем вы вызвали его и передали в запросе на обновление - разделите их; Запросы на обновление должны выполняться с использованием ExecuteNonQuery и не требовать адаптера данных

  • вы не правильно параметризовали свой запрос, вы просто использовали конкатенацию / интерполяцию строк для построения строки запроса, и это чревато рисками безопасности и непредвиденными последствиями, такими как проблема с кавычками, которую вы видите здесь

Весь совет в комментариях о замене одинарных и двойных кавычек и т. Д. Неверно направлен, и это всего лишь бинты на зияющей ране; используйте параметры, и вы можете вставить любое значение переменной, которое вам нравится https://bobby -tables.com содержит некоторую справочную информацию о том, почему это важно, и примеры для c # - очень близко к PS. https://powershellstation.com/2009/09/15/executing-sql-the-right-way-in-powershell/ Есть несколько важных советов. Я не делаю PowerShell, поэтому я не буду пытаться обернуть это в функцию (я, вероятно, сделаю много синтаксических ошибок - пишу это на телефоне без помощи IDE) со словарем параметров / аргумент массива, который заполняется в цикле, поэтому я оставлю это в качестве упражнения для читателя. Посмотрите в этой статье блога за 2009 г. базовую методологию;) и запомните этот совет, что вам не нужен sqladapter для выполнения запросов на обновление и т. Д. Следовательно, вы можете захотеть поместить две функции (QuerySelect и QueryNonSelect) и добавить некоторую логику вдоль строки "если строка sql начинается с вызова SELECT QuerySelect, иначе вызов QueryNonSelect", поэтому QueryNonSelect может выполнить все ваши обновления / удаление / слияние / создание и т. д.

Ваш код должен быть больше похож на:

$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()

Финальные указатели:

  • Используйте @parameters в вашей строке sql.
  • Имена столбцов и таблиц не могут быть @parameterized (нельзя сказать "update @tablename set @columnname = @ value1" - единственный допустимый параметр здесь - @ value1.
  • Заполните коллекцию параметров sqlcmd.
  • Запустите запрос, используя соответствующий метод - рассмотрите возможность использования адаптера данных для всего, что возвращает строки. используйте ExecuteNonQuery для всего, что вносит изменения

    Есть причины избегать AddWithValue (https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/), но это полезный удобный метод при первой установке, а также я пишу код для вас на мобильном телефоне ... рассмотрите этот блог и обновите кодировку при необходимости

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...