Dlaczego ktoś miałby używać WHERE 1=1 i w klauzuli SQL?

Dlaczego ktoś miałby używać WHERE 1=1 AND <conditions> w klauzuli SQL (albo SQL uzyskany przez skonkatenowane łańcuchy, albo definicja widoku)

Widziałem gdzieś, że będzie to używane do ochrony przed SQL Injection, ale wydaje się to bardzo dziwne.

W przypadku zastrzyku WHERE 1 = 1 AND injected OR 1=1 wynik byłby taki sam jak injected OR 1=1.

Późniejsza edycja: co z użyciem definicji widoku?


Dziękuję za odpowiedzi.

Still, Nie rozumiem dlaczego ktoś używa tej konstrukcji do definiowania widoku lub używa jej wewnątrz procedury składowanej.

Weźmy na przykład:

CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 AND table.Field=Value
Author: Sampson, 2008-10-28

20 answers

Jeśli lista warunków nie jest znana w czasie kompilacji, a zamiast tego jest budowana w czasie wykonywania, nie musisz się martwić o to, czy masz jeden, czy więcej niż jeden warunek. Możesz wygenerować je wszystkie w następujący sposób:

and <condition>

I połączyć je wszystkie razem. Z 1=1 na początku, początkowy and ma z czym się kojarzyć.

Nigdy nie widziałem, aby to było używane do jakiegokolwiek rodzaju ochrony iniekcji, ponieważ mówisz, że nie wydaje się, aby to pomogło. Ihave seen it used jako wygoda wdrożenia. Silnik zapytań SQL będzie ignorował 1=1, więc nie powinien mieć wpływu na wydajność.

 357
Author: Greg Hewgill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-28 10:39:59

Wystarczy dodać przykładowy kod do odpowiedzi Grega:

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
 116
Author: Eduardo Molteni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-11 09:45:24

Widziałem go używany, gdy liczba warunków może być zmienna.

Warunki można łączyć za pomocą łańcucha "i". Następnie, zamiast liczyć liczbę warunków, które przekazujesz, umieszczasz "WHERE 1=1" na końcu instrukcji stock SQL i rzucasz na skonkatenowane warunki.

Zasadniczo oszczędza to konieczności wykonania testu dla warunków, a następnie dodania ciągu "gdzie" przed nimi.

 38
Author: Carl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-28 10:43:05

Wygląda na leniwy sposób, aby zawsze wiedzieć, że Twoja klauzula WHERE jest już zdefiniowana i pozwala ci na dodawanie warunków bez konieczności sprawdzania, czy jest to pierwsza.

 28
Author: John Lemp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-28 10:40:05

Pośrednio istotne: gdy stosuje się 1=2:

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

Spowoduje utworzenie nowej tabeli z tym samym schematem co stara tabela. (Bardzo przydatne, jeśli chcesz załadować niektóre dane do porównania)

 20
Author: milso,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-16 06:33:38

1 = 1 wyrażenie jest powszechnie używane w generowanym kodzie sql. To wyrażenie może uprościć generowanie kodu sql, zmniejszając liczbę instrukcji warunkowych.

 17
Author: aku,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-28 10:40:46

Widziałem takie rzeczy używane w raportach Birta. Zapytanie przekazywane do środowiska uruchomieniowego BIRT ma postać:

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

I'?'jest zastępowane w czasie wykonywania przez rzeczywistą wartość parametru wybraną z listy rozwijanej. Wybór w rozwijanym menu jest podany przez:

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

, aby otrzymać wszystkie możliwe wartości plus " *". Jeśli użytkownik wybierze "* " z listy rozwijanej (co oznacza, że należy wybrać wszystkie wartości a), zapytanie musi zostać zmodyfikowane (przez Javascript) przed bycie uciekającym.

Od "?"jest parametrem pozycyjnym i musi tam pozostać, aby inne rzeczy działały, Javascript modyfikuje zapytanie na:

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

To zasadniczo usuwa efekt klauzuli where, pozostawiając parametr pozycyjny na swoim miejscu.

Widziałem również przypadek AND używany przez leniwych programistów podczas dynamicznego tworzenia zapytania SQL.

