Perché qualcuno dovrebbe usare WHERE 1 = 1 AND in una clausola SQL?

Perché qualcuno dovrebbe usare WHERE 1=1 AND in una clausola SQL (o SQL ottenuto tramite stringhe concatenate, o definizione della vista)

Ho visto da qualche parte che questo sarebbe stato usato per proteggere da SQL Injection, ma sembra molto strano.

Se c’è un’iniezione WHERE 1 = 1 AND injected OR 1=1 avrebbe lo stesso risultato di injected OR 1=1 .

Modifica successiva: per quanto riguarda l’utilizzo in una definizione di visualizzazione?


Grazie per le tue risposte.

Tuttavia, non capisco perché qualcuno dovrebbe usare questa costruzione per definire una vista, o usarla all’interno di una stored procedure.

Prendi questo ad esempio:

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

Se l’elenco delle condizioni non è noto al momento della compilazione e viene invece creato in fase di esecuzione, non è necessario preoccuparsi se si dispone di una o più condizioni. Puoi generarli tutti come:

 and  

e concatenarli tutti insieme. Con 1=1 all’inizio, l’iniziale and ha qualcosa da associare.

Non l’ho mai visto usato per nessun tipo di protezione per l’iniezione, come dici tu non sembra che sarebbe di grande aiuto. L’ho visto usato come comodità di implementazione. Il motore di query SQL finirà per ignorare 1=1 quindi non dovrebbe avere alcun impatto sulle prestazioni.

Basta aggiungere un codice di esempio alla risposta di Greg:

 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 

L’ho visto usato quando il numero di condizioni può essere variabile.

È ansible concatenare le condizioni utilizzando una stringa “AND”. Quindi, invece di contare il numero di condizioni che stai trasmettendo, devi inserire “WHERE 1 = 1” alla fine della tua dichiarazione SQL azionaria e lanciare le condizioni concatenate.

Fondamentalmente, ti risparmia di dover fare un test per le condizioni e quindi aggiungere una stringa “WHERE” prima di loro.

Sembra un modo pigro per sapere sempre che la tua clausola WHERE è già definita e ti consente di continuare ad aggiungere condizioni senza dover controllare se è la prima.

1 = 1 espressione è comunemente usata nel codice sql generato. Questa espressione può semplificare il codice di generazione SQL riducendo il numero di istruzioni condizionali.

Indirettamente rilevante: quando si utilizza 1 = 2:

CREATE TABLE New_table_name come seleziona * FROM Old_table_name WHERE 1 = 2;

questo creerà una nuova tabella con lo stesso schema della vecchia tabella. (Molto utile se si desidera caricare alcuni dati per il confronto)

In realtà, ho visto questo genere di cose usate nei report BIRT. La query passata al runtime BIRT è del formato:

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

e il ‘?’ viene sostituito in fase di esecuzione da un valore di parametro effettivo selezionato da una casella a discesa. Le scelte nel menu a discesa sono date da:

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

in modo da ottenere tutti i valori possibili più ” * “. Se l’utente seleziona ” * ” dalla casella a discesa (che significa che devono essere selezionati tutti i valori di a), la query deve essere modificata (da Javascript) prima di essere eseguita.

Dal momento che il “?” è un parametro posizionale e DEVE rimanere lì per far funzionare altre cose, il Javascript modifica la query per essere:

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

Ciò rimuove sostanzialmente l’effetto della clausola where lasciando il parametro posizionale in posizione.

Ho anche visto il caso AND usato dai codificatori pigri mentre creava dynamicmente una query SQL.

Supponi di dover creare dynamicmente una query che inizi con select * from t e controlli:

  • il nome è Bob; e
  • lo stipendio è> $ 20.000

alcune persone aggiungerebbero il primo con un DOVE e quelli successivi con un AND:

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

I programmatori pigri (e questo non è necessariamente un tratto negativo ) non distinguerebbero tra le condizioni aggiunte, comincerebbero con select * from t where 1=1 e aggiungeranno semplicemente le clausole AND successivamente.

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

dove 1 = 0, Questo è fatto per verificare se la tabella esiste. Non so perché 1 = 1 è usato.

Ho trovato utile questo modello quando sto testando o duplicando le cose sul database, così posso commentare molto velocemente altre condizioni:

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

diventa:

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

Mentre posso vedere che 1 = 1 sarebbe utile per l’SQL generato, una tecnica che uso in PHP è creare una serie di clausole e poi fare

 implode (" AND ", $clauses); 

