зачем использовать оператор WHERE 1=0 в SQL?
Я видел запрос, выполняемый в файле журнала приложения. и в нем содержался такой вопрос:
SELECT ID FROM CUST_ATTR49 WHERE 1=0
какая польза от такого запроса, который обязан ничего возвращать?
8 ответов
такой запрос можно использовать для пинга базы данных. Статья:
WHERE 1=0
обеспечивает что non данные посланы назад, поэтому никакая обязанность К. П. У., никакой сетевой трафик или другое потребление ресурса.
подобный запрос можно проверить на:
- доступность сервера
- существование таблицы CUST_ATTR49
- существование столбца ID
- сохранение связи
- вызвать триггер без изменения строки
- управление многими условиями OR в динамических запросах (e.g
WHERE 1=0 OR <condition>
)
a usecase я могу думать о: у вас есть форма фильтра, где вы не хотите иметь никаких результатов поиска. Если вы укажете какой-либо фильтр, они будут добавлены в предложение where.
или он обычно используется, если вам нужно создать sql-запрос вручную. Е. Г. вы не хотите проверить, является ли предложение where является пустым или нет..и вы можете просто добавить такие вещи:
where := "WHERE 0=1"
if X then where := where + " OR ... "
if Y then where := where + " OR ... "
(Если вы соединяете предложения С или вам нужно 0=1, Если у вас есть и у вас есть 1=1)
Это также может использоваться для извлечения схемы таблицы из таблицы без извлечения каких-либо данных внутри этой таблицы. Как сказал Андреа Коллеони, это будут другие преимущества использования этого.
цитата из Грега
Если список условий не известен во время компиляции, а построенный во время выполнения, вам не нужно беспокоиться о том, есть ли у вас один или несколько условий. Вы можете генерировать их все, как:
и
и объединить их все вместе. При 1=1 в начале начальный и имеет с чем-то ассоциироваться.
Я никогда не видел, чтобы это использовалось для каких-либо инъекций защита, как вы скажи, что это вряд ли поможет. Я видел, как его использовали как удобство реализации. Механизм запросов SQL в конечном итоге игнорирует 1=1, поэтому он не должен влиять на производительность.
некоторые системы используют скрипты и могут динамически устанавливать выбранные записи, которые будут скрыты из полного списка; поэтому ложное условие должно быть передано SQL. Например, три записи из 500 могут быть отмечены как конфиденциальность по медицинским причинам и не должны быть видны всем. Динамический запрос будет контролировать 500 записей, видимых тем, кто в HR, в то время как 497 видны менеджерам. Значение будет передано условно заданному предложению SQL, т. е. "где 1=1" или " где 1=0 ", в зависимости от того, кто вошел в систему.
Если пользователь намерен только добавлять записи, то самый быстрый метод-открыть набор записей без возврата существующих записей.
в качестве ответа-но и в качестве дальнейшего разъяснения того, что @AndreaColleoni уже упоминал:
управление многими условиями OR в динамических запросах (e.g
WHERE 1=0 OR <condition>
)
цель как включено-выключено переключатель
Я использую это как оператор switch (on/off) для частей моего запроса.
если бы я использовал
WHERE (0=? OR first_name = ?) AND (0=? OR last_name = ?)
тогда я могу использовать первую переменную bind (?
) для включения или выключения first_name
поиск критерий. , и третья переменная bind (?
) для включения или выключения last_name
Критериум.
только для этих двух критериев, это не кажется, что полезно, как один может вещь, это просто проще сделать то же самое, динамически строя ваше где условие либо положить только first_name
или last_name
, или оба, или никто. Таким образом, ваш код должен будет динамически создавать 4 версии одного и того же запроса. Представьте, что произойдет, если у вас есть 10 различных критериев для рассмотрения, то сколько комбинации одного и того же запроса вам придется управлять тогда?
Оптимизация Времени Компиляции
Я также могу добавить, что добавление в 0=? как переключатель переменной привязки не будет работать очень хорошо, если все ваши критерии индексируются. Оптимизатор времени выполнения, который будет выбирать соответствующие индексы и планы выполнения, может просто не видеть выгоды от использования индекса в этих немного более сложных предикатах. Поэтому я обычно советую, чтобы ввести 0 / 1 явно в ваш запрос (строка, объединяющая ее в вашем sql или выполняющая поиск/замену). Это даст компилятору возможность оптимизировать избыточные операторы и даст исполнителю среды выполнения гораздо более простой запрос для просмотра.
(0=1 OR cond = ?) --> (cond = ?)
(0=0 OR cond = ?) --> Always True (ignore predicate)
во втором заявлении выше компилятор знает, что он никогда не должен даже рассматривать вторую часть условия (cond = ?
), и он просто удалит весь предикат. Если бы это была переменная bind, компилятор никогда не смог бы выполнить этот.
потому что вы просто и насильственно вводите 0/1, есть нулевой шанс SQL-инъекций.
в моем SQL, как один подход, я обычно размещаю свои точки SQL-инъекции как ${literal_name}, а затем просто ищу/заменяю с помощью регулярного выражения любой ${...} вхождение с соответствующим литералом, прежде чем я даже позволю компилятору нанести на него удар. Это в основном приводит к запросу, хранящемуся следующим образом:
WHERE 1=1
AND (0=${cond1_enabled} OR cond1 = ?)
AND (0=${cond2_enabled} OR cond2 = ?)
выглядит хорошо, легко понять, компилятор хорошо справляется с этим, и оптимизатор на основе стоимости выполнения понимает это лучше и будет иметь большую вероятность выбора правильного индекса.
Я проявляю особую осторожность в том, что я впрыскиваю. Основным способом передачи переменных является и остается привязка переменных по всем очевидным причинам.
похоже, что кто-то пытается взломать вашу базу данных. Похоже, кто-то попробовал инъекцию mysql. Подробнее об этом можно прочитать здесь:Инъекция В MySQL