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

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

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

Если есть инъекция 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

Ответ 1

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

and <condition>

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

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

Ответ 2

Просто добавьте пример кода в ответ Грега:

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

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

Собственно, я видел такие вещи, которые использовались в отчетах 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, и проверит:

  • имя Боб; и
  • зарплатa > $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

Ответ 7

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

Ответ 8

Косвенно релевантно: при использовании 1 = 2:

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

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

Ответ 9

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

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

Ответ 10

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

implode (" AND ", $clauses);

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

Ответ 11

Здесь приведен пример, близкий к этому: использование оператора 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;

Ответ 12

Почему кто-то использует WHERE 1 = 1 AND <proper conditions>

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

Например (я использую С# в качестве примера здесь), рассмотрим условный синтаксический анализ следующих предикатов в запросе 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 означает, что никакого специального кода не требуется:

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

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

Ответ 13

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

Ответ 14

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

Select * from tablename

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

Where 1=1

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

Ответ 15

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

Ответ 16

Я делаю это обычно, когда я создаю динамический 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'.

Ответ 17

Это полезно в случае, когда вам нужно использовать динамический запрос, в котором вы должны добавить некоторые параметры фильтра. Например, если вы включили опции 0 для статуса неактивно, 1 для активного. Исходя из параметров, доступно только два доступных варианта (0 и 1), но если вы хотите отобразить все записи, удобно включить туда, где близко 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);

Ответ 18

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

SELECT
*
FROM MyTable

WHERE 1=1

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

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

ЭСТ Проведя все проверки, поселение запросов будет таким же. даже без предложения where. Я не поклонник синтаксиса