Firebird Documentation IndexFirebird 2.5 SprachreferenzAllgemeine Sprachelemente → Ausdrücke
Firebird Home Firebird Home Zurück: Allgemeine SprachelementeFirebird Documentation IndexNach oben: Allgemeine SprachelementeWeiter: Prädikate

Ausdrücke

Inhaltsverzeichnis

Konstanten
SQL-Operatoren
Bedingte Ausdrücke
NULL in Ausdrücken
Unterabfragen

SQL-Ausdrücke bieten formelle Methoden zum Auswerten, Transformieren und Vergleichen von Werten. SQL-Ausdrücke können Tabellenspalten, Variablen, Konstanten, Literale, andere Statements und Prädikate sowie andere Ausdrücke enthalten. Folgend die vollständige Liste möglicher Elemente.

Tabelle 4.1. Beschreibung der Ausdruck-Elemente

Element Beschreibung
Spaltenname Kennung einer Spalte aus einer angegebenen Tabelle, die in Auswertungen oder als Suchbedingung verwendet wird. Eine Spalte des Array-Typs kann kein Element innerhalb eines Ausdrucks sein, es sei denn sie wird mit dem IS [NOT] NULL-Prädikat verwendet.
Array-Element Ein Ausdruck kann einen Verweis auf ein Array-Element enthalten.
Arithmetische Operatoren Die Zeichen +, -, *, / werden verwendet um Berechnungen durchzuführen.
Verkettungsoperator Der Operator || („Doppel-Pipe“) wird verwendet um Strings zu verketten.
Logische Operatoren Die reservierten Wörter NOT, AND sowie OR werden verwendet um einfache Suchbedingungen oder komplexere Behauptungen zu erstellen.
Vergleichsoperatoren Die Zeichen =, <>, !=, ~=, ^=, <, <=, >, >=, !<, ~<, ^<, !>, ~> und ^>
Vergleichsprädikate LIKE, STARTING WITH, CONTAINING, SIMILAR TO, BETWEEN, IS [NOT] NULL und IS [NOT] DISTINCT FROM
Existenzprädikate Prädikate, die für die Existenzprüfung von Werten Verwendung finden. Das Prädikat IN kann sowohl innerhalb von Listen kommagetrennter Konstanten als auch mit Unterabfragen, die nur eine Spalte zurückgeben, verwendet werden. Die Prädikate EXISTS, SINGULAR, ALL, ANY und SOME können nur mit Unterabfragen verwendet werden.
Konstanten Eine Zahl; oder eine Zeichenkette, die in Apostrophs eingeschlossen wird.
Datum-/Zeitliterale Ein Ausdruck, ähnlich zu Zeichenketten, eingeschlossen in Apostrophs, der als Datum, Zeit oder Zeitstempel interpretiert wird. Datumsliterale können vordefinierte Literale ('TODAY', 'NOW', etc.) oder Zeichenketten aus Buchstaben oder Zahlen sein, wie zum Beispiel '25.12.2016 15:30:35', die zu einem Datum und/oder einer Zeit aufgelöst werden können.
Kontextvariablen Eine intern definierte Kontextvariable
Lokale Variablen Deklarierte lokale Variablen, Über- und Rückgabeparameter eines PSQL-Moduls (Stored Procedure, Trigger, unbenannter PSQL-Block in DSQL)
Positionale Parameter Ein Mitglied innerhalb einer geordneten Gruppe von einem oder mehreren unbenannten Parametern, die an eine gespeicherte Prozedur oder eine vorbereitete Abfrage übergeben wurden.
Unterabfrage Eine SELECT-Anweisung, die in Klammern eingeschlossen ist, die einen einzelnen (skalaren) Wert zurückgibt oder, wenn er in existenziellen Prädikaten verwendet wird, einen Satz von Werten.
Funktionskennung Die Kennung einer internen oder externen Funktion in einem Funktionsausdruck
Type-Cast Ein Ausdruck, der explizit Daten von einem in einen anderen Datentyp unter Verwendung der CAST-Funktion ( CAST (<value> AS <datatype>) ) konvertiert. Nur für Datum-/Zeit-Literale ist die Kurzschreibweise <datatype> <value> (DATE '25.12.2016') möglich.
Bedingter Ausdruck Ausdrücke mit CASE und verwandten internen Funktionen
Klammern Klammernpaare (…) werden verwendet, um Ausdrücke zu gruppieren. Operationen innerhalb der Klammern werden vor Operationen außerhalb von ihnen durchgeführt. Wenn eingebettete Klammern verwendet werden, werden die tiefsten eingebetteten Ausdrücke zuerst ausgewertet und dann bewegen sich die Auswertungen von innen nach außen durch die Einbettungsstufen.
COLLATE-Klausel Klausel, die für CHAR- und VARCHAR-Datentypen angewendet werden kann, um die Collation für String-Vergleiche festzulegen.
NEXT VALUE FOR Sequenz Ausdruck zum Ermitteln des nächsten Wertes eines bestimmten Generators (Sequenz). Die interne Funktion GEN_ID() tut das Gleiche.


