Funktionsweise bei logischen Operatoren

Schüppi

Neuer Benutzer
Beiträge
3
Hallo,

werden beim OR-Operator immer beide Ausdrücke ausgewertet oder evtl. nur der erste, falls dieser TRUE ergibt?

Mit freundlichen Grüßen
Schüppi
 
Werbung:

Tommi

Datenbank-Guru
Beiträge
290
Hallo Schüppi,

ein logischer Ausdruck wird nicht sequentiell ausgewertet. Der SQL Server betrachtet zunächst die verketteten Ausdrücke und prüft, ob hier ein Ergenis herauskommt, das auch logisch Verknüpfbar ist.
Es werden also zunächst die Unterausdrücke ausgewertet.

Das kann man nachvollziehen, wenn man z.B. eine Division durch 0 in einer UNterberechnung durchführt. Dann gibt der SQL Server eine Fehlermeldung aus, auch wenn diese Rechnung in der x+1. Stelle der Logik-Verknüpfung steht.
Beispiel: CASE WHEN Wert1>15 Or Wert1 / Wert2 > 3 THEN ...
Funktioniert, wenn Wert2<>0 ist. Bei Wert2=0 wird eine Fehlermeldung ausgegeben.

Fazit: ein Logischer Ausdruck wird immer im Gesamten ausgewertet, aber nicht der Reihenfolge nach.


Viele Grüße,
Tommi
 

akretschmer

Datenbank-Guru
Beiträge
9.846
Hallo Schüppi,

ein logischer Ausdruck wird nicht sequentiell ausgewertet. Der SQL Server betrachtet zunächst die verketteten Ausdrücke und prüft, ob hier ein Ergenis herauskommt, das auch logisch Verknüpfbar ist.
Es werden also zunächst die Unterausdrücke ausgewertet.

Das kann man nachvollziehen, wenn man z.B. eine Division durch 0 in einer UNterberechnung durchführt. Dann gibt der SQL Server eine Fehlermeldung aus, auch wenn diese Rechnung in der x+1. Stelle der Logik-Verknüpfung steht.
Beispiel: CASE WHEN Wert1>15 Or Wert1 / Wert2 > 3 THEN ...
Funktioniert, wenn Wert2<>0 ist. Bei Wert2=0 wird eine Fehlermeldung ausgegeben.

Fazit: ein Logischer Ausdruck wird immer im Gesamten ausgewertet, aber nicht der Reihenfolge nach.


Viele Grüße,
Tommi


Gute Frage und gute Antwort, ich mach grad eine andere Erfahrung:

Code:
test=*# select 1 where true or 1=1 or (1/0 = 1);
 ?column?
----------
        1
(1 row)

test=*# select 1/0;
ERROR:  division by zero
test=*# select 1 where true or 1=1 or (1/0 = 1);
 ?column?
----------
        1
(1 row)

test=*# select 1 where (1/0 = 1) or true or 1=1 or (1/0 = 1);
ERROR:  division by zero
test=*#

PG optimiert hier, und nach dem ersten Treffer bricht es ab, das zu untersuchen, prüft also nicht die anderen Ausdrücke.


Andreas
 

Tommi

Datenbank-Guru
Beiträge
290
Hallo zusammen,

ich muss hier ein wenig zurückrudern. Ganz so in der Reihenfolge wie ich es zunächst beschrieben habe, arbeitet der SQL-Server tatsächlich nicht. Insbesondere das Beispiel in meiner ersten Antwort war Falsch!

Ich habe aber noch ein wenig nachgelesen.
Bei einer logischen Verknüpfung mir OR wird nach einem wahren Ausdruck gesucht. Fehler werden hierbei zunächst ignoriert (bzw. wir der Wert UNKNOWN zurückgegeben)
Wenn direkt ein wahrer Wert in der Verknüpfung gefunden wird, gibt der Gesamt-Ausdruck auch ein "TRUE" zurück.
Wenn kein Prüf-Wert das Ergebnis "TRUE" zurückgibt, werden die "UNKNOWN"-Werte im Details betrachtet, was in der Regel zu einer Fehlermeldung führt.

Link hierzu: http://msdn.microsoft.com/de-de/library/ms186992(v=sql.105).aspx

So lange ein Wert der OR-Verknüpfung "TRUE" zurückgibt und somit das Ergebnis der Gesamt-Verknüpfung fest steht, werden die UNKNOWN-Rückgaben einfach ignoriert.

Sorry, wenn ich mit der vorherigen Antwort jetzt jemanden verwirrt habe (ich war's selbst ja dann auch) - manchmal muss man doch noch mal nachlesen :oops:.

Viele Grüße,
Tommi
 

Schüppi

Neuer Benutzer
Beiträge
3
Ich hatte die Frage gestellt, weil in einem Ausdruck eine Skalarwertfunktion aufgerufen wird und ich überlegte, ob es sinnvoll ist, diese als zweiten Ausdruck (nach "OR") zu verwenden, damit die Funktion nicht ausgeführt werden muss, falls der andere Ausdruck bereits TRUE zurück gibt.
Euren Antworten entnehme ich jetzt, dass die Reihenfolge egal ist.
Danke.

LG Schüppi
 
Werbung:

ukulele

Datenbank-Guru
Beiträge
4.702
Das würde ich nach den neueren Erkentnissen nicht so sehen. Wenn der erste Ausdruck wahr ist wird der 2te "unter Umständen" nicht mehr verarbeitet. Ich meine das das auch bei Subselects der Fall ist.
 
Oben