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

StackOverflow https://stackoverflow.com/questions/242822

  •  04-07-2019
  •  | 
  •  

Вопрос

Зачем кому-то использовать WHERE 1=1 AND <conditions> в предложении SQL (либо SQL, полученный с помощью объединенных строк, либо определение представления)

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

Если есть инъекция WHERE 1 = 1 AND injected OR 1=1 имел бы тот же результат, что и injected OR 1=1.

Последующее редактирование:Как насчет использования в определении представления?


Спасибо вам за ваши ответы.

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

Возьмем это, к примеру:

CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 AND table.Field=Value
Это было полезно?

Решение

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

and <condition>

и объедините их все вместе.С помощью 1=1 в начале, начальный and есть с чем ассоциироваться.

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

Другие советы

Просто добавляю пример кода к ответу Грега:

dim sqlstmt as new StringBuilder
sqlstmt.add("SELECT * FROM Products")
sqlstmt.add(" WHERE 1=1") 

''// From now on you don't have to worry if you must 
''// append AND or WHERE because you know the WHERE is there
If ProductCategoryID <> 0 then
  sqlstmt.AppendFormat(" AND ProductCategoryID = {0}", trim(ProductCategoryID))
end if
If MinimunPrice > 0 then
  sqlstmt.AppendFormat(" AND Price >= {0}", trim(MinimunPrice))
end if

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

Вы можете объединить условия, используя строку " И ".Затем, вместо подсчета количества передаваемых вами условий, вы помещаете "WHERE 1 = 1" в конец вашей стандартной инструкции SQL и добавляете объединенные условия.

По сути, это избавляет вас от необходимости выполнять проверку условий, а затем добавлять перед ними строку "WHERE".

Кажется ленивым способом всегда знать, что ваше предложение WHERE уже определено, и позволяет вам продолжать добавлять условия без необходимости проверять, является ли оно первым.

Косвенно Относящийся К делу:когда используется 1=2:

CREATE TABLE New_table_name 
as 
select * 
FROM Old_table_name 
WHERE 1 = 2;

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

Выражение 1 = 1 обычно используется в сгенерированном коде sql.Это выражение может упростить генерирующий sql код, уменьшая количество условных операторов.

где 1=0, это делается для проверки, существует ли таблица.Не знаю, почему используется 1= 1.

На самом деле, я видел, как подобные вещи использовались в отчетах BIRT.Запрос, переданный в среду выполнения BIRT , имеет вид:

select a,b,c from t where a = ?

и '?' заменяется во время выполнения фактическим значением параметра, выбранным из выпадающего списка.Варианты выбора в раскрывающемся списке задаются:

select distinct a from t
union all
select '*' from sysibm.sysdummy1

так что вы получите все возможные значения плюс "*".Если пользователь выбирает "*" из выпадающего списка (что означает, что должны быть выбраны все значения a) запрос должен быть изменен (с помощью Javascript) перед запуском.

Поскольку "?" является позиционным параметром и ДОЛЖЕН оставаться там для работы других функций, Javascript изменяет запрос так, чтобы он был:

select a,b,c from t where ((a = ?) or (1==1))

Это в основном устраняет эффект предложения where, все еще оставляя позиционный параметр на месте.

Я также видел регистр И, используемый ленивыми программистами при динамическом создании SQL-запроса.

Допустим, вам нужно динамически создать запрос, который начинается со select * from t и проверяет:

  • меня зовут Боб;и
  • зарплата составляет > 20 000 долларов

некоторые люди добавили бы первое с помощью WHERE , а последующие - с помощью AND, таким образом:

select * from t where name = 'Bob' and salary > 20000

Ленивые программисты (и это не обязательно плохой черта) не проводил бы различия между добавленными условиями, они начинались бы с select * from t where 1=1 и просто добавьте предложения AND после этого.

select * from t where 1=1 and name = 'Bob' and salary > 20000

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

CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 
AND Table.Field=Value
AND Table.IsValid=true

превращается в:

CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 
--AND Table.Field=Value
--AND Table.IsValid=true

Хотя я вижу, что 1 = 1 было бы полезно для сгенерированного SQL, метод, который я использую в PHP, заключается в создании массива предложений, а затем выполнении

implode (" AND ", $clauses);

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

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

MERGE INTO Circles
   USING 
      (
        SELECT pi
         FROM Constants
      ) AS SourceTable
   ON 1 = 1