Konstanten

Eine Konstante ist ein Wert der direkt in einem SQL-Statement verwendet wird und weder von einem Ausdruck, einem Parameter, einem Spaltenverweis noch einer Variablen abgeleitet wird. Dies kann eine Zeichenkette oder eine Zahl sein.

Zeichenkonstanten (Literale)

Eine String-Konstante ist eine Aneinanderreihung von Zeichen, die zwischen einem Paar von Apostrophen („einfache Anführungszeichen“) eingeschlossen werden. Die größtmögliche Länge dieser Zeichenketten ist 32.767 Bytes; die maximale Anzahl der Zeichen wird durch die verwendete Zeichenkodierung bestimmt.

Anmerkung

  • Doppelte Anführungszeichen dürfen nicht für die Kennzeichnung von Zeichenketten verwendet werden. SQL sieht hierfür einen anderen Zweck vor.
  • Wird ein Apostroph innerhalb der Zeichenkette benötigt, wird dieses durch ein vorangehendes Apostroph „escaped“. Zum Beispiel 'Mother O''Reilly's home-made hooch'.
  • Vorsicht ist geboten bei String-Längen, wenn der Wert in ein Feld des Typs VARCHAR geschrieben wird. Hierfür gilt die maximale Länge von 32.765 Bytes.

Es wird angenommen, dass der Zeichensatz einer Zeichenkonstanten der gleiche ist wie der Zeichensatz seines Bestimmungsspeichers.

Stringkonstanten in Hexadezimalnotation

Ab Firebird 2.5 aufwärts, können Stringliterale in hexadezimaler Schreibweise eingegeben werden, die sogenannten „Binary Strings“. Jedes Paar hexadezimaler Stellen definiert ein Byte der Zeichenkette. Zeichenketten die in dieser Form eingegeben werden, besitzen den Zeichensatz OCTETS als Standard. Die Introducer-Syntax kann auch genutzt werden um zu erzwingen, dass die Zeichenkette als ein anderer Zeichensatz interpretiert wird.

Syntax: 

{x|X}'<hexstring>'

  <hexstring>  ::=  eine gerade Anzahl von <hexdigit>
  <hexdigit>   ::=  eines aus 0..9, A..F, a..f
              

Beispiele: 

    select x'4E657276656E' from rdb$database
      -- liefert 4E657276656E, a 6-byte 'binary' string

    select _ascii x'4E657276656E' from rdb$database
      -- liefert 'Nerven' (same string, now interpreted as ASCII text)

    select _iso8859_1 x'53E46765' from rdb$database
      -- liefert 'Säge' (4 chars, 4 bytes)

    select _utf8 x'53C3A46765' from rdb$database
      -- liefert 'Säge' (4 chars, 5 bytes)
            

Hinweise

Die Client-Schnittstelle legt fest, wie Binärzeichenfolgen dem Benutzer angezeigt werden. Das isql-Werkzeug beispielsweise, nutzt großgeschriebene Buchstaben A-F, während FlameRobin Kleinschreibung verwendet. Andere Client-Applikationen könnten andere Konventionen bevorzugen, zum Beispiel Leerzeichen zwischen den Bytepaaren: '4E 65 72 76 65 6E'.

