Frage

Warum jemand verwenden würde WHERE 1=1 AND <conditions> in einer SQL-Klausel (entweder SQL erhalten durch verkettete Strings, entweder View-Definition)

Ich habe irgendwo gesehen, dass dies gegen SQL-Injection zu schützen verwendet werden würde, aber es scheint sehr seltsam.

Wenn es Injektion WHERE 1 = 1 AND injected OR 1=1 das gleiche Ergebnis wie injected OR 1=1 haben.

Später bearbeiten: Was ist mit der Verwendung in einer View-Definition


Vielen Dank für Ihre Antworten.

Still, Ich verstehe nicht, warum jemand diese Konstruktion für die Definition einer Ansicht verwenden würde, oder es innerhalb einer gespeicherten Prozedur verwenden.

Nehmen Sie dies zum Beispiel:

CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 AND table.Field=Value
War es hilfreich?

Lösung

Wenn die Liste der Bedingungen nicht zum Zeitpunkt der Kompilierung bekannt und wird stattdessen während der Laufzeit gebaut, müssen Sie sich keine Gedanken darüber machen, ob Sie eine oder mehr als eine Bedingung. Sie können sie alle wie erzeugen:

and <condition>

und verketten sie alle zusammen. Mit dem 1=1 am Start, hat der anfängliche and etwas mit zu verbinden.

Ich habe dies nie für jede Art von Spritzschutz gesehen, wie Sie sagen, es scheint nicht, wie es viel helfen würde. I Haben gesehen als Implementierungs Bequemlichkeit verwendet. Die SQL-Abfrage-Engine wird die 1=1 am Ende zu ignorieren, so dass es keine Auswirkungen auf die Leistung haben.

Andere Tipps

Hinzufügen nur ein Beispiel-Code zu Gregs Antwort:

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

Ich habe gesehen, es verwendet wird, wenn die Anzahl der Bedingungen variabel sein kann.

Sie können die Bedingungen verketten eine „und“ Zeichenfolge verwendet wird. Dann statt die Anzahl der Bedingungen Zählen Sie vorbei in, legen Sie eine „WHERE 1 = 1“ am Ende Ihrer Aktien SQL-Anweisung und werfen auf die verketteten Bedingungen.

Im Grunde ist es erspart Sie einen Test für Bedingungen zu tun haben und dann ein „WHERE“ string bevor sie hinzufügen.

scheint wie eine faule Weise immer weiß, dass Ihre WHERE-Klausel bereits definiert ist, und ermöglicht es Ihnen, das Hinzufügen Bedingungen zu halten, ohne zu überprüfen, ob es die erste ist.

Indirekt Relevant: wenn 1 = 2 verwendet wird:

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

Dies wird eine neue Tabelle mit demselben Schema wie alte Tabelle erstellen. (Sehr praktisch, wenn Sie einige Daten laden möchten vergleicht)

1 = 1-Expression wird in der generierten SQL-Code verwendet. Dieser Ausdruck kann SQL-Code generiert vereinfachen Anzahl der bedingten Anweisungen zu reduzieren.

1 = 0, geschieht dies zu überprüfen, ob die Tabelle vorhanden ist. Sie wissen nicht, warum 1 = 1 verwendet wird.

Eigentlich habe ich diese Art der Sache in BIRT verwendet gesehen berichtet. Die Abfrage an die Laufzeit BIRT vergangen ist von der Form:

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

und das '?' zur Laufzeit durch einen tatsächlichen Parameterwert wird von einer Drop-Down-Box ausgewählt ersetzt. Die Auswahl in der Drop-down ist gegeben durch:

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

, so dass Sie alle möglichen Werte erhalten plus "*". Wenn der Benutzer aus der Dropdown-Feld „*“ wählt (dh alle Werte von a ausgewählt werden soll), die Abfrage (von Javascript) modifiziert werden muss, bevor gestartet wird.

Da das "?" ein Positionsparameter und muss für andere Dinge zu arbeiten, ändert die Javascript um die Abfrage zu sein dort bleiben:

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

Das grundsätzlich beseitigt die Wirkung der Klausel, wo während immer noch die Positionsparameter an Ort und Stelle zu verlassen.

Ich habe auch den AND Fall verwendet durch faule Programmierer während dynamischer Erstellung eine SQL-Abfrage.

gesehen

Angenommen, Sie haben, um dynamisch eine Abfrage zu erstellen, die mit select * from t beginnt und Kontrollen:

  • der Name ist Bob; und
  • das Gehalt> $ 20.000

einige Leute die erste hinzufügen würde mit einer WHERE und folgende mit ein und so:

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

Faule Programmierer (und das ist nicht unbedingt ein schlecht Charakterzug) nicht zwischen den zugegebenen Bedingungen unterscheiden, sie mit select * from t where 1=1 beginnen würden und nur hinzufügen, AND-Klauseln danach.

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

Ich fand dieses nützliche Muster, wenn ich die Prüfung oder die Dinge auf der Datenbank doublechecking, so kann ich sehr schnell andere Bedingungen Kommentar:

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

verwandelt sich in:

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

Während ich sehen kann, dass 1 = 1 würde für generierte SQL nützlich sein, eine Technik, die ich in PHP ist eine Reihe von Klauseln zu erstellen und dann tun

