Кавычки в SQL запросах

Mols

Новичок
Вы бы лучше рассказали об этом
Автор оригинала: dimagolov
реальном опыте и реальных сложностях в решении подобных задач.
Просто в двух словах. Не ради холивара. Хочу просто знать что именно происходило и в чем именно проблема. Я тут в принципе не ради тыканья других.

Насчет не пользуешься и т.д. - пользовался. Работало. Проблем не было. Но была особенность. Практически весь СКЛ был в функциях и хранимых процедурах. Вот phprus сейчас сказал про оптимизатор... В ХП в параметрах - указывается тип. Может быть, что поэтому и проблем не было.
 

Фанат

oncle terrible
Команда форума
Дима, вот ты взъелся, а.
Ну давай я дам совет. О том, чем пользуюсь.
Кавычу все подряд. Бескавычное (фцнкции) добираю, как автор топика, руками.
проблем с проивзодительностью не замечал (что-то мне подсказвывает, что оно приводится к нужному типу при парсинге запроса)
 

dimagolov

Новичок
*****, ну ты хоть понимаешь, что это не самая лучшая практика и не доказываешь обратное 3 страницы :)

п.с. я не говорю, что тот код, которым я пользуюсь идеален, но я знаю чем именно он не идеален.

-~{}~ 12.03.10 13:32:

а про приведение к типу - нужно перечитать тему, про которую упоминали, чтобы оценить, на сколько вероятно подобное.
 

Mols

Новичок
dimagolov
Меня всегда радовали вот такие люди которые всё за всех знают.
Мой код далеко не идеален И это вообще не оспаривается.
ДА и практика не лучшая - просто вполне допустимая. Я пытаюсь от Вас получить критику - а в ответ слышу что я оказывается что-то не знаю. Но вот что я не знаю - Вы скрываете.))) Я ж Вас прошу - скажите мне!!! Если Вы знаете....
Хоть один реальный эксплейн - когда оно глючит есть? Ну просто ради интереса.
Или хоть ссылку дайте на тот топик где вы обсуждали эту мифическую проблему.
А то "от тебя нет аргументов ламер".
Ну смешно ей богу.
 

phprus

Moderator
Команда форума
Mols
эм... мне сложновато понять как может поменять логику запроса подставленный туда НУЛЛ - если этот НУЛЛ передан для того, чтобы его подставили в запрос.
Логика в том, что NULL не может подставляться на этапе экранирования данных. Корректно его можно подставить только на этапе конструирования самого запроса, так как операторы для работы с NULL отличается от операторов для работы с другими типами (для примера операторы сравнения для NULL специальные).
Проще говоря, если нам нужно найти все записи у которых поле NULL это будет один запрос, а если все записи у которых это-же поле равно, к примеру, 666, то это будет другой запрос.
 

dimagolov

Новичок
как называется полемический прием сделать спорное утверждение и возложить на оппонента задачу по его опровержения?

я знаю, что неявные преобразования типов это путь к проблемам в программировании. надеюсь, обосновывать это утверждение нет смысла. соответственно я стремлюсь избегать подобного в любых ситуациях и подготовка данных SQL запросов это частный случай этого.

если тебе интересно когда именно такое преобразование привело к проблемам, на которые указывал phprus, то поиск по форуму в твоем распоряжении. мне же уточнять когда именно можно наступить на грабли не слишком интересно, так как я не ставлю себя в ситуацию, когда на эти грабли можно наступить.
 

phprus

Moderator
Команда форума
Фанат
(что-то мне подсказвывает, что оно приводится к нужному типу при парсинге запроса)
Приводится. Но только приводить то можно либо правый операнд к левому, либо левый к правому (по типам), а оптимизатор может ошибиться и начать делать преобразование типов у значений колонки.

Ссылка на ту, как тут выразились, мифическую проблему:
http://phpclub.ru/talk/showthread.php?s=&threadid=118337
Если оптимизатор ошибся (хотя я даже не уверен, что это ошибка. Это скорее напоминание разработчикам о том, что думать надо) в том случае, то где гарантия, что он не ошибется в аналогичном?
 

Mols

Новичок
phprus
Вы что реально думаете что я не понимаю того, что простое = NULL не выведет данные? Или это шутка? Любые данные могут быть "=" ">" "<" их комбинации ну или "IS" "NOT IS". Могут быть функции ну и кучи всего Это всё не имеет отношения к самой защите данных... И теме топика. Ещё раз спасибо за упоминание проблемы с приведением типов. Попробую поискать.
dimagolov
Спасибо. Ваша позиция мне понятна.
Насчет неявных преобразований - в принципе согласен. Чем их меньше - тем лучше.
Насчет полемических приёмов не подскажу. Не силён.
З.Ы.
Жаль только что великие знания о " реальном опыте и реальных сложностях в решении подобных задач." так и остались тайной знатока полемики.
 

dimagolov

Новичок
оптимизатор может ошибиться и начать делать преобразование типов у значений колонки.
после повторного прочтения темы (спасибо за ссылку) возникло подозрение, что он всегда пытается привести к числовому типу.
что и требовалось доказать:
PHP:
mysql> select 2 = '2A';
+----------+
| 2 = '2A' |
+----------+
|        1 |
+----------+
аналогично происходит при запросе к таблице с строками '2', '2A', когда они проверяются на числовое значение. ключ, соответственно, не используется.

-~{}~ 12.03.10 14:27:

Это всё не имеет отношения к самой защите данных
мы тут вообще-то не про защиту данных говорили, а про формирование запросов.
 

Mols

Новичок
dimagolov
Мда. Ну "это уже теплее" (с).
И что в такой ситуации Ваша либа делает?
Если тип допустим ИНТ а приходит "2а"?

-~{}~ 12.03.10 20:32:

не знаю кто про что. Вот вопрос ТС
"Он нужен только для того, чтобы в SQL запросах расставлять кавычки у строковых значений, а там где численные значения - кавычки не ставим. Неужели без этого второго столбика никак не обойтись? Есть какой-то выход, а то он мне сильно жить мешает? "

-~{}~ 12.03.10 20:34:

Так что формально мы должны говорить только в рамках "Валидная строка" и "Валидное число" И важно ли что число в кавычках. НА всякий... ну логично её расширить до защиты данных. Но никак не до формирования запроса.
 

phprus

Moderator
Команда форума
Mols
Код:
postgres=# select 2+'2dd';
ERROR:  invalid input syntax for integer: "2dd"
СТРОКА 1:select 2+'2dd';
После экранирования твоим методом получили некорректный запрос в PostgreSQL.
 

dimagolov

Новичок
у меня код выбрасывает ошибку, если при ожидаемом числовом значении получаем не целое число.
PHP:
/**
* is_bigint
*
* Test if the vaule is valid for MySQL bigint field
* Return TRUE for numeric non-float values (integer or string) and NULL
* Return FALSE for empty or spaced strings, boolean values (even TRUE)
* Ignore begining or ending spaces or NL
* !!! Does not check length of the value, so overflow is possible
*
* @param mixed $Value value to test
*
* @return boolean: result of test
*
*/
function is_bigint($Value) {
	if ($Value === TRUE) return FALSE;
	if ($Value === NULL) return TRUE;
	$Value= trim($Value, " \t\n\r");
	$trimmed= trim($Value, '+-0123456789');
	return (is_numeric($Value) && empty($trimmed));
}

/**
* is_nonempty_bigint
*
* Test if the vaule pass is_bigint and non-zero or non-null
*
* @param mixed $Value value to test
*
* @return boolean: result of test
*
*/
function is_nonempty_bigint($Value) {
	return (!!$Value && intval($Value) && is_bigint($Value));
}
 

Mols

Новичок
phprus
угу. Ну опять же валидация... У Вас это тоже либа СКЛ делает?
dimagolov
100% зачет. Любой рассказ кроме броска исключения - не выход. Бросок исключения звучит очень реально. Ну что сказать... может быть мне стоит подумать... Честно говоря сейчас я просто явно привожу типы (даже после валидаторов). И отдаю в PDO. И до сего момента считал это(явное приведение) личной параноей.
В тех местах где считаю критичным - проверяю значения после приведения... и бросаю исключение в случае ошибки.
Но положить эту работу на СКЛ либу... в общем спасибо за нормальный ответ.
Может быть действительно стоит отказаться от приведения.
 

dimagolov

Новичок
я вообще стараюсь любой кусок кода, даже private ф-ии писать так, чтобы они нормально отработали или вернули ошибку на ЛЮБЫХ параметрах и при ЛЮБОМ состоянии объекта. то есть я стараюсь никогда не подразумевать, что полученные данные содержат что-то определенное, вне зависимости от их источника.
 
Сверху