2009-08-12 38 views
8

mögliche Dubletten:
Why would a sql query have “where 1 = 1”
Why would someone use WHERE 1=1 AND <conditions> in a SQL clause?Welchen Zweck hat WHERE 1 = 1 in SQL-Anweisungen?

Ich habe gesehen, dass viele in verschiedenen Abfragebeispiele und es geht wahrscheinlich alle SQL-Motoren.

Wenn es eine Abfrage gibt, die keine Bedingungen hat, definieren Personen (und speziell ORM-Frameworks) oft immer-wahr-Bedingung WHERE 1 = 1 oder so ähnlich.

Also statt

SELECT id, name FROM users; 

sie verwenden

SELECT id, name FROM users WHERE 1 = 1; 

Der einzig mögliche Grund, warum ich denken konnte, wenn Sie Bedingungen hinzufügen, dynamisch Sie müssen nicht über Abstreifen des anfänglichen AND zur Sorge, aber Diese Bedingung 1 = 1 wird immer noch häufig entfernt, wenn eine tatsächliche Bedingung in der Abfrage vorhanden ist.

Actual Beispiel von CakePHP (durch Rahmen generiert):

(keine Bedingungen)

SELECT `User`.`id`, `User`.`login` 
FROM `users` AS `User` WHERE 1 = 1 
ORDER BY `User`.`id` ASC; 

(mit Bedingung)

SELECT `User`.`id`, `User`.`login` 
FROM `users` AS `User` 
WHERE `User`.`login` = '[email protected].com' 
LIMIT 1; 

Gibt es einen Grund für die zusätzliche Bedingung hinzuzufügen?

+1

Dupe von http://stackoverflow.com/questions/517107/why-would-a-sql-query-have-where-1-1 unter anderem –

Antwort

4

Ja, es ist in der Regel weil es beginnt als 'where 1 = 0', um die Anweisung zum Scheitern zu zwingen.

Es ist eine naive Art, es in eine Transaktion einzubinden und am Ende nicht zu committen, um Ihre Anfrage zu testen. (Dies ist die bevorzugte Methode).

+0

Es kann mehr als eine Antwort geben; und in diesem Fall war das OP spezifisch, dass es nicht nur für die Erstellung dynamischer Abfragen gedacht war (und ehrlich gesagt, wenn Sie dynamische Abfragen in diesen Tagen von ORMs erstellen, nehmen Sie sich einen guten Blick auf sich selbst). –

2

Die Verwendung von 1 = 1 ist eigentlich keine sehr gute Idee, da dies ganze Tabellen-Scans allein verursachen kann.

Siehe this ->T-SQL 1=1 Performance Hit

+1

Nur auf dem Crappiest von DBMS '. – paxdiablo

+1

Alle Antworten in der Frage, die Sie mit 1 = 1 verknüpft haben, haben keine Auswirkungen. – Ryan

13

Es ist auch eine gängige Praxis, wenn die Leute baut die SQL-Abfrage programmatisch, es ist nur einfacher zu starten mit ‚1 = 1‘ und dann Anhängen 'und customer.id =: custId 'abhängig davon, ob eine Kundennummer angegeben wurde. So können Sie immer den nächsten Teil der Abfrage anhängen, beginnend mit 'und ...'.

+1

-1 Dies wiederholt die Frage, die besagt: "Sie müssen sich keine Gedanken über das Entfernen der ursprünglichen UND" – Andomar

1

Wie Sie gesagt haben:

wenn Sie Bedingungen hinzufügen Sie dynamisch die anfänglichen Sorgen machen müssen Strippen nicht über UND , die der einzige Grund ist sein könnte, Sie haben Recht.

4

The 1 = 1 wird von immer alle rdbms ignoriert.Es gibt keinen Kompromiss, der eine Abfrage mit WHERE 1 = 1 ausführt.

Gebäude dynamische WHERE-Bedingungen, wie ORM-Frameworks oder andere sehr oft tun, ist es einfacher, die echte, wo die Bedingungen anzuhängen, weil Sie für das Voranstellen eines UND dem aktuellen Zustand überprüft vermeiden.

stmt += "WHERE 1=1"; 
if (v != null) { 
    stmt += (" AND col = " + v.ToString()); 
} 

So sieht es ohne 1 = 1 aus.

var firstCondition = true; 
... 
if (v != null) { 
    if (!firstCondition) { 
     stmt += " AND "; 
    } 
    else { 
     stmt += " WHERE "; 
     firstCondition = false; 
    } 
    stmt += "col = " + v.ToString()); 
} 
+1

Eigentlich tendiere ich dazu, etwas wie zu tun: cmd = "select ..."; sep = "wo"; foreach (cond) {cmd + = sep + cond; sep = "und"; } – paxdiablo

+0

Das sieht ein * wenig * sauberer aus. – paxdiablo

+0

Gute Idee! Ich behalte es für die weitere Programmierung im Hinterkopf. – Christian13467

3

Die Leute verwenden es, weil sie beim Erstellen dynamischer SQL-Abfragen inhärent faul sind. Wenn Sie mit einem "where 1 = 1" beginnen, dann beginnen alle Ihre Extra-Klauseln einfach mit "and" und Sie müssen nicht herausfinden.

Nicht dass es etwas falsch daran wäre, von Natur aus faul zu sein. Ich habe doppelt verkettete Listen gesehen, bei denen eine "leere" Liste aus zwei Sentinel-Knoten besteht und Sie beginnen mit der Verarbeitung bei first->next bis einschließlich last->prev.

Dies entfernte tatsächlich alle speziellen Handhabung Code zum Löschen first und last Knoten. In dieser Konfiguration war jeder Knoten ein mittlerer Knoten, da Sie first oder last nicht löschen konnten. Zwei Knoten wurden verschwendet, aber der Code war einfacher und (etwas) schneller.

Der einzige andere Ort, an dem ich jemals das "1 = 1" Konstrukt gesehen habe, ist in BIRT. Berichte verwenden oft Positionsparameter und werden mit Javascript modifiziert, um alle Werte zuzulassen. So ist die Abfrage:

select * from tbl where col = ? 

, wenn der Benutzer "*" für den Parameter für col modifiziert wird, verwendet wird zum:

select * from tbl where ((col = ?) or (1 = 1)) 

Dies ermöglicht die neue Abfrage mit dem Positionsparameter ohne Hantieren verwendet werden Einzelheiten. Es gibt immer noch genau einen solchen Parameter. Jedes vernünftige DBMS (z. B. DB2/z) wird diese Abfrage optimieren, um die Klausel im Wesentlichen vollständig zu entfernen, bevor versucht wird, einen Ausführungsplan zu erstellen, so dass es keinen Kompromiss gibt.

+0

Danke, Alter! Das war die plausibelste Antwort! –

Verwandte Themen