implode (" AND ", $clauses);

so zu vermeiden, das Problem eine führende zu haben oder nachgestellte AND. Natürlich ist dies nur dann sinnvoll, wenn Sie wissen, dass Sie zumindest haben eine Klausel werden!

Hier ist ein eng verwandtes Beispiel: SQL MERGE Anweisung mit dem Ziel aktualisieren TABLED alle Werte aus der Quelltabelle verwenden, wo es kein gemeinsames Attribut, auf das beispielsweise auf beitreten

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

Warum sollte jemand WHERE 1 = 1 und <proper conditions>

Ich habe homespun Frameworks gesehen dies tun Sachen wie ( blush ), wie diese beide ermöglicht faul Parsing Praktiken auf die WHERE und AND SQL- Schlüsselwörter angewendet werden.

Zum Beispiel (ich bin mit C # als Beispiel hier), betrachten das bedingte Parsing der folgenden Prädikate in einer SQL-Abfrage string builder:

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

Der "Nutzen" von WHERE 1 = 1 bedeutet, dass kein spezieller Code benötigt wird:

  • und - ob Null, ein oder beiden Prädikate (Bars und Baz) angewandt werden sollen, das anzeigt, ob der erste AND erforderlich bestimmen würde. Da wir schon mindestens ein Prädikat mit der 1 = 1 haben, bedeutet dies, AND immer in Ordnung ist.
  • Für überhaupt keine Prädikate - In dem Fall, wo ZERO Prädikate sind, dann muss der WHERE fallen gelassen werden. Aber auch hier können wir faul sein, weil wir wieder von mindestens einem Prädikat garantiert werden.

Das ist natürlich eine schlechte Idee und würde empfehlen, einen etablierten Datenzugriff Framework oder ORM zum Parsen optional und bedingte Prädikate auf diese Weise.

Wenn Sie hierher gekommen für WHERE 1 suchen, beachten Sie, dass WHERE 1 und WHERE 1=1 identisch sind. WHERE 1 wird selten verwendet, da einige Datenbanksysteme ablehnen wenn man bedenkt es WHERE 1 nicht wirklich zu sein boolean.

Das ist in einem Fall nützlich, wenn Sie die dynamische Abfrage, in der verwenden haben, in denen Klausel müssen Sie einige Filteroptionen anhängen. Wie, wenn Sie Optionen 0 für den Status sind inaktiv, 1 für aktiv. Basierend aus den Optionen gibt es nur zwei Optionen (0 und 1), aber wenn Sie alle Datensätze angezeigt werden sollen, ist es praktisch, in denen schließen 1 = 1 aufzunehmen. Siehe unten Beispiel:

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

Mit Überprüfung alle Antworten habe ich beschlossen, einige Experiment wie

auszuführen
SELECT
*
FROM MyTable

WHERE 1=1

Dann überprüfte ich mit anderen Zahlen

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

ect Nachdem dies erledigt aller Kontrollen ist die Abfrage laufen Stadt gleich. auch ohne die where-Klausel. Ich bin kein Fan von der Syntax

ein Prädikats wie 1=1 Verwendung ist ein normaler Hinweis manchmal den Zugriffsplan zu zwingen, verwendet oder nicht verwendet einen Index-Scan verwenden. Der Grund, warum diese verwendet wird, ist, wenn Sie eine Multi-verschachtelte Join-Abfrage mit vielen Prädikaten in der where-Klausel, wo manchmal sogar alle Indizes verwenden bewirkt, dass der Zugriffsplan jede Tabelle lesen - einen vollständigen Table-Scan. Dies ist nur 1 von vielen Hinweisen von DBAs verwendet, um eine dbms in mit einem effizienteren Weg zu betrügen. Nur nicht werfen ein in; Sie benötigen einen dba die Abfrage zu analysieren, da es nicht immer funktioniert.

Ich tue dies in der Regel, wenn ich für einen Bericht dynamische SQL bin Gebäude, die viele Drop-Down hat Werte ein Benutzer auswählen kann. Da der Benutzer nicht kann die Werte von jedem Dropdown auswählen oder kann am Ende wir herauszufinden, eine harte Zeit, die Bedingung der erste war, wo Klausel. So Pad wir die Abfrage mit einem where 1=1 am Ende nach oben und fügen Sie alle where-Klauseln danach.

So etwas wie

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

Dann würden wir die where-Klausel wie dieses bauen und als Parameterwert übergeben

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

Wie die where-Klausel Auswahl uns zur Laufzeit nicht bekannt ist, so das hilft uns sehr viel bei der Suche nach, ob ein 'AND' or 'WHERE'. einschließen

ich zum ersten Mal über diese kam mit ADO und klassischen Asp zurück, die Antwort, die ich bekam, war:. Leistung wenn Sie eine gerade tun

Select * from tablename

und als SQL-Befehl / Text passiert in Sie eine spürbare Leistungssteigerung mit dem bekommen

Where 1=1

hinzugefügt, es ein sichtbarer Unterschied war. etwas mit Tabellenüberschriften zu tun, so schnell zurückgegeben wird als die erste Bedingung erfüllt ist, oder eine andere Verrücktheit, wie auch immer, es hat die Dinge beschleunigen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top