Вопрос:

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

sql dynamic-sql

174083 просмотра

18 ответа

3376 Репутация автора

Зачем кому-то использовать 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
Автор: Bogdan Maxim Источник Размещён: 28.10.2008 10:37

Ответы (18)


312 плюса

671792 Репутация автора

Решение

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

and <condition>

и объединить их всех вместе. С самого 1=1начала у инициала andесть что связать.

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

Автор: Greg Hewgill Размещён: 28.10.2008 10:39

24 плюса

4037 Репутация автора

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

Автор: duckworth Размещён: 28.10.2008 10:40

13 плюса

99559 Репутация автора

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

Автор: aku Размещён: 28.10.2008 10:40

32 плюса

832 Репутация автора

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

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

По сути, это избавляет вас от необходимости выполнять проверку условий, а затем добавлять строку «ГДЕ» перед ними.

Автор: Carl Размещён: 28.10.2008 10:43

108 плюса

31821 Репутация автора

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

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
Автор: Eduardo Molteni Размещён: 28.10.2008 10:53

10 плюса

635305 Репутация автора

На самом деле, я видел подобные вещи, используемые в отчетах 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, оставляя позиционный параметр на месте.

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

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

  • зовут Боб; а также
  • зарплата> 20 000 долларов

некоторые люди добавили бы первое с ГДЕ, а последующие с И, таким образом:

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
Автор: paxdiablo Размещён: 28.10.2008 12:13

-1 плюса

415 Репутация автора

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

Select * from tablename

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

Where 1=1

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

Автор: jackberry Размещён: 05.02.2009 06:44

10 плюса

0 Репутация автора

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

Автор: asd Размещён: 14.09.2009 05:38

5 плюса

472 Репутация автора

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

implode (" AND ", $clauses);

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

Автор: sanbikinoraion Размещён: 07.01.2010 04:00

4 плюса

43596 Репутация автора

Вот тесно связанный пример: использование оператора 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;
Автор: onedaywhen Размещён: 17.11.2011 09:33

0 плюса

191 Репутация автора

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

Автор: Big Al Размещён: 10.08.2012 03:50

14 плюса

443 Репутация автора

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

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

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

Автор: milso Размещён: 20.02.2013 02:37

0 плюса

6236 Репутация автора

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

Автор: Zo Has Размещён: 19.03.2014 05:43

4 плюса

82050 Репутация автора

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

Я видел, как фреймворки homespun делают такие вещи ( blush ), так как это позволяет применять ленивые методы парсинга к ключевым словам WHEREи ANDSql.

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

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

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

Автор: StuartLC Размещён: 23.12.2014 02:53

3 плюса

5558 Репутация автора

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

Автор: Yogesh Umesh Vaity Размещён: 05.04.2016 01:06

7 плюса

1071 Репутация автора

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

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
Автор: Carlos Toledo Размещён: 18.05.2016 09:57

1 плюс

71 Репутация автора

Это полезно в случае, когда вам нужно использовать динамический запрос, в котором в предложении where вы должны добавить некоторые параметры фильтра. Например, если вы включите опции 0 для статуса неактивно, 1 для активного. Исходя из опций, есть только две доступные опции (0 и 1), но если вы хотите отобразить Все записи, удобно включить в где 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);
Автор: Eliseo Jr Размещён: 16.02.2018 07:22

1 плюс

543 Репутация автора

Изучив все ответы, я решил провести такой эксперимент, как

SELECT
*
FROM MyTable

WHERE 1=1

Тогда я проверил с другими номерами

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

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

Автор: JonWay Размещён: 16.03.2018 03:05
Вопросы из категории :
32x32