Зачем кому-то использовать WHERE 1=1 И <conditions> в предложении SQL?
-
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
добавим, это была заметная разница.что-то связанное с тем, что заголовки таблиц возвращаются, как только выполняется первое условие, или с каким-то другим безумием, в любом случае, это ускорило процесс.