почему вы используете WHERE 1 = 0 оператор в SQL? - PullRequest
30 голосов
/ 04 февраля 2012

Я видел запрос, запущенный в файле журнала приложения. и он содержал запрос как:

SELECT ID FROM CUST_ATTR49 WHERE 1=0

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

Ответы [ 11 ]

59 голосов
/ 04 февраля 2012

Такой запрос можно использовать для проверки связи с базой данных. Пункт:

WHERE 1=0

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

Такой запрос может проверить:

  • доступность сервера
  • CUST_ATTR49 существование таблицы
  • Наличие столбца идентификатора
  • Поддержание соединения живым
  • Вызвать срабатывание триггера без изменения каких-либо рядов
  • управлять многими условиями ИЛИ в динамических запросах (например, WHERE 1=0 OR <condition>)
12 голосов
/ 04 февраля 2012

Вариант использования, который я могу себе представить: у вас есть форма фильтра, в которой вы не хотите получать результаты поиска. Если вы укажете какой-либо фильтр, он будет добавлен в предложение where.

Или обычно используется, если вам нужно создать SQL-запрос вручную. Например. Вы не хотите проверять, является ли предложение where пустым или нет .. и вы можете просто добавить что-то вроде этого:

where := "WHERE 0=1"

if X then where := where + " OR ... "
if Y then where := where + " OR ... "

(если вы соединяете пункты с ИЛИ, вам нужно 0 = 1, если у вас есть И у вас есть 1 = 1)

9 голосов
/ 09 августа 2012

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

2 голосов
/ 10 декабря 2018

Это очень хорошо при извлечении метаданных и делает его универсальным.У многих БД есть оптимизатор, поэтому они не будут его выполнять, но он все еще является допустимым оператором SQL и должен выполняться на всех БД.Это не приведет к получению какого-либо результата, но вы знаете, что имена столбцов действительны, типы данных и т. Д. Если он не выполняется, вы знаете, что с БД что-то не так (не работает и т. Д.). Многие универсальные программы выполняют этот фиктивный оператор для тестирования и выборки метаданных.

2 голосов
/ 20 августа 2018

В качестве ответа - но также и в качестве дополнительного пояснения к тому, что @AndreaColleoni уже упомянул:

управлять многими условиями ИЛИ в динамических запросах (например, WHERE 1=0 OR <condition>)

Предназначен для включения / выключения

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

Если бы я использовал

WHERE 1=1
  AND (0=? OR first_name = ?) 
  AND (0=? OR last_name = ?)

Затем я могу использовать первую переменную связывания (?), чтобы включить или выключить критерий поиска first_name. и третья переменная связывания (?) для включения или выключения критерия last_name.

Я также добавил литерал 1=1 только для эстетики, чтобы текст запроса хорошо выровнялся.

Только для этих двух критериев это не кажется полезным, так как, возможно, проще сделать то же самое, динамически создавая условие WHERE, указав только first_name или last_name, или оба, или никто. Таким образом, ваш код должен будет динамически создавать 4 версии одного и того же запроса. Представьте себе, что произойдет, если у вас будет 10 различных критериев, а затем сколько комбинаций одного и того же запроса вам придется обрабатывать?

Оптимизация времени компиляции

Я также мог бы добавить, что добавление в 0 =? так как переменная связывания не будет работать очень хорошо, если все ваши критерии проиндексированы. Оптимизатор времени выполнения, который выберет соответствующие индексы и планы выполнения, может просто не увидеть экономическую выгоду от использования индекса в этих немного более сложных предикатах. Поэтому я обычно советую явно вставлять 0/1 в ваш запрос (объединить строку в вашем sql или выполнить поиск / замену). Это даст компилятору возможность оптимизировать избыточные операторы и даст исполнителю времени выполнения гораздо более простой запрос для рассмотрения.

(0=1 OR cond = ?) --> (cond = ?)
(0=0 OR cond = ?) --> Always True (ignore predicate)

Во втором приведенном выше утверждении компилятор знает, что ему никогда не придется даже учитывать вторую часть условия (cond = ?), и он просто удалит весь предикат. Если бы это была переменная связывания, компилятор никогда бы этого не достиг.

Поскольку вы просто и принудительно вводите 0/1, вероятность внедрения SQL-кода равна нулю.

В моем SQL, в качестве одного из подходов, я обычно помещаю свои точки внедрения sql как $ {literal_name}, а затем просто выполняю поиск / замену с помощью регулярного выражения любого вхождения $ {...} с соответствующим литералом, прежде чем я даже пусть у компилятора есть на это удар. Это в основном приводит к тому, что запрос хранится следующим образом:

WHERE 1=1
  AND (0=${cond1_enabled} OR cond1 = ?)
  AND (0=${cond2_enabled} OR cond2 = ?)

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

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

2 голосов
/ 04 марта 2017

Некоторые системы используют скрипты и могут динамически устанавливать выбранные записи, которые будут скрыты из полного списка;поэтому ложное условие должно быть передано в SQL.Например, три записи из 500 могут быть помечены как конфиденциальные по медицинским причинам и должны быть доступны не всем.Динамический запрос будет контролировать 500 записей, видимых для тех, кто в HR, а 497 - для менеджеров.Значение будет передано условному выражению SQL, которое установлено условно, т.е. «WHERE 1 = 1» или «WHERE 1 = 0», в зависимости от того, кто вошел в систему.

2 голосов
/ 04 февраля 2012

цитируется Грегом

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

и

и объедините их все вместе. С 1 = 1 в начале, начальный и есть с чем связать.

Я никогда не видел, чтобы это использовалось для какой-либо защиты от инъекций, как вы скажем, не похоже, что это сильно поможет. Я видел, что это использовалось как удобство реализации. Механизм SQL-запросов в конечном итоге игнорирует 1 = 1, поэтому он не должен влиять на производительность.

Зачем кому-то использовать WHERE 1 = 1 И в предложении SQL?

1 голос
/ 13 ноября 2018

Per пользователь milso в другом потоке , другое назначение для "WHERE 1 = 0":

CREATE TABLE New_table_name как выбрать * FROM Old_table_name WHERE 1 = 2;

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

1 голос
/ 26 октября 2018

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

Вставка фрагмента кода здесь

String query = "SELECT * from <Table_name> where 1=0";
PreparedStatement stmt = connection.prepareStatement(query);
ResultSet rs = stmt.executeQuery();
ResultSetMetaData rsMD  = rs.getMetaData();
int columnCount = rsMD.getColumnCount();
for(int i=0;i<columnCount;i++) {
    System.out.println("Column display size is: " + rsMD.getColumnDisplaySize(i+1));
}

Здесь запрос типа «выбрать * из таблицы» может вызвать проблемы с производительностью, если вы работаете с большими данными, потому что он попытается извлечь все записи из таблицы. Вместо этого, если вы предоставите запрос типа «выбрать * из таблицы , где 1 = 0 », тогда он будет выбирать только метаданные таблицы, а не записи, поэтому он будет эффективен.

1 голос
/ 11 мая 2017

Если пользователь намеревается добавлять только записи, самый быстрый способ - открыть набор записей без возврата каких-либо существующих записей.

...