Powiedz, że musisz dynamicznie utworzyć zapytanie, które zaczyna się od select * from t i sprawdza:

  • the mam na imię Bob; i
  • pensja wynosi > $20,000

Niektórzy ludzie dodaliby pierwsze z WHERE I kolejne z i tak:

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

Leniwi Programiści (a to niekoniecznie jest zła cecha ) nie rozróżnialiby dodanych warunków, zaczynaliby od select * from t where 1=1 i po prostu dodawali i klauzule.

select * from t where 1=1 and name = 'Bob' and salary > 20000
 12
Author: paxdiablo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-30 06:28:32

Znalazłem przydatny ten wzór, gdy testuję lub sprawdzam rzeczy w bazie danych, więc mogę bardzo szybko skomentować inne warunki:

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

Zamienia się w:

CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 
--AND Table.Field=Value
--AND Table.IsValid=true
 12
Author: Carlos Toledo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-03 20:15:02

Gdzie 1=0, odbywa się to w celu sprawdzenia, czy tabela istnieje. Nie wiem dlaczego 1=1 jest używany.

 10
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-14 05:38:29

Chociaż widzę, że 1=1 byłby przydatny dla generowanego SQL, technika, której używam w PHP, polega na utworzeniu tablicy klauzul, a następnie wykonaniu

implode (" AND ", $clauses);

W ten sposób unikamy problemu posiadania wiodącej lub ciągłej i. Oczywiście jest to przydatne tylko wtedy, gdy wiesz, że masz zamiar mieć co najmniej jedną klauzulę!

 6
Author: sanbikinoraion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-07 16:00:12

Oto ściśle powiązany przykład: użycie instrukcji SQL MERGE do aktualizacji celu przy użyciu wszystkich wartości z tabeli źródłowej, gdzie nie ma wspólnego atrybutu, na którym można się połączyć np.

MERGE INTO Circles
   USING 
      (
        SELECT pi
         FROM Constants
      ) AS SourceTable
   ON 1 = 1
WHEN MATCHED THEN 
  UPDATE
     SET circumference = 2 * SourceTable.pi * radius;
 5
Author: onedaywhen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-17 09:33:42

Dlaczego ktoś miałby używać WHERE 1=1 i <proper conditions>

Widziałem frameworki homespun robią takie rzeczy ( blush), ponieważ pozwala to na stosowanie leniwych praktyk parsowania zarówno do słów kluczowychWHERE, jak i AND Sql.

Na przykład (używam C# jako przykład tutaj), rozważ warunkowe parsowanie następujących predykatów w zapytaniu 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";
}

"korzyść" z WHERE 1 = 1 oznacza, że żaden specjalny kod nie jest potrzebne:

  • dla I - czy należy zastosować zero, jeden lub oba predykaty (bary i Baz), które określiłyby, czy wymagana jest pierwsza AND. Ponieważ mamy już przynajmniej jeden predykat z 1 = 1, oznacza to, że AND jest zawsze w porządku.
  • Dla żadnych predykatów - w przypadku, gdy istnieją predykaty zerowe, to WHERE musi zostać odrzucony. Ale znowu, możemy być leniwi, ponieważ znowu jesteśmy gwarancją co najmniej jednego orzeczenia.

To jest to oczywiście zły pomysł i zalecałby użycie ustalonej struktury dostępu do danych lub ORM do przetwarzania opcjonalnych i warunkowych predykatów w ten sposób.

 5
Author: StuartLC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:19

Jeśli szukasz WHERE 1, zauważ, że WHERE 1 i WHERE 1=1 są identyczne. WHERE 1 jest używany rzadko, ponieważ niektóre systemy bazodanowe odrzucają go, ponieważ WHERE 1 nie jest tak naprawdę boolean.

 4
Author: Yogesh Umesh Vaity,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-05 13:24:17

Jest to przydatne w przypadku, gdy musisz użyć dynamicznego zapytania, w którym w klauzula musisz dołączyć kilka opcji filtrowania. Na przykład jeśli dodasz opcje 0 dla status jest nieaktywny, 1 dla aktywny. Na podstawie opcji, są tylko dwie dostępne opcje (0 i 1), ale jeśli chcesz wyświetlić wszystkie rekordy, jest to przydatne do włączenia w where close 1=1. Patrz poniżej przykład:

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);
 2
