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

Single

пилот капсулы
Mols
SELECT now( ) и SELECT 'now( ) ' - разница есть?
у топик автора результат всегда будет как во втором варианте, это ему нужно исправлять формируя запросы по человечески.

а твои посты про что то там pdo и бла бла бла прости не читал.
 

Фанат

oncle terrible
Команда форума
latmap, ну, Single более-менее ответил, я только добавлю:
во-первых, не только перед кавычками надо ставить слеш
во-вторых - и с чего, собственно, разговор зашел - для чисел, ЕСЛИ ты не ставишь вокруг них кавычки, это бессмысленно.

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

latmap

Новичок
Автор оригинала: Single
и да, если уж у тебя есть некое подобие sql конструктора в виде твоего массива почему бы в него не добавить еще один элемент для where блока с указанием типа условия отличного от AND?
Ну так это же будет четвертый, а то и пятый столбец входного массив. Хотелось бы сократить до двух, наоборот.
 

Mols

Новичок
Single
Ну конечно есть разница.
Но не надо котлеты смешивать с мухами.
now( ) - это не параметр(не данные).
Кроме того - это частный случай функции (то есть функция без параметров).
А я когда говорил о подготовке - имел в виду именно данные. То есть на мой взгляд ВСЕ данные вполне можно защищать двумя шагами
1. эскейп
2. кавычки
+ обработка NULL.
Эти данные должны обрабатываться одним механизмом для вставки в запрос вне зависимости от того куда они вставляются, в функцию(как параметр) или нет.
Вы же просто забываете о чем идет речь. Речь не идет о написании полнофункционального билдера запросов. Речь идет о обработке данных.
БЕзусловно ТС столкнется с массой вопросов, когда надо будет использовать неравенства, конструкции типа IN(), функция в условии и прочее прочее.
Но это не отменяет того, что практически всегда и везде достаточно "эскейп + кавычки" именно для данных.
 

latmap

Новичок
Single
Я уже заранее знаю реплику на свой ответ, но все же скажу его.

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

Фанат

oncle terrible
Команда форума
Твоя конструкция не максимально простая. А максимально кривая.
Читать этот ужас, и высчитывать по кавычечкам, какое поле идет в фиелд лист а какое во вхере - сам же будешь материться, читая свой код через пару месяцев. Важна не "простота", а чи-та-бель-ность и однозначность кода.
У тебя недоконструктор запросов, и очень нежизнеспособный.
менять ты все равно будешь. Так что расслабься. Лучше синтаксисом займись, который ты почему-то упорно игнорируешь
 

dimagolov

Новичок
Довольно распространённая практика - ескейпить все и всё закрывать кавычками.
Это ничему не мешает.
Mols, так уж и ничему:
PHP:
mysql> select 2 + '2';
+---------+
| 2 + '2' |
+---------+
|       4 |
+---------+

mysql> select 2 + '2two';
+-------------+
| 2 + '2two2' |
+-------------+
|           4 |
+-------------+

mysql> select 2 + 'two';
+-----------+
| 2 + 'two' |
+-----------+
|         2 |
+-----------+
MySQL преобразовывает типы и ошибок не дает даже если в данных совершенный мусор. Вопрос в том, какой смысл эскейпить мусор и выполнять запросы с мусором, выводить пользователю мусорный результат, вместо того, чтобы обработать ошибку входящих данных.
 

Mols

Новичок
dimagolov
С каких пор библиотеки для работы с БД проверяют валидность данных? Я конечно понимаю, что это может быть кому-то удобно, кому то нет. Но ИМХО валидация это не задача библиотеки для работы с БД.
Кроме того если сделать в ПХП
PHP:
2 + intval('2two')
Не трудно понять, что получит те же результаты.

Ну и всё аналогичные вычисления с приведением указанных строк к числу - результат будет такой же.
То есть скажем мы библиотеке "приведи строку '2two2' в число и выполни + 2" - получим на выходе туже 4.
Просто в мускл пойдут запросы
PHP:
select 2 + 2;
select 2 + 2;
select 2 + 0;
Соответственно тому, что Вы написали. Результат будет тот же.
Просто преобразование произойдет средствами МуСКЛ.

Хотя я считаю, что такие данные вообще не должны доходить до библиотеки. Их надо валидировать до вызова подобных библиотек.
 

dimagolov

Новичок
intval это тоже костыль, аналогично преобразовывающий мусор к числу, причем вылазящий боком на 32-х битных платформах при работе с BIGINT типом MySQL
Хотя я считаю, что такие данные вообще не должны доходить до библиотеки. Их надо валидировать до вызова подобных библиотек.
Уже теплее. Хотя непонятна логика, почему нужно отказываться от возможной валидации данных для построения запросов, если данные о типах полей известны.
 

Mols

Новичок
1. Конструкция очень простая.
PHP:
return  is_null($var) ? 'NULL' : "'".mysql_real_escape_string($var)."'";
Чем проще код - тем лучше. И исключается возможность формирования любых иньекций.
2. Нет необходимости каждый раз отправлять в библиотеку тип данных.
3. Нет необходимости обрабатывать в библиотеке типы данных. Вот например смотри выше высказывание Single - о now( ). У человека прямо напрашивается какая-то константа навроде 'NOT_ESCAPE' или что-то в этом духе. В общем если ты будешь 100% знать, что ВСЕ значения которые ты передал в свою библиотеку ОБЯЗАТЕЛЬНО пройдут через обработку п.1 - таких соблазнов не будет. И волей не волей будешь делать безопасный код.
4. Каким образом вы предлагаете например обрабатывать валидацию? intval и 32 разряда - бог с ним. Хотите пользуйте для приведени флоатвал - хотите регуляку или ещё что нибудь. Это проблема высосанная из пальца. Но вот если Вы уж решили контролировать типы, то наверное надо проверять и длины строк, и наличие запрещённых символов и т.п.? Вы себе представляете "удобство" от такой библиотеки? И неплохо бы оповещать пользователя если он ввел не корректные данные? Что-то мне подсказывает, что это совершенно другие библиотеки должны делать. Ну про данные которые программист сам получает например из БД тут уж извините. Если руки настолько кривые, что он не знает, что шлет в запрос... ну мне нечего сказать.