evitando così il problema di avere un AND leader o finale. Ovviamente questo è utile solo se sai che avrai almeno una clausola!

Ecco un esempio strettamente correlato: l’utilizzo di un’istruzione SQL MERGE per aggiornare il target presentato utilizzando tutti i valori della tabella di origine in cui non esiste un attributo comune su cui partecipare, ad esempio

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

Perché qualcuno dovrebbe usare DOVE 1 = 1 E

Ho visto i quadri homespun fare cose del genere ( arrossire ), in quanto ciò consente di applicare le pratiche di analisi pigro alle parole chiave WHERE e AND Sql.

Ad esempio (sto usando C # come esempio qui), si consideri l’analisi condizionale dei seguenti predicati in un string builder query Sql:

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

Il "vantaggio" di WHERE 1 = 1 significa che non è necessario alcun codice speciale:

  • Per AND - se deve essere applicato zero, uno o entrambi i predicati (Bar e Baz), che determinerebbe se il primo AND è richiesto. Poiché abbiamo già almeno un predicato con 1 = 1 , significa che AND è sempre OK.
  • Per nessun predicato - Nel caso in cui ci siano predicati ZERO, il WHERE deve essere abbandonato. Ma di nuovo, possiamo essere pigri, perché siamo di nuovo la garanzia di almeno un predicato.

Questa è ovviamente una ctriggers idea e raccomanderebbe l'utilizzo di un framework di accesso ai dati o ORM per l'analisi dei predicati facoltativi e condizionali in questo modo.

Se sei venuto qui a cercare WHERE 1 , nota che WHERE 1 e WHERE 1=1 sono identici. WHERE 1 è usato raramente perché alcuni sistemi di database lo rifiutano considerando WHERE 1 non è veramente booleano.

Ciò è utile nel caso in cui sia necessario utilizzare la query dynamic in cui nella clausola where è necessario aggiungere alcune opzioni di filtro. Come se includessi le opzioni 0 per lo stato è inattivo, 1 per attivo. In base alle opzioni, sono disponibili solo due opzioni (0 e 1), ma se si desidera visualizzare tutti i record, è utile includere in dove chiudere 1 = 1. Vedi sotto campione:

 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); 

Dopo aver esaminato tutte le risposte, ho deciso di eseguire alcuni esperimenti come

 SELECT * FROM MyTable WHERE 1=1 

Poi ho controllato con altri numeri

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

ect Dopo aver effettuato tutti i controlli, la query run town è la stessa. anche senza la clausola where. Non sono un fan della syntax

L’utilizzo di un predicato come 1=1 è un suggerimento normale a volte utilizzato per forzare il piano di accesso a utilizzare o non utilizzare una scansione dell’indice. Il motivo per cui viene utilizzato è quando si utilizza una query unita a più nidificati con molti predicati nella clausola where, dove a volte anche utilizzando tutti gli indici fa sì che il piano di accesso legga ciascuna tabella: una scansione completa della tabella. Questo è solo uno dei tanti suggerimenti usati dagli amministratori di database per ingannare un database in modo da utilizzare un percorso più efficiente. Basta non gettarne uno; è necessario un dba per analizzare la query poiché non sempre funziona.

Lo faccio di solito quando sto creando SQL dinamico per un report che ha molti valori di dropdown che un utente può selezionare. Poiché l’utente può o non può selezionare i valori da ciascun menu a discesa, finiamo con l’avere difficoltà a capire quale condizione era la prima clausola where. Quindi recuperiamo la query con una where 1=1 alla fine e aggiungiamo tutte le clausole where dopo.

Qualcosa di simile a

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

Quindi dovremmo build la clausola where in questo modo e passarla come valore di parametro

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

Dato che la selezione della clausola where ci è sconosciuta in fase di runtime, questo ci aiuta molto a scoprire se includere un 'AND' or 'WHERE'.

L’ho incontrato per la prima volta con ADO e ASP classico, la risposta che ho ottenuto è stata: prestazioni. se fai una scala

Select * from tablename

e passalo come un comando / testo sql otterrai un notevole aumento delle prestazioni con

Where 1=1

aggiunto, era una differenza visibile. qualcosa a che fare con le intestazioni delle tabelle restituite non appena viene soddisfatta la prima condizione, o qualche altra follia, comunque, ha fatto accelerare le cose.