SQL_NULL
-Datentyp
Der Typ SQL_NULL
enthält keine Daten, sondern nur einen Zustand: NULL
oder NOT NULL
.Als Datentyp zum Deklarieren von Tabellenfeldern, PSQL-Variablen oder Parameterbeschreibungen steht er nicht zur Verfügung.Es wurde hinzugefügt, um die Verwendung nicht typisierter Parameter in Ausdrücken zu unterstützen, die das Prädikat IS NULL
beinhalten.
Ein Auswertungsproblem tritt auf, wenn optionale Filter verwendet werden, um Abfragen des folgenden Typs zu schreiben:
WHERE col1 = :param1 OR :param1 IS NULL
Nach der Verarbeitung auf API-Ebene sieht die Abfrage wie folgt aus:
WHERE col1 = ? OR ? IS NULL
Dies ist ein Fall, in dem der Entwickler eine SQL-Abfrage schreibt und :param1
als eine Variable betrachtet, auf die er zweimal verweisen kann.Auf API-Ebene enthält die Abfrage jedoch zwei separate und unabhängige Parameter.Der Server kann den Typ des zweiten Parameters nicht bestimmen, da er mit IS NULL
verknüpft ist.
Der Datentyp SQL_NULL
löst dieses Problem.Immer wenn die Engine in einer Abfrage auf ein Prädikat “? IS NULL
” stößt, weist sie dem Parameter den Typ SQL_NULL
zu, was anzeigt, dass es sich bei dem Parameter nur um “Nulligkeit” und den Datentyp handelt oder der Wert muss nicht angesprochen werden.
Das folgende Beispiel zeigt die Anwendung in der Praxis.Es nimmt zwei benannte Parameter an — sagen wir :size
und :colour
— die zum Beispiel Werte aus Bildschirmtextfeldern oder Dropdown-Listen erhalten können.Jeder benannte Parameter entspricht zwei Positionsparametern in der Abfrage.
SELECT
SH.SIZE, SH.COLOUR, SH.PRICE
FROM SHIRTS SH
WHERE (SH.SIZE = ? OR ? IS NULL)
AND (SH.COLOUR = ? OR ? IS NULL)
Um zu erklären, was hier passiert, wird davon ausgegangen, dass der Leser mit der Firebird-API und der Übergabe von Parametern in XSQLVAR-Strukturen vertraut ist — was unter der Oberfläche passiert, ist für diejenigen nicht von Interesse, die keine Treiber oder Anwendungen schreiben, die mit der "nakten" API kommunizieren.
Die Anwendung übergibt die parametrisierte Anfrage an den Server in der üblichen positionellen ?
-Form.Paare von “identischen” Parametern können nicht zu einem zusammengeführt werden, daher werden beispielsweise für zwei optionale Filter vier Positionsparameter benötigt: einer für jedes ?
in unserem Beispiel.
Nach dem Aufruf von isc_dsql_describe_bind()
wird der SQLTYPE des zweiten und vierten Parameters auf SQL_NULL
gesetzt.Firebird hat keine Kenntnis von ihrer speziellen Beziehung zum ersten und dritten Parameter: Diese Verantwortung liegt vollständig auf der Anwendungsseite.
Nachdem die Werte für Größe und Farbe vom Benutzer festgelegt (oder nicht festgelegt) wurden und die Abfrage ausgeführt werden soll, muss jedes Paar von `XSQLVAR`s
wie folgt gefüllt werden:
- Der Benutzer hat einen Wert angegeben
-
Erster Parameter (Wertvergleich): setze
*sqldata
auf den angegebenen Wert und*sqlind
auf0
(fürNOT NULL
)Zweiter Parameter (
NULL
Test): setzesqldata
aufnull
(Nullzeiger, nicht SQLNULL
) und*sqlind
auf0
(fürNOT NULL
) - Der Benutzer hat das Feld leer gelassen
-
Beide Parameter: setze
sqldata
aufnull
(Nullzeiger, nicht SQLNULL
) und*sqlind
auf-1
(zeigtNULL
)
Mit anderen Worten: Der Parameter Wertvergleich wird immer wie gewohnt gesetzt.Der Parameter SQL_NULL
wird gleich gesetzt, außer dass sqldata
immer null
bleibt.