Mit der hexadezimalen Notation kann jeder Bytewert (einschließlich 00) an beliebiger Stelle im String eingefügt werden. Allerdings, wenn Sie diesen auf etwas anderes als OCTETS erzwingen wollen, liegt es in Ihrer Verantwortung, die Bytes in einer Sequenz zu liefern, die für den Zielzeichensatz gültig ist.

Introducer-Syntax für String-Literale

Bei Bedarf kann ein String-Literal einem Zeichensatznamen vorangestellt werden, dem ein Unterstrich „_“ vorangestellt ist. Dies wird als Introducer-Syntax bezeichnet. Sein Ziel ist es, die Engine darüber zu informieren, wie man den eingehenden String interpretiert und speichert.

Beispiel

INSERT INTO People
VALUES (_ISO8859_1 'Hans-Jörg Schäfer')
            

Zahlenkonstanten

Eine Zahlkonstante ist eine gültige Zahl in einer unterstützten Notation:

  • In SQL wird der Dezimalpunkt, für Zahlen in der Standard-Dezimal-Notation, immer durch das Punkt-Zeichen dargestellt. Tausender werden nicht getrennt. Einbeziehung von Komma, Leerzeichen usw. führt zu Fehlern.
  • Exponentielle Notation wird unterstützt. Zum Beispiel kann 0.0000234 auch als 2.34e-5 geschrieben werden.
  • Hexadezimal-Notation wird von Firebird 2.5 und höheren Versionen unterstützt—siehe unten.

Hexadezimale Notation für Ziffern

Von Firebird 2.5 aufwärts können ganzzahlige Werte in hexadezimaler Notation eingegeben werden. Zahlen mit 1-8 Hex-Ziffern werden als Typ INTEGER interpretiert; Zahlen mit 9-16 Hex-Ziffern als Typ BIGINT.

Syntax: 

0{x|X}<hexdigits>

  <hexdigits>  ::=  1-16 als <hexdigit>
  <hexdigit>   ::=  eins aus 0..9, A..F, a..f
            

Beispiele: 

select 0x6FAA0D3 from rdb$database           -- liefert 117088467
select 0x4F9 from rdb$database               -- liefert 1273
select 0x6E44F9A8 from rdb$database          -- liefert 1850014120
select 0x9E44F9A8 from rdb$database          -- liefert -1639646808 (an INTEGER)
select 0x09E44F9A8 from rdb$database         -- liefert 2655320488 (a BIGINT)
select 0x28ED678A4C987 from rdb$database     -- liefert 720001751632263
select 0xFFFFFFFFFFFFFFFF from rdb$database  -- liefert -1
            