Author: Eliseo Jr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-16 07:22:40

Po przejrzeniu wszystkich odpowiedzi postanowiłem przeprowadzić eksperyment typu

SELECT
*
FROM MyTable

WHERE 1=1

Potem sprawdziłem innymi numerami

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

Ect Po wykonaniu wszystkich kontroli, zapytanie Uruchom miasto jest taka sama. nawet bez klauzuli where. Nie jestem fanem składni

 2
Author: JonWay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 15:05:16

Robię to zwykle, gdy buduję dynamiczny SQL dla raportu, który ma wiele wartości rozwijanych, które użytkownik może wybrać. Ponieważ użytkownik może lub nie może wybrać wartości z każdego rozwijanego menu, trudno nam się domyślić, który warunek był pierwszą klauzulą where. Tak więc podajemy zapytanie where 1=1 na końcu i dodajemy po nim wszystkie klauzule where.

Coś jak

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

Wtedy zbudowalibyśmy klauzulę where w ten sposób i przekazalibyśmy ją jako parametr wartość

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

Ponieważ wybór klauzuli where nie jest nam znany w czasie wykonywania, więc pomaga nam to w znalezieniu, czy dodać 'AND' or 'WHERE'.

 1
Author: Zo Has,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-19 07:46:31

Pierwszy raz natknąłem się na to z ADO i klasyczną asp, odpowiedź jaką otrzymałem brzmiała: wydajność. if you do a straight

Select * from tablename

I przekaż to jako polecenie sql / tekst otrzymasz zauważalny wzrost wydajności z

Where 1=1

Dodał, to była widoczna różnica. coś związanego z zwracaniem nagłówków tabeli, gdy tylko spełniony jest pierwszy warunek, lub inne szaleństwo, w każdym razie, przyspieszyło to wszystko.

 0
Author: jackberry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-05 18:44:14

Używanie predykatu podobnego do 1=1 jest normalną podpowiedzią używaną czasami, aby wymusić na planie dostępu użycie lub nie użycie skanowania indeksu. Powodem, dla którego jest to używane, jest użycie wielozadaniowego połączonego zapytania z wieloma predykatami w klauzuli where, gdzie czasami nawet użycie wszystkich indeksów powoduje, że plan dostępu odczytuje każdą tabelę-Pełne skanowanie tabeli. Jest to tylko jedna z wielu podpowiedzi używanych przez DBAs, aby oszukać dbms, aby użyć bardziej wydajnej ścieżki. Tylko nie wrzucaj, potrzebujesz dba, aby przeanalizuj zapytanie, ponieważ nie zawsze działa.

 0
Author: Big Al,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-14 18:01:28

Oto przykład użycia... jednak nie jestem zbyt zainteresowany szczegółami technicznymi, dlaczego powinienem lub nie używać 1 = 1. Piszę funkcję, używając pyodbc do pobierania niektórych danych z serwera SQL. Szukałem sposobu, aby wymusić wypełniacz po słowie kluczowym where w moim kodzie. To była naprawdę świetna sugestia:

if _where == '': _where = '1=1'
...
...
...
cur.execute(f'select {predicate} from {table_name} where {_where}')

Powodem jest to, że nie mogłem zaimplementować słowa kluczowego "where" razem wewnątrz zmiennej klauzuli _where. Więc myślę, że używając dowolnego warunku obojętnego, który ocenia na true przydałby się jako wypełniacz.

 0
Author: SMS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-12 02:47:43

Uczynienie "where 1=1" standardem dla wszystkich zapytań sprawia również, że banalnie łatwo jest zweryfikować sql, zastępując go where 1 = 0, przydatnym, gdy masz partie poleceń/plików.

Ułatwia również znalezienie końca sekcji from / join dowolnego zapytania. Nawet zapytania z pod-zapytaniami, jeśli są prawidłowo wcięte.

 0
Author: spioter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-19 14:25:08