WHEN MATCHED THEN 
  UPDATE
     SET circumference = 2 * SourceTable.pi * radius;

Зачем кому-то использовать WHERE 1= 1 И <proper conditions>

У меня есть увиденный домотканые фреймворки делают подобные вещи (покраснеть), поскольку это позволяет применять методы ленивого синтаксического анализа как к WHERE и AND Ключевые слова Sql.

Например (здесь я использую C # в качестве примера), рассмотрим условный синтаксический анализ следующих предикатов в Sql-запросе string builder:

var sqlQuery = "SELECT * FROM FOOS WHERE 1 = 1"
if (shouldFilterForBars)
{
    sqlQuery = sqlQuery + " AND Bars > 3";
}
if (shouldFilterForBaz)
{
    sqlQuery = sqlQuery + " AND Baz < 12";
}

"Выгода" от WHERE 1 = 1 означает, что никакого специального кода не требуется:

  • Для И - следует ли применять ноль, один или оба предиката (Bars и Baz), что определило бы, следует ли применять первый AND требуется.Поскольку у нас уже есть по крайней мере один предикат с 1 = 1, это означает AND всегда в порядке.
  • При полном отсутствии предикатов - В случае, когда предикатов НОЛЬ, тогда WHERE должно быть отброшено.Но опять же, мы можем быть ленивы, потому что мы снова являемся гарантией по крайней мере одного предиката.

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

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

Это полезно в случае, когда вам приходится использовать динамический запрос, в котором в предложении where вы должны добавить некоторые параметры фильтра.Например, если вы включите параметры 0 для статуса неактивен, 1 для активен.Исходя из параметров, доступно только два параметра (0 и 1), но если вы хотите отобразить все записи, удобно включить в where close 1=1.Смотрите приведенный ниже пример:

Declare @SearchValue    varchar(8) 
Declare @SQLQuery varchar(max) = '
Select [FirstName]
    ,[LastName]
    ,[MiddleName]
    ,[BirthDate]
,Case
    when [Status] = 0 then ''Inactive''
    when [Status] = 1 then ''Active''
end as [Status]'

Declare @SearchOption nvarchar(100)
If (@SearchValue = 'Active')
Begin
    Set @SearchOption = ' Where a.[Status] = 1'
End

If (@SearchValue = 'Inactive')
Begin
    Set @SearchOption = ' Where a.[Status] = 0'
End

If (@SearchValue = 'All')
Begin
    Set @SearchOption = ' Where 1=1'
End

Set @SQLQuery = @SQLQuery + @SearchOption

Exec(@SQLQuery);

Просмотрев все ответы, я решил провести какой-нибудь эксперимент, например

SELECT
*
FROM MyTable

WHERE 1=1

Затем я сверился с другими номерами

WHERE 2=2
WHERE 10=10
WHERE 99=99

ect После выполнения всех проверок запрос run town остается тем же самым.даже без предложения where .Я не поклонник синтаксиса

Используя предикат , подобный 1=1 это обычная подсказка, иногда используемая для того, чтобы заставить план доступа использовать или не использовать индексное сканирование.Причина, по которой это используется, заключается в том, что вы используете многозадачный объединенный запрос со многими предикатами в предложении where, где иногда даже использование всех индексов приводит к тому, что план доступа считывает каждую таблицу - полное сканирование таблицы.Это всего лишь 1 из многих подсказок, используемых администраторами баз данных, чтобы заставить СУБД использовать более эффективный путь.Только не бросай один в;вам нужен администратор базы данных для анализа запроса, поскольку это не всегда работает.

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

Что - то вроде

select column1, column2 from my table where 1=1 {name} {age};

Затем мы бы построили предложение where следующим образом и передали его в качестве значения параметра

string name_whereClause= ddlName.SelectedIndex > 0 ? "AND name ='"+ ddlName.SelectedValue+ "'" : "";

Поскольку выбор предложения where неизвестен нам во время выполнения, это очень помогает нам в определении того, следует ли включать 'AND' or 'WHERE'.

Впервые я столкнулся с этим в ADO и classic asp, ответ, который я получил, был: Производительность. если вы сделаете прямой

Select * from tablename

и передайте это в виде sql-команды / текста, вы получите заметное увеличение производительности с

Where 1=1

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top