Hexadezimale Wertebereiche
  • Hex-Nummern im Bereich 0 .. 7FFF FFFF sind positive INTEGER mit Dezimalwerten zwischen 0 .. 2147483647. Um eine Zahl als BIGINT zu erzwingen, müssen Sie genügend Nullen voranstellen, um die Gesamtzahl der Hex-Ziffern auf neun oder mehr zu bringen. Das ändert den Typ, aber nicht den Wert.
  • Hex-Nummern zwischen 8000 0000 .. FFFF FFFF erfordern etwas Aufmerksamkeit:

    • Bei der Eingabe mit acht Hex-Ziffern, wie in 0x9E44F9A8, wird ein Wert als 32-Bit-INTEGER interpretiert. Da das erste Bit (Vorzeichenbit) gesetzt ist, wird es dem negativen Dezimalbereich -2147483648 .. -1 zugeordnet.
    • Bei einer oder mehreren Nullen, die wie in 0x09E44F9A8 vorangestellt werden, wird ein Wert als 64-Bit-BIGINT im Bereich 0000 0000 8000 0000 .. 0000 0000 FFFF FFFF interpretiert. Das Zeichen-Bit ist jetzt nicht gesetzt, also wird der Dezimalwert dem positiven Bereich 2147483648 .. 4294967295 zugewiesen.

    So ergibt sich in diesem Bereich - und nur in diesem Bereich - anhand einer mathematisch unbedeutenden 0 ein gänzlich anderer Wert. Dies ist zu beachten.

  • Hex-Zahlen zwischen 1 0000 0000 .. 7FFF FFFF FFFF FFFF sind alle positiv BIGINT.
  • Hex-Zahlen zwischen 8000 0000 0000 0000 .. FFFF FFFF FFFF FFFF sind alle negativ BIGINT.
  • Ein SMALLINT kann nicht in Hex geschrieben werden, streng genommen zumindest, da sogar 0x1 als INTEGER ausgewertet wird. Wenn Sie jedoch eine positive Ganzzahl innerhalb des 16-Bit-Bereichs 0x0000 (Dezimal-Null) bis 0x7FFF (Dezimalzahl 32767) schreiben, wird sie transparent in SMALLINT umgewandelt.

    Es ist möglich einen negativen SMALLINT in Hex zu schreiben, wobei eine 4-Byte-Hexadezimalzahl im Bereich 0xFFFF8000 (Dezimal -32768) bis 0xFFFFFFFF (Dezimal -1) verwendet wird.

SQL-Operatoren

SQL-Operatoren umfassen Operatoren zum Vergleichen, Berechnen, Auswerten und Verknüpfen von Werten.

Vorrang der Operatoren

SQL Operatoren sind in vier Typen unterteilt. Jeder Operator-Typ hat eine Priorität, eine Rangfolge, die die Reihenfolge bestimmt, in der die Operatoren und die mit ihrer Hilfe erhaltenen Werte in einem Ausdruck ausgewertet werden. Je höher der Vorrang des Operator-Typs ist, desto früher wird er ausgewertet. Jeder Operator hat seine eigene Priorität innerhalb seines Typs, der die Reihenfolge bestimmt, in der sie in einem Ausdruck ausgewertet werden.

Operatoren der gleichen Rangfolge werden von links nach rechts ausgewertet. Um dieses Verhalten zu beeinflussen, können Gruppen mittels Klammern erstellt werden.

Tabelle 4.2. Vorrang der Operatortypen

Operatortyp Vorrang Erläuterung
Verkettung 1 Strings werden verkettet, bevor andere Operationen stattfinden
Arithmetik 2 Arithmetische Operationen werden durchgeführt, nachdem Strings verkettet sind, aber vor Vergleichs- und logischen Operationen
Vergleiche 3 Vergleichsoperationen erfolgen nach String-Verkettung und arithmetischen Operationen, aber vor logischen Operationen
Logical 4 Logische Operatoren werden nach allen anderen Operatortypen ausgeführt


Verkettungsoperator

Der Verkettungsoperator, zwei Pipe-Zeichen, auch „Doppel-Pipe“— || — verkettet (verbindet) zwei Zeichenketten zu einer einzigen Zeichenkette. Zeichenketten können dabei Konstante Werte oder abgeleitet von einer Spalte oder einem Ausdruck sein.

Beispiel: 

       SELECT LAST_NAME || ', ' || FIRST_NAME AS FULL_NAME
       FROM EMPLOYEE
            
Arithmetische Operatoren

Tabelle 4.3. Vorrang arithmetischer Operatoren

Operator Zweick Vorrang
+ Zahl mit Vorzeichen unäres Plus 1
- Zahl mit Vorzeichen unäres Minus 1
* Multiplikation 2
/ Division 2
+ Addition 3
- Subtraktion 3


Beispiel: 

       UPDATE T
         SET A = 4 + 1/(B-C)*D
            

Anmerkung

Wenn Operatoren den gleichen Vorrang besitzen, werden diese von links nach rechts ausgewertet.

Vergleichsoperatoren

Tabelle 4.4. Prioritäten der Vergleichsoperatoren

