Spezielle Datentypen
“Spezielle” Datentypen …
Datentypen für Datum und Uhrzeit
“Spezielle” Datentypen …
SQL_NULL
-DatentypDer 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:
Erster Parameter (Wertvergleich): setze *sqldata
auf den angegebenen Wert und *sqlind
auf 0
(für NOT NULL
)
Zweiter Parameter (NULL
Test): setze sqldata
auf null
(Nullzeiger, nicht SQL NULL
) und *sqlind
auf 0
(für NOT NULL
)
Beide Parameter: setze sqldata
auf null
(Nullzeiger, nicht SQL NULL
) und *sqlind
auf -1
(zeigt NULL
)
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.
Beim Verfassen eines Ausdrucks oder der Angabe einer Operation sollte das Ziel sein, kompatible Datentypen für die Operanden zu verwenden.Wenn eine Mischung von Datentypen verwendet werden muss, sollten Sie nach einer Möglichkeit suchen, inkompatible Operanden zu konvertieren, bevor Sie sie der Operation unterziehen.Die Möglichkeit, Daten zu konvertieren, kann durchaus ein Problem darstellen, wenn Sie mit Dialekt-1-Daten arbeiten.
Die CAST
-Funktion ermöglicht die explizite Konvertierung zwischen vielen Paaren von Datentypen.
CAST (<expression> AS <target_type>) <target_type> ::= <domain_or_non_array_type> | <array_datatype> <domain_or_non_array_type> ::= !! Vgl. Syntax für Scalardatentypen !! <array_datatype> ::= !! Vgl. Syntax für Array-Datentypen !!
Siehe auch CAST()
im Abschnitt Eingebaute Skalarfunktionen.
Beim Casting in eine Domäne werden alle dafür deklarierten Constraints berücksichtigt, d. h. NOT NULL
- oder CHECK
-Constraints.Wenn der Wert die Prüfung nicht besteht, schlägt die Umwandlung fehl.
Wenn zusätzlich TYPE OF
angegeben wird — Umwandlung in seinen Basistyp — werden alle Domäneneinschränkungen während der Umwandlung ignoriert.Wird TYPE OF
mit einem Zeichentyp (CHAR/VARCHAR
) verwendet, bleiben Zeichensatz und Kollatierung erhalten.
Spaltentyp
Wenn Operanden in den Typ einer Spalte umgewandelt werden, kann die angegebene Spalte aus einer Tabelle oder einer Sicht stammen.
Es wird nur der Typ der Spalte selbst verwendet.Bei Zeichentypen enthält die Besetzung den Zeichensatz, aber nicht die Sortierung.Die Einschränkungen und Standardwerte der Quellspalte werden nicht angewendet.
CREATE TABLE TTT (
S VARCHAR (40)
CHARACTER SET UTF8 COLLATE UNICODE_CI_AI
);
COMMIT;
SELECT
CAST ('I have many friends' AS TYPE OF COLUMN TTT.S)
FROM RDB$DATABASE;
CAST
-Funktion möglichVon Datentyp | Zu Datentyp |
---|---|
Numerische Typen |
Numerische Typen, |
|
|
|
|
|
|
|
|
|
|
Um String-Datentypen in den Typ BOOLEAN
zu konvertieren, muss der Wert (ohne Berücksichtigung der Groß-/Kleinschreibung) 'true'
oder 'false'
oder NULL
sein.
Important
|
Beachten Sie, dass ein teilweiser Informationsverlust möglich ist.Wenn Sie beispielsweise den Datentyp |
Um String-Datentypen in die Datentypen DATE
, TIME
oder TIMESTAMP
umzuwandeln, muss das String-Argument eines der vordefinierten Datums- und Uhrzeitliterale sein (siehe [fblangref40-dtyp-tbl-datetimemnemonics-de]) oder eine Darstellung des Datums in einem der zulässigen Datum-Uhrzeit-Literal-Formate (siehe Datumzeit-Format-Syntax),
Literal |
Beschreibung |
---|---|
|
Aktuelle Zeit und Datum |
|
Aktuelles Datum |
|
Aktuelles Datum + 1 (Tag) |
|
Aktuelles Datum - 1 (Tag) |
Note
|
Das Umwandeln der Datumsmnemonik Zum Beispiel erzeugt |
select
cast('04.12.2014' as date) as d1, -- DD.MM.YYYY
cast('04 12 2014' as date) as d2, -- MM DD YYYY
cast('4-12-2014' as date) as d3, -- MM-DD-YYYY
cast('04/12/2014' as date) as d4, -- MM/DD/YYYY
cast('04.12.14' as date) as d5, -- DD.MM.YY
-- DD.MM with current year
cast('04.12' as date) as d6,
-- MM/DD with current year
cast('04/12' as date) as d7,
cast('2014/12/04' as date) as d8, -- YYYY/MM/DD
cast('2014 12 04' as date) as d9, -- YYYY MM DD
cast('2014.12.04' as date) as d10, -- YYYY.MM.DD
cast('2014-12-04' as date) as d11, -- YYYY-MM-DD
cast('4 Jan 2014' as date) as d12, -- DD MM YYYY
cast('2014 Jan 4' as date) as dt13, -- YYYY MM DD
cast('Jan 4 2014' as date) as dt14, -- MM DD YYYY
cast('11:37' as time) as t1, -- HH:mm
cast('11:37:12' as time) as t2, -- HH:mm:ss
cast('11:31:12.1234' as time) as t3, -- HH:mm:ss.nnnn
-- DD.MM.YYYY HH:mm
cast('04.12.2014 11:37' as timestamp) as dt1,
-- MM/DD/YYYY HH:mm:ss
cast('04/12/2014 11:37:12' as timestamp) as dt2,
-- DD.MM.YYYY HH:mm:ss.nnnn
cast('04.12.2014 11:31:12.1234' as timestamp) as dt3,
cast('now' as timestamp) as m1,
cast('today' as date) as m2,
cast('yesterday' as date) as m3,
cast('tomorrow' as date) as m4
from rdb$database
Firebird erlaubt die Verwendung einer abgekürzten Typsyntax im C-Stil
für Umwandlungen von Strings in die Typen "DATE", "TIME" und "TIMESTAMP".Der SQL-Standard ruft diese Datetime-Literale auf.
<data_type> 'date_format_string'
Siehe auch Datums- und Zeitliterale.
Note
|
Diese Literalausdrücke werden beim Parsen direkt ausgewertet, als ob die Anweisung bereits für die Ausführung vorbereitet wäre.Da dies bei der Verwendung von Datetime-Mnemoniken wie Um Datetime-Mnemonik zu verwenden, verwenden Sie die vollständige
|
Eine implizite Datenkonvertierung ist in Dialekt 3 nicht möglich — die CAST
-Funktion wird fast immer benötigt, um Datentypkonflikte zu vermeiden.
In Dialekt 1 wird in vielen Ausdrücken ein Typ implizit in einen anderen umgewandelt, ohne dass die CAST-Funktion verwendet werden muss.Zum Beispiel gilt die folgende Aussage in Dialekt 1:
UPDATE ATABLE
SET ADATE = '25.12.2016' + 1
Das Datumsliteral wird implizit in den Datumstyp umgewandelt.
In Dialekt 3 wird diese Anweisung den Fehler 35544569 ausgeben, “`Dynamic SQL Error: expression evaluation not supported, Strings cannot be added or subtracted in dialect 3” — eine Umwandlung ist erforderlich:
UPDATE ATABLE
SET ADATE = CAST ('25.12.2016' AS DATE) + 1
Oder mit einem Datetime-Literal:
UPDATE ATABLE
SET ADATE = DATE '25.12.2016' + 1
In Dialekt 1 ist es normalerweise möglich, ganzzahlige Daten und numerische Zeichenfolgen zu mischen, da der Parser versucht, die Zeichenfolge implizit umzuwandeln.Beispielsweise,
2 + '1'
wird korrekt ausgeführt.
In Dialekt 3 führt ein solcher Ausdruck zu einem Fehler, daher müssen Sie ihn als CAST
-Ausdruck schreiben:
2 + CAST('1' AS SMALLINT)
Die Ausnahme von der Regel ist während der String-Verkettung.
Wenn mehrere Datenelemente verkettet werden, werden alle Nicht-String-Daten nach Möglichkeit implizit in Strings umgewandelt.
SELECT 30||' days hath September, April, June and November' CONCAT$
FROM RDB$DATABASE;
CONCAT$
------------------------------------------------
30 days hath September, April, June and November