dhiraj mane Ответов: 3

Встроенный единой ошибки SQL запрос цитировать


В моем проекте мы используем встроенный запрос SQL, как показано ниже. Запрос выдает ошибку, если строковый параметр имеет значение в одной кавычке (').

var Query = "Update temp set HIBLCK14='" + _billingDetails.Qual + "',HICOND='" + 
             CondRelate + "', HIATLEG='" + _billingDetails.AttendingLegacy + "', 
             HIATT#='" + _billingDetails.AttendingPhys + "', HIATNM='" + 
             _billingDetails.AttendingPhysName + "'" +
             " where HILOCX =" + Locix ;

var status = ExecNonQuery(Query);
         
 
 
public bool ExecNonQuery(string Query)
        {
          try
            {
                using (SqlCommand cmd = new SqlCommand(Query, _conn))
                {
                    if (_conn.State != ConnectionState.Open)
                    {
                        _conn.Open();
                    }
                    cmd.ExecuteNonQuery();
                    return true;
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                _conn.Close();
            }
        }
ERROR:System.FormatException: The SQL statement text is not valid


Я знаю, что мы можем справиться с этой ошибкой, заменив одинарную кавычку(') на двойную(") для параметра. Но в моем проекте очень много запросов и параметров. Применение замены для каждого параметра отнимает у меня много времени (ослиная работа).

Пожалуйста, скажите мне, как я могу найти параметр одиночной кавычки из SQL-запроса и заменить его.Таким образом, я могу справиться с этим в функции "ExecNonQuery()" и мне не нужно будет вносить изменения для всех параметров(HILBNM.Replace ("',"")). В приведенном ниже запросе есть столбец "HILBNM", который имеет одинарное кавычковое(детское) значение

Update temp set HIBLCK14='',HICOND='', HIATLEG='', HIATT#='', HIATNM='', HIOTHLEG='MA159694',HIOTH#='',HIFST='', HIFZIP=0, HIFZP2=0, HILBNM='Boston Children's Hospita',  HILBAD='PO BOX D-3053',HILBA2='', HILBCT='BOSTON',
HIDIA11 ='',HIDIA12 ='' where HILOCX =18693585 and HISEQ=3 and HIDOS=0


Что я уже пробовал:

HILBNM.Replace(''','''')

3 Ответов

Рейтинг:
2

Mohibur Rashid

Распечатайте запрос в окне отладки или файле, скопируйте запрос, выполненный с консоли. Вы будете лучше видеть свою ошибку.

А также у вас есть много параметров, которые вы непосредственно связываете с вашим запросом, это рискованно, приведет к серьезному повреждению вашей системы. Попробуйте найти sql-инъекцию.

И наконец если бы вы посмотрели на свой собственный вопрос вы бы заметили там дополнительную цитату в ваших переменных,

HILBNM='Boston Children's Hospita'  <<-- Children's


Что это за класс DB2Helper?
Класс DB2Helper должен дать вам функцию привязки найти ее и использовать


Maciej Los

Хороший совет!

Mohibur Rashid

Спасибо!

Рейтинг:
2

Patrice T

Цитата:
Запрос выдает ошибку, если строковый параметр имеет значение в одной кавычке (').

Обычно это начальная точка SQL-инъекции.

Никогда не создавайте SQL-запрос путем объединения строк. Рано или поздно вы сделаете это с помощью пользовательских вводов, и это откроет дверь к уязвимости под названием "SQL-инъекция", она опасна для вашей базы данных и подвержена ошибкам.
Одна кавычка в имени - и ваша программа выйдет из строя. Если пользователь вводит имя, например "Брайан О'Коннер", может привести к сбою вашего приложения, это уязвимость SQL-инъекции, и сбой-это наименьшая из проблем, вредоносный пользовательский ввод, и он продвигается к командам SQL со всеми учетными данными.
SQL-инъекция - Википедия[^]
SQL-инъекция[^]
Атаки SQL-инъекций на примере[^]
PHP: SQL-инъекция - руководство пользователя[^]
Шпаргалка по предотвращению инъекций SQL - OWASP[^]
Как я могу объяснить SQL-инъекцию без технического жаргона? - Обмен Стеками Информационной Безопасности[^]


Рейтинг:
0

MadMyche

Никогда не создавайте SQL-команду, объединяя строки вместе!.
Как вы обнаружили, одинарные кавычки могут нарушить утверждение. И это счастливая версия, что ваша программа выдает ошибку. ЕСЛИ кто-то должен создать значения, входящие в него, тогда они могут "закоротить" команду, а затем начать запускать свои собственные.
Это было определено как серьезная уязвимость 20 лет назад и до сих пор является одним из 10 лучших способов взлома веб-сайтов

Способ избежать этого состоит в том, чтобы использовать Parameterized Query В исходном запросе будут введены переменные-заполнители, а затем в команду будут добавлены параметры

Самое приятное в использовании параметров-это то, что вам не нужно беспокоиться о кавычках (или других используемых идентификаторах (например, #date# в некоторых версиях Access). Вам действительно нужно быть осторожным, так как заполнители будут заменены вводом данных SQL на основе вводимых значений; поэтому, если у вас есть INT внутри текстового поля, он будет отформатирован как строка; поэтому убедитесь, что вводимые значения правильно набраны.
Обычно это выглядело бы примерно так:

SqlCommand cmd = new SqlCommand("UPDATE table SET ColumnValue = @NewValue WHERE TableID = @TableID", _connection);
cmd.Parameters.AddWithValue("@NewValue", somevalue);
cmd.Parameters.AddWithValue("@TableID", indexvalue);


Ваш случай немного отличается,так как вы передаете CommandText какому-то помощнику.
Итак, нам нужно будет построить некоторую коллекцию,значения которой могут быть <string,object> или <object, object>. Так что новый запрос будет выглядеть примерно так
var Query = "UPDATE temp SET HIBLCK14= @HIBLCK14,HICOND = @HICOND,HIATLEG = @HIATLEG,[HIATT#] = @HIATT,HIATNM = @HIATNM,HIOTHLEG = @HIOTHLEG,[HIOTH#] = @HIOTH,HIDOSF = @HIDOSF,HIDOST = @HIDOST,HIBLCK19 = @HIBLCK19,HIOCCD = @HIOCCD WHERE (HILOCX = @HILOCX) AND (HISEQ = @HISEQ) AND (HIDOS = @HIDOS);";

А затем мы добавим значения с помощью OrderedDictionary (не обязательно таким образом, может быть любой тип объекта key&value)
OrderedDictionary params = new OrderedDictionary();
params.add("@HIBLCK14", _billingDetails.Qual);
params.add("@HICOND", CondRelate);
params.add("@HIATLEG", billingDetails.AttendingLegacy);
params.add("@HIATT", _billingDetails.AttendingPhys);
params.add("@HIATNM", _billingDetails.AttendingPhysName);
params.add("@HIOTHLEG", _billingDetails.LOCATOR17A1);
params.add("@HIOTH", _billingDetails.LOCATOR17B);
params.add("@HIDOSF", _billingDetails.DOSFrom);
params.add("@HIDOST", ToDOS);
params.add("@HIBLCK19", _billingDetails.AdditionalClaimInformation);
params.add("@HIOCCD", _billingDetails.DateOfOccur);
params.add("@HILOCX", Locix);
params.add("@HISEQ", Sequence);
params.add("@HIDOS", DateOfService);
А затем идет последний бит, добавляющий новый метод, который принимает коллекцию параметров и может добавить их в команду.
public bool ExecNonQuery(string Query, OrderedDictionary QueryValues) {
	try {
		using (SqlCommand cmd = new SqlCommand(Query, _conn)) {

			// iterate through the dictionary
			foreach (DictionaryEntry entry in QueryValues) {
				cmd.Parameters.AddWithValue(entry.Key, entry.Value);
			}

			if (_conn.State != ConnectionState.Open) { _conn.Open(); }
			cmd.ExecuteNonQuery();
			return true;
		}
	}
	catch (Exception) { throw; }
	finally { _conn.Close(); }
}


ЗАПИСИ:
- Хотя это функционально, это не мой предпочтительный метод, поскольку он ограничивает функциональность параметров
- Некоторые из ваших названий столбцов содержали специальные символы. От них надо спасаться.

Я не нахожусь на машине, оснащенной IDE, поэтому могут быть синтаксические или другие ошибки. Принципал надежен, и если он не работает, то никаких возвратов нет.


dhiraj mane

Спасибо тебе, Мадмыч... это решение сработает для меня.

MadMyche

Пожалуйста