Operator Zweck Priorität
= Ist gleich, ist identisch mit 1
<>, !=, ~=, ^= Ist ungleich zu 1
> Ist größer als 1
< Ist kleiner als 1
>= Ist größer oder gleich als 1
<= Ist kleiner oder gleich als 1
!>, ~>, ^> Ist nicht gößer als 1
!<, ~<, ^< Ist nicht kleiner als 1


Diese Gruppe enthält außerdem die Vergleichsprädikate BETWEEN, LIKE, CONTAINING, SIMILAR TO, IS und andere.

Beispiel: 

       IF (SALARY > 1400) THEN
       …
            

See also: Andere Vergleichsprädikate.

Logische Operatoren

Tabelle 4.5. Prioritäten logischer Operatoren

Operator Zweck Priorität
NOT Negierung eines Suchkriteriums 1
AND Kombiniert zwei oder mehr Prädikate, wobei jedes als wahr angesehen werden muss, damit der Gesamtausdruck ebenfalls als wahr aufgelöst wird 2
OR Kombiniert zwei oder mehr Prädikate, wobei mindestens eines als wahr angesehen werden muss, damit der Gesamtausdruck ebenfalls als wahr aufgelöst wird 3


Beispiel: 

       IF (A < B OR (A > C AND A > D) AND NOT (C = D)) THEN …
            

NEXT VALUE FOR

Verfügbar: DSQL, PSQL

NEXT VALUE FOR gibt den nächsten Wert einer Sequenz zurück. SEQUENCE ist ein SQL-konformer Begriff für Generatoren in Firebird und dessen Vorgänger, InterBase. Der Operator NEXT VALUE FOR ist equivalent zur ursprünglichen Funktion GEN_ID (..., 1) und ist die empfohlene Syntax zum Holen des nächsten Wertes.

Syntax für NEXT VALUE FOR: 

       NEXT VALUE FOR Sequenzname
          

Beispiel: 

       NEW.CUST_ID = NEXT VALUE FOR CUSTSEQ;
          

Anmerkung

Anders als GEN_ID (..., 1) verwendet NEXT VALUE FOR keine Parameter, wodurch es nicht möglich ist den aktuellen Wert einer Sequenz zu ermitteln sowie eine andere Schrittweite als 1 zu nutzen. GEN_ID (..., <step value>) wird noch immer für diesen Zweck verwendet. Eine <Schrittweite> von 0 gibt den aktuellen Sequenzwert zurück.

Siehe auch:  SEQUENCE (GENERATOR), GEN_ID()

Bedingte Ausdrücke

Inhaltsverzeichnis

CASE

Ein bedingter Ausdruck ist einer der verschiedene Werte zurückgibt, je nach verwendeter Bedingung. Es besteht aus einem bedingten Funktionskonstrukt, wovon Firebird mehrere unterstützt. Dieser Abschnitt beschreibt nur ein bedingtes Ausdruckskonstrukt: CASE. Alle anderen bedingten Ausdrücke sind interne Funktionen und leiten sich von CASE ab und werden in Bedingte Funktionen beschrieben.

CASE

Verfügbar:  DSQL, PSQL

Das CASE-Konstrukt gibt einen einzigen Wert aus einer Reihe von Werten zurück. Zwei syntaktische Varianten werden unterstützt:

  • Das einfache CASE, vergleichbar zu einem CASE-Konstrukt in Pascal oder einem Switch in C
  • Das gesuchte CASE, welches wie eine Reihe aus  „if ... else if ... else if“  -Klauseln funktioniert.

Einfaches CASE

Syntax: 

       …
       CASE <test-expr>
         WHEN <expr> THEN <result>
         [WHEN <expr> THEN <result> ...]
         [ELSE <defaultresult>]
       END
       …
            

Wenn diese Variante verwendet wird, wird <test-expr> mit <expr> 1, <exp> 2 etc. verglichen, bis ein Treffer gefunden und das passende Ergebnis zurückgegeben wird. Wenn kein passender Treffer vorhanden ist, wird <defaultresult> aus der optionalen ELSE-Klausel zurückgegeben, andernfalls NULL.

