Frage

Ich arbeite auf eine Abfrage zu optimieren und haben in einer Situation, lief das mich macht die Frage, wie ich immer SQL des OR-Operator verwendet haben. (SQL Server 2000 auch)

Ich habe eine Abfrage, wo die bedingte (WO) Klausel etwa wie folgt aussieht:

WHERE (Column1 = @Param1 or Column1 LIKE @Param1 + '%')
AND (@Param2 = '' OR Column2 = @Param2 OR Column2 LIKE @Param2 + '%')

Jetzt habe ich immer verstanden, dass OR in SQL beiden Ausdrücke ausgewertet. So werden alle Datensätze, die wahr für den linken Ausdruck ausgewertet würden alle zurückgegebenen Datensätze zusammen, die wahr auf dem richtigen Ausdruck ausgewertet. Zum Beispiel:

SELECT * FROM TABLE1
WHERE COL1 = 'Test' OR Col2 = 'Data'

Dies würde alle Datensätze zurück, zurück, wo COL1 is'Test‘sowie jeden Datensatz, in dem Col2 ist‚Daten‘

In dem obigen Beispiel modifizierte ich die Spalte2 bedingte auf die folgenden:

AND(Column2 LIKE ISNULL(@Param2, '') + '%')

Ganz plötzlich, ich 0 Zeilen zurückgegeben.

Habe ich, dass OR wertet nur Ausdrücke verwechselt worden, bis es ein Ergebnis TRUE finden oder gibt es eine Bedingung, dass die zwei verschiedenen zurückzukehren unterschiedlichen Ergebnissen führen würde?

War es hilfreich?

Lösung

„ODER nur auswertet Ausdrücke, bis es ein Ergebnis TRUE finden“

Es hat nur zu, aber das ist nicht Ihr Problem (eigentlich das ist, was Sie in Ihrem ursprünglichen Fall spart). Ihre beiden Abfragen sind nicht wirklich gleichwertig.

Ich denke, Sie NULLs in Column2 haben, die nie (Column2 LIKE ISNULL(@Param2, '') + '%') verursachen um wahr zu sein - und in der ursprünglichen Version der @Param2 = '' diesen Fall wurde maskieren, da es wahr ist (manchmal)

Vielleicht:

(ISNULL(Column2, '') LIKE ISNULL(@Param2, '') + '%')

Denken Sie daran, die dreiwertigen Logik für NULL-Werte:

TRUE and UNKNOWN: UNKNOWN
TRUE or UNKNOWN: TRUE

FALSE and UNKNOWN: FALSE
FALSE or UNKNOWN: UNKNOWN

Aber ich bin nicht sicher, dass Ihre Optimierung wirklich hilft.

Andere Tipps

oder nicht allumfassend, zumal es in den Klammern ist. Was Sie in einem größeren haben, da ist: WHERE X AND Y. Die Tatsache, dass X und Y selbst Booleschen Ausdrücken, die Verwendung eines OR machen, ist nicht wichtig. Sie werden getrennt ausgewertet und dann werden die Ergebnisse zu dem AND-Operator zugeführt

[Bearbeiten]:
Lesen wieder, ich mag Ihre Frage falsch verstanden. In diesem Sinne werde, ich habe mit der anderen Antwort gehen, weil NULL LIKE '%' NULL zurückgibt, die die gleiche wie falsch in diesem Fall ist. Sie könnten versuchen, diese stattdessen:

COALESCE(Column2,'') LIKE COALESCE(@param2,'') + '%'

FYI, gibt es nur sehr einfache Experimente Sie tun können, um zu sehen, dass nicht alle Bedingungen unbedingt ausgewertet werden.

Ich tue dies in Oracle, aber ich erwarte, dass Sie ein ähnliches Ergebnis in SQL Server haben.

dev> select * from dual where 1=1 or 1/0 = 3;

D
-
X

Der Zustand nach dem OR darf nicht ausgewertet worden sind, da es sich um eine Division durch Null-Fehler erhöhen würde.

Diese Handhabung von Booleschen Operatoren wird im Allgemeinen als „Kurzschluss“ bekannt und AFAIK ist ziemlich Standard in modernen Sprachen. Es kann auch in einem UND-Ausdruck gilt -., Wenn die erste Bedingung falsch ist, gibt es keinen Punkt ist die zweite Bedingung bei der Bewertung, da der gesamte Ausdruck nicht wahr sein kann

Mehr Infos: http://en.wikipedia.org/wiki/Short-circuit_evaluation

Wie auch immer als Cade sagte, Ihr eigentliches Problem ist falsche Handhabung wahrscheinlich von NULL-Werten.

MS-SQL wird die linke Seite zuerst bewerten und nicht fortgesetzt werden, es sei denn es muss.

Dies ist das gleiche mit dem AND-Anschluss, wird die linke Seite ausgewertet und wenn falsch wird das Recht nicht evaulated werden.

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