З.Ы.
Есть только одно, о чем надо помнить. Если после подобного ескейпа будет вызвана процедура, которая на базе параметра формирует запрос динамически - то там надо быть очень внимательным.
В общем я за принцип "делать не много, но максимально надёжно"
А не ваять гипер универсальные штуки для того, чтобы муху поймать.
 

Фанат

oncle terrible
Команда форума
Mols
Не нужно спорить, отстаивая <i>единственно верное </i>решение.
Решений может быть много. У тебя более простое, у Димы - более кошерное. Кому какое использовать - каждый решит себе сам. Не надо устраивать холивар на стописят тыщ комментов, когда правы оба.
 

Mols

Новичок
Имеются в виду хранимые процедуры МуСКЛя

-~{}~ 12.03.10 16:01:

Ф анат
Меня просто несколько возмущает безапелляционность dimagolov
Да и не спорю я. Отстаиваю свою точку зрения. Просто стараюсь это делать аргументированно.
З.Ы.
Если кого достал сорри. Тема действительно мальца раздулась.
 

dimagolov

Новичок
intval и 32 разряда - бог с ним. Хотите пользуйте для приведени флоатвал - хотите регуляку или ещё что нибудь. Это проблема высосанная из пальца.
когда у тебе понадобиться занести в БД BIGINT значение, большее PHP_INT_MAX, ты поймешь, что это совсем не из пальца, а вполне реальная проблема. особенно с учетом того, что ошибка появиться "сама по себе" когда значение поля превысит PHP_INT_MAX и будет весьма своеобразно проявляться, так как intval(value > PHP_INT_MAX) = PHP_INT_MAX, что вызовет непредсказуемое поведение, которое, тем не менее, не даст явных ошибок ни на уровне PHP ни на уровне MySQL и которую заметить можно будет только много позже, когда значительное кол-во данных уже будет утеряно.
 

phprus

Moderator
Команда форума
Mols
1. Конструкция очень простая.

return is_null($var) ? 'NULL' : "'".mysql_real_escape_string($var)."'";

Чем проще код - тем лучше. И исключается возможность формирования любых иньекций.
Каждое сложная задача имеет простое, очевидное и эффектное неправильное решение.
Почему не правильное? Потому, что сравнивать c NULL/не NULL при помощи операторов сравнения не получится. Для этого есть специальные конструкции IS NULL и IS NOT NULL. А приведенный код это не учитывает и скорее всего используется вместе с обычными операторами сравнения.
 

Mols

Новичок
dimagolov
Я не постил готовый код. Все это набиралось на коленке в браузере. Естественно при работе с бигинтом надо понимать что ты работаешь с бигинтом. Вас это удивляет? Меня нет. Кроме того. Я как раз и говорю о том, что НЕ обязательно приводить типы. Достаточно защитить данные.
phprus
Конструктив запроса и защита данных - разные вещи. Я же писал уже.
Где Вы вообще видите сравнение в моем коде или примерах?
Тоже самое, что если нужен будет BETWEEN одним значением не отделаешься. Надо 2. Но ОБА эти значения надо обработать. А потом подставить в запрос. Это отдельная песня.

-~{}~ 12.03.10 18:16:

Все это ИМХО... на всякий случай)))
А то точно холивар какой-то получается.
Без обид на каких-либо реальных аргументов против - я пока не увидел.
 

dimagolov

Новичок
Я не постил готовый код. Все это набиралось на коленке в браузере.
Mols, в этом и проблема. ты постишь первое что пришло тебе в голову, вместо того, чтобы скопировать свой РЕАЛЬНЫЙ код, который работает и хоть сколько-нибудь продуман и адекватен реальности. потом с пеной у рта начинаешь возражать на замечания, которые основаны на реальном опыте и реальных сложностях в решении подобных задач.
 

phprus

Moderator
Команда форума
Mols
Конструктив запроса и защита данных - разные вещи. Я же писал уже.
Где Вы вообще видите сравнение в моем коде или примерах?
Экранирование ни при каких условиях не должно менять логику ЛЮБОГО запроса. Бездумное возвращение NULL может поменять логику запроса. По этому оно недопустимо.

Кроме того, я считаю, бездумное экранирование (приведение всего к строке) - это удар по производительности. Если сравнивать колонки числового типа с числами в кавычках, то даже самый лучший оптимизатор может ошибиться и начать приводить не строку в кавычках к числу один раз, а каждую ROW таблицы из числа в строку и сравнивать со строковой константой из запроса. (Недавно на этом форуме как раз такой случай обсуждали)
 

Mols

Новичок
dimagolov
Я в реальности уже так не делаю. Я же писал, что отдал это всё на откуп PDO. А пример с интом привел только для того, чтобы показать несостоятельность Ваших аргуметов вида
PHP:
mysql> select 2 + 'two';
Примеров Вашего РЕАЛЬНОГО кода и пока тоже не увидел. Как и ни одного приличного аргумента.

phprus
эм... мне сложновато понять как может поменять логику запроса подставленный туда НУЛЛ - если этот НУЛЛ передан для того, чтобы его подставили в запрос.

На счет "это удар по производительности" - не знаю. Может быть. Если обсуждали и было - это первый реальный аргумент. И кстати хороший.
 

dimagolov

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