Der Trefferwahl funktioniert identisch zum "="-Operator. Daher gilt, wenn <test-expr> gleich NULL ist, wird kein Treffer für <expr> ermittelt, nicht einmal wenn dieser zu NULL aufgelöst wird.

Das zurückgegebene Ergebnis muss kein literaler Wert sein: Es kann ein Feld oder ein Variablenname, ein Ausdruck oder NULL-Literal sein.

Beispiel: 

       SELECT
         NAME,
         AGE,
         CASE UPPER(SEX)
           WHEN 'M' THEN 'Male'
           WHEN 'F' THEN 'Female'
           ELSE 'Unknown'
         END GENDER,
	RELIGION
      FROM PEOPLE
              

Eine Kurzform des einfachen CASE-Konstrukts wird auch in der DECODE -Funktion verwendet.

Gesuchtes CASE

Syntax: 

       CASE
         WHEN <bool_expr> THEN <result>
         [WHEN <bool_expr> THEN <result> …]
         [ELSE <defaultresult>]
         END
            

Der <bool_expr>-Ausdruck gibt ein ternäres logisches Ergebnis zurück: TRUE, FALSE oder NULL. Der erste Ausdruck, der TRUE ermittelt, wird als Ergebnis verwendet. Gibt kein Ausdruck TRUE zurück, kommt <defaultresult> aus der optionalen ELSE-Klausel zum Einsatz. Gibt kein Ausdruck TRUE zurück und gibt es keine ELSE-Klausel, ist der Rückgabewert NULL.

So wie im einfachen CASE-Konstrukt, muss das Ergebnis nicht zwangsläufig ein Literal sein: es kann ein Feld- oder Variablenname, ein zusammengesetzter Ausdruck oder NULL sein.

Beispiel: 

       CANVOTE = CASE
         WHEN AGE >= 18 THEN 'Yes'
         WHEN AGE < 18 THEN 'No'
         ELSE 'Unsure'
         END
            

NULL in Ausdrücken

NULL kein Wert in SQL, sondern ein Status der anzeigt, dass der Wert des Elements entweder unbekannt (engl. unknown) ist oder nicht existiert. Es ist weder null, noch void, noch ein „leerer String“, und es verhält sich auch nicht wie ein anderer Wert.

Wenn Sie NULL in numerischen, String- oder Datums/Zeit-Ausdrücken verwenden, wird das Ergebnis immer NULL sein. Verwenden Sie NULL in logischen (Boolean) Ausdrücken, hängt das Ergebnis von der Art der Operation ab und anderen partizipierenden Werten. Wenn Sie einen Wert mit NULL vergleichen, wird das Ergebnis unknown sein.

Zu beachten

NULL heißt NULL, jedoch gilt in Firebird, dass das logische Ergebnis unknown ebenfalls durch NULL repräsentiert wird.

Ausdrücke die NULL zurückgeben

Ausdrücke in dieser Liste werden immer NULL zurückgeben:

       1 + 2 + 3 + NULL
       'Home ' || 'sweet ' || NULL
       MyField = NULL
       MyField <> NULL
       NULL = NULL
       not (NULL)
          

Wenn es Ihnen schwerfällt dies zu verstehen, beachten Sie, dass NULL ein Status ist, der für „unknown“ (unbekannt) steht.

NULL in logischen Ausdrücken

Es wurde bereits gezeigt, dass not (NULL) in NULL aufgeht. Dieser Effekt ist etwas komplizierter für logische AND- sowie logische OR-Operatoren:

       NULL or false = NULL
       NULL or true = true
       NULL or NULL = NULL
       NULL and false = false
       NULL and true = NULL
       NULL and NULL = NULL
          

Bis einschließlich Firebird 2.5.x existiert keine Implementierung für logische (Boolean) Datentypen—diese gibt es erst seit Firebird 3. Jedoch gibt es logische Ausdrücke (Prädikate), die true, false oder unknown zurückgeben können.

Beispiele: 

       (1 = NULL) or (1 <> 1) -- liefert NULL
       (1 = NULL) or (1 = 1) -- liefert TRUE
       (1 = NULL) or (1 = NULL) -- liefert NULL
       (1 = NULL) and (1 <> 1) -- liefert FALSE
       (1 = NULL) and (1 = 1) -- liefert NULL
       (1 = NULL) and (1 = NULL) -- liefert NULL
            

Unterabfragen

Eine Unterabfrage ist eine spezielle Form eines Ausdrucks, die innerhalb einer anderen Abfrage eingebettet wird. Unterabfragen werden in der gleichen Weise geschrieben wie reguläre SELECT-Abfragen, werden jedoch von Klammern umschlossen. Unterabfrage-Ausdrücke können in folgender Art und Weise verwendet werden:

  • Um eine Ausgabespalte in der SELECT-Liste anzugeben
  • Um Werte zu holen oder als Kriterium für Suchprädikate (die WHERE- und HAVING-Klauseln)
  • Um ein Set zu erstellen, das die Eltern-Abfrage verwenden kann, so als wäre dies eine reguläre Tabelle oder View. Unterabfragen wie diese erscheinen in der FROM-Klausel (Derived Tables) oder in einer Common Table Expression (CTE)

Korrelierte Unterabfragen

Eine Unterabfrage kann korrelierend sein. Sie ist korellierend, wenn die Hauptafrage und die Unterabfrage voneinander abhängig sind. Um einen Datensatz in der Unterabfrage zu verarbeiten, ist es notwendig einen Datensatz in der Hauptabfrage zu holen; beispielsweise hängt die Unterabfrage vollständig von der Hauptabfrage ab.

Beispiel einer korrelierenden Unterabfrage: 

       SELECT *
       FROM Customers C
       WHERE EXISTS
             (SELECT *
              FROM Orders O
              WHERE C.cnum = O.cnum
                AND O.adate = DATE '10.03.1990');
          

Werden Unterabfragen verwendet um Werte einer Ausgabespalte aus einer SELECT-Liste zu holen, muss die Unterabfrage ein skalares Ergebnis zurückliefern.

Skalare Ergebnisse

Unterabfragen, die in Suchprädikaten verwendet werden, mit Ausnahme von existenziellen und quantifizierten Prädikaten, müssen ein skalares Ergebnis zurückgeben; Das heißt, nicht mehr als eine Spalte von nicht mehr als einer passenden Zeile oder Aggregation. Sollte mehr zurückgegeben werden, wird es zu einem Laufzeitfehler kommen („Multiple rows in a singleton select...“).

Anmerkung

Obwohl es einen echten Fehler berichtet, kann die Nachricht etwas irreführend sein. Ein „singleton SELECT“ ist eine Abfrage, die nicht mehr als eine Zeile zurückgeben kann. Jedoch sind „singleton“ und „skalar“ nicht gleichzusetzen: nicht alle singleton SELECTs müssen zwangsläufig skalar sein; und Einspalten-SELECTs können mehrere Zeilen für existenzielle und quantifizierte Prädikate zurückgeben.

Unterabfrage-Beispiele: 

  1. Eine Unterabfrage als Ausgabespalte in einer SELECT-Liste:
           SELECT
               e.first_name,
               e.last_name,
               (SELECT
                    sh.new_salary
                FROM
                    salary_history sh
                WHERE
                    sh.emp_no = e.emp_no
                ORDER BY sh.change_date DESC ROWS 1) AS last_salary
           FROM
                employee e
                  
  2. eine Unterabfrage in der WHERE-Klausel, um das höchste Gehalt eines Mitarbeiters zu ermitteln und hierauf zu filtern:
           SELECT
               e.first_name,
               e.last_name,
               e.salary
           FROM
               employee e
           WHERE
               e.salary = (
                           SELECT MAX(ie.salary)
                           FROM employee ie
                           )
                  
Zurück: Allgemeine SprachelementeFirebird Documentation IndexNach oben: Allgemeine SprachelementeWeiter: Prädikate
Firebird Documentation IndexFirebird 2.5 SprachreferenzAllgemeine Sprachelemente → Ausdrücke