Virtuelle Tabelle RDB$TIME_ZONES
Eine virtuelle Tabelle, die die von der Engine unterstützten Zeitzonen auflistet.
Siehe auch RDB$TIME_ZONES
in Systemtabellen.
Datentypen für Datum und Uhrzeit
RDB$TIME_ZONES
Eine virtuelle Tabelle, die die von der Engine unterstützten Zeitzonen auflistet.
Siehe auch RDB$TIME_ZONES
in Systemtabellen.
RDB$TIME_ZONE_UTIL
Ein Paket von Zeitzonen-Dienstprogrammfunktionen und -prozeduren:
DATABASE_VERSION
RDB$TIME_ZONE_UTIL.DATABASE_VERSION
gibt die Version der Zeitzonendatenbank als VARCHAR(10) CHARACTER SET ASCII
zurück.
select rdb$time_zone_util.database_version() from rdb$database;
Returns:
DATABASE_VERSION
================
2021a
RDB$TIME_ZONE_UTIL.TRANSITIONS
gibt den Regelsatz zwischen den Start- und Endzeitstempeln für eine benannte Zeitzone zurück.
Die Eingabeparameter sind:
RDB$TIME_ZONE_NAME
Typ CHAR(63)
RDB$FROM_TIMESTAMP
Typ TIMESTAMP WITH TIME ZONE
RDB$TO_TIMESTAMP
Typ TIMESTAMP WITH TIME ZONE
Ausgabeparameter:
RDB$START_TIMESTAMP
Typ TIMESTAMP WITH TIME ZONE
— Der Startzeitstempel des Übergangs
RDB$END_TIMESTAMP
Typ TIMESTAMP WITH TIME ZONE
— Der Endzeitstempel des Übergangs
RDB$ZONE_OFFSET
Typ SMALLINT
— Der Offset der Zone in Minuten
RDB$DST_OFFSET
Typ SMALLINT
— Der DST-Offset der Zone in Minuten
RDB$EFFECTIVE_OFFSET
Typ SMALLINT
— Effektiver Offset (ZONE_OFFSET
+ DST_OFFSET
)
select *
from rdb$time_zone_util.transitions(
'America/Sao_Paulo',
timestamp '2017-01-01',
timestamp '2019-01-01');
Rückgabe (das Präfix RDB$
wurde der Kürze halber weggelassen):
START_TIMESTAMP END_TIMESTAMP ZONE_OFFSET DST_OFFSET EFFECTIVE_OFFSET ============================ ============================ =========== ========== ================ 2016-10-16 03:00:00.0000 GMT 2017-02-19 01:59:59.9999 GMT -180 60 -120 2017-02-19 02:00:00.0000 GMT 2017-10-15 02:59:59.9999 GMT -180 0 -180 2017-10-15 03:00:00.0000 GMT 2018-02-18 01:59:59.9999 GMT -180 60 -120 2018-02-18 02:00:00.0000 GMT 2018-10-21 02:59:59.9999 GMT -180 0 -180 2018-10-21 03:00:00.0000 GMT 2019-02-17 01:59:59.9999 GMT -180 60 -120
Zeitzonen werden oft geändert: Wenn es passiert, ist es natürlich wünschenswert, die Zeitzonendatenbank so schnell wie möglich zu aktualisieren.
Firebird speichert WITH TIME ZONE
-Werte, die in die UTC-Zeit übersetzt wurden.Angenommen, ein Wert wird mit einer Zeitzonendatenbank erstellt und eine spätere Aktualisierung dieser Datenbank ändert die Informationen im Bereich unseres gespeicherten Werts.Wenn dieser Wert gelesen wird, wird er anders als der ursprünglich gespeicherte Wert zurückgegeben.
Firebird verwendet die IANA time zone database über die ICU-Bibliothek.Die im Firebird-Kit (Windows) enthaltene oder in einem POSIX-Betriebssystem installierte ICU-Bibliothek kann manchmal eine veraltete Zeitzonendatenbank aufweisen.
Eine aktualisierte Datenbank finden Sie auf diese Seite auf dem FirebirdSQL GitHub.Der Dateiname le.zip
steht für Little-Endian und ist die notwendige Datei für die meisten Computerarchitekturen (Intel/AMD-kompatibel x86 oder x64), während be.zip
für Big-Endian-Architekturen steht und meistens für RISC-Computerarchitekturen benötigt wird .Der Inhalt der ZIP-Datei muss in das Unterverzeichnis /tzdata
der Firebird-Installation entpackt werden, wobei vorhandene *.res
-Dateien der Datenbank überschrieben werden.
Note
|
|
Für die Arbeit mit Zeichendaten hat Firebird die Datentypen CHAR
mit fester Länge und VARCHAR
mit variabler Länge.Die maximale Größe der in diesen Datentypen gespeicherten Textdaten beträgt 32.767 Byte für 'CHAR' und 32.765 Byte für 'VARCHAR'.Die maximale Anzahl von Zeichen, die in diese Grenzen passt, hängt davon ab, welches CHARACTER SET
für die betrachteten Daten verwendet wird.Die Sortierreihenfolge hat keinen Einfluss auf dieses Maximum, kann sich jedoch auf die maximale Größe eines Index auswirken, der die Spalte umfasst.
Wenn beim Definieren eines Zeichenobjekts kein Zeichensatz explizit angegeben wird, wird der beim Erstellen der Datenbank angegebene Standardzeichensatz verwendet.Wenn in der Datenbank kein Standardzeichensatz definiert ist, erhält das Feld den Zeichensatz NONE
.
Die meisten aktuellen Entwicklungstools unterstützen Unicode, implementiert in Firebird mit den Zeichensätzen UTF8
und UNICODE_FSS
. UTF8
enthält Kollationen für viele Sprachen.UNICODE_FSS
ist eingeschränkter und wird hauptsächlich von Firebird intern zum Speichern von Metadaten verwendet.Beachten Sie, dass ein UTF8
-Zeichen bis zu 4 Byte belegt, wodurch die Größe von CHAR
-Feldern auf 8.191 Zeichen (32.767/4) begrenzt ist.
Note
|
Der tatsächliche Wert von “Bytes pro Zeichen” hängt vom Bereich ab, zu dem das Zeichen gehört.Lateinische Buchstaben ohne Akzent belegen 1 Byte, kyrillische Buchstaben der Codierung |
Der in Firebird implementierte UTF8
-Zeichensatz unterstützt die neueste Version des Unicode-Standards und empfiehlt daher seine Verwendung für internationale Datenbanken.
Bei der Arbeit mit Strings ist es wichtig, den Zeichensatz der Client-Verbindung im Auge zu behalten.Wenn die Zeichensätze der gespeicherten Daten nicht mit denen der Client-Verbindung übereinstimmen, werden die Ausgabeergebnisse für String-Spalten automatisch neu codiert, sowohl beim Senden der Daten vom Client an den Server als auch beim Zurücksenden von der Server an den Client.Wenn die Datenbank beispielsweise in der Codierung WIN1251
erstellt wurde, aber KOI8R
oder UTF8
in den Verbindungsparametern des Clients angegeben ist, ist die Abweichung transparent.
NONE
Der Zeichensatz NONE
ist ein Sonderzeichensatz in Firebird.Es kann so charakterisiert werden, dass jedes Byte Teil einer Zeichenkette ist, die Zeichenkette jedoch im System ohne Hinweise darauf gespeichert wird, was ein Zeichen darstellt: Zeichencodierung, Sortierung, Groß-/Kleinschreibung usw. sind einfach unbekannt.Es liegt in der Verantwortung der Clientanwendung, mit den Daten umzugehen und die Mittel bereitzustellen, um die Bytefolge auf eine für die Anwendung und den menschlichen Benutzer sinnvolle Weise zu interpretieren.
OCTETS
Daten in der OCTETS
-Kodierung werden als Bytes behandelt, die möglicherweise nicht wirklich als Zeichen interpretiert werden.OCTETS
bietet eine Möglichkeit, Binärdaten zu speichern, die das Ergebnis einiger Firebird-Funktionen sein können.Die Datenbank-Engine hat keine Vorstellung davon, was sie mit einer Bitfolge in OCTETS
tun soll, außer sie nur zu speichern und abzurufen.Auch hier ist die Clientseite dafür verantwortlich, die Daten zu validieren, sie in für die Anwendung und ihre Benutzer sinnvollen Formaten darzustellen und alle Ausnahmen zu behandeln, die sich aus der Decodierung und Codierung ergeben.Seit Firebird 4.0 haben CHAR
und VARCHAR
mit dem Zeichensatz OCTETS
die Synonyme BINARY
und VARBINARY
.
Jeder Zeichensatz hat eine Standardkollatierungssequenz (COLLATE
), die die Sortierreihenfolge angibt.Normalerweise ist dies nichts anderes als eine Sortierung basierend auf dem numerischen Code der Zeichen und eine grundlegende Zuordnung von Groß- und Kleinbuchstaben.Wenn für Strings ein Verhalten erforderlich ist, das nicht von der Standardsortierreihenfolge bereitgestellt wird, und eine geeignete alternative Kallation für diesen Zeichensatz unterstützt wird, kann eine COLLATE
-Klausel in der Spaltendefinition angegeben werden.collation
Eine COLLATE collation
-Klausel kann neben der Spaltendefinition auch in anderen Kontexten angewendet werden.Für Größer-als/Kleiner-Vergleichsoperationen kann es in der WHERE
-Klausel einer SELECT
-Anweisung hinzugefügt werden.Wenn die Ausgabe in einer speziellen alphabetischen Reihenfolge oder ohne Beachtung der Groß-/Kleinschreibung sortiert werden muss und die entsprechende Sortierung vorhanden ist, kann eine COLLATE
-Klausel in die ORDER BY
-Klausel eingefügt werden, wenn Zeilen nach einem Zeichenfeld sortiert werden und mit die GROUP BY
-Klausel bei Gruppierungsoperationen.
Für eine Suche ohne Beachtung der Groß-/Kleinschreibung könnte die Funktion UPPER
verwendet werden, um sowohl das Suchargument als auch die gesuchten Zeichenfolgen in Großbuchstaben umzuwandeln, bevor eine Übereinstimmung versucht wird:
…
where upper(name) = upper(:flt_name)
Bei Zeichenfolgen in einem Zeichensatz, der eine Sortierung ohne Beachtung der Groß-/Kleinschreibung zur Verfügung hat, können Sie einfach die Sortierung anwenden, um das Suchargument und die gesuchten Zeichenfolgen direkt zu vergleichen.Wenn Sie beispielsweise den Zeichensatz WIN1251
verwenden, ist die Sortierung PXW_CYRL
zu diesem Zweck unabhängig von der Groß-/Kleinschreibung:
…
WHERE FIRST_NAME COLLATE PXW_CYRL >= :FLT_NAME
…
ORDER BY NAME COLLATE PXW_CYRL
UTF8
-SortierreihenfolgenDie folgende Tabelle zeigt die möglichen Sortierfolgen für den Zeichensatz UTF8
.
Kollation | Eigenschaften |
---|---|
|
Die Sortierung funktioniert nach der Position des Zeichens in der Tabelle (binär).In Firebird 2.0 hinzugefügt |
|
Die Sortierung funktioniert nach dem UCA-Algorithmus (Unicode Collation Algorithm) (alphabetisch).In Firebird 2.0 hinzugefügt |
|
Die standardmäßige, binäre Sortierung, identisch mit |
|
Sortierung ohne Berücksichtigung der Groß-/Kleinschreibung, funktioniert ohne Berücksichtigung der Groß-/Kleinschreibung.Hinzugefügt in Firebird 2.1 |
|
Groß-/Kleinschreibung, akzentunabhängige Sortierung, arbeitet alphabetisch ohne Berücksichtigung von Groß-/Kleinschreibung oder Akzenten.Hinzugefügt in Firebird 2.5 |
Ein Beispiel für die Sortierung für den UTF8-Zeichensatz ohne Berücksichtigung der Groß-/Kleinschreibung oder der Akzentuierung von Zeichen (ähnlich wie COLLATE PXW_CYRL
).
...
ORDER BY NAME COLLATE UNICODE_CI_AI
In Firebird vor Version 2.0 kann ein Problem beim Erstellen eines Indexes für Zeichenspalten auftreten, die eine nicht standardmäßige Kollatierungssequenz verwenden: Die Länge eines indizierten Felds ist auf 252 Byte begrenzt, wenn COLLATE
nicht angegeben ist, oder 84 Byte, wenn `COLLATE ` ist angegeben.Multi-Byte-Zeichensätze und zusammengesetzte Indizes begrenzen die Größe noch weiter.
Ab Firebird 2.0 beträgt die maximale Länge für einen Index ein Viertel der Seitengröße, d. h. von 1.024 — für die Seitengröße 4.096 — bis 8.192 Bytes — für die Seitengröße 32.768.Die maximale Länge einer indizierten Zeichenfolge beträgt 9 Byte weniger als diese Viertelseitenbegrenzung.
Die folgende Formel berechnet die maximale Länge einer indizierten Zeichenfolge (in Zeichen):
max_char_length = FLOOR((page_size / 4 - 9) / N)
wobei N die Anzahl der Bytes pro Zeichen im Zeichensatz ist.
Die folgende Tabelle zeigt die maximale Länge einer indizierten Zeichenfolge (in Zeichen), je nach Seitengröße und Zeichensatz, berechnet mit dieser Formel.
Seitengröße |
Bytes je Zeichen |
||||
---|---|---|---|---|---|
1 |
2 |
3 |
4 |
6 |
|
4.096 |
1.015 |
507 |
338 |
253 |
169 |
8.192 |
2.039 |
1.019 |
679 |
509 |
339 |
16.384 |
4.087 |
2.043 |
1.362 |
1.021 |
681 |
32,768 |
8,183 |
4,091 |
2,727 |
2,045 |
1,363 |
Note
|
Bei Sortierungen, bei denen die Groß-/Kleinschreibung nicht beachtet wird (“_CI”), belegt ein Zeichen im index nicht 4, sondern 6 (sechs) Bytes, sodass die maximale Schlüssellänge für eine Seite von z 169 Zeichen. |
CREATE DATABASE
, Sortierreihenfolge, SELECT
, WHERE
, GROUP BY
, ORDER BY
BINARY
BINARY [(length)]
Parameter | Beschreibung |
---|---|
length |
Länge in Byte zwischen 1 und 32.767;standardmäßig |
BINARY
ist ein Datentyp fester Länge und ist ein SQL-Standard-kompatibler Alias für CHAR(length) CHARACTER SET OCTETS
.Werte, die kürzer als die angegebene Länge sind, werden bis zur angegebenen Länge mit NULL aufgefüllt.
Note
|
Einige Tools melden den Typ möglicherweise als |
CHAR
{CHAR | CHARACTER} [(length)] [CHARACTER SET <set>] [COLLATE <name>]
Parameter | Beschreibung |
---|---|
length |
Länge in Zeichen, standardmäßig '1'.Eine gültige Länge reicht von 1 bis zur maximalen Anzahl von Zeichen, die innerhalb von 32.767 Bytes untergebracht werden können. |
set |
Zeichensatzname |
name |
Kollationsname der Sortierreihenfolge |
CHAR
ist ein Datentyp mit fester Länge.Werte, die kürzer als die angegebene Länge sind, werden bis zur angegebenen Länge mit Leerzeichen aufgefüllt.Im Allgemeinen muss das Auffüllzeichen kein Leerzeichen sein: Es hängt vom Zeichensatz ab.Das Füllzeichen für den Zeichensatz OCTETS
ist beispielsweise NUL.
Der vollständige Name dieses Datentyps ist CHARACTER
, aber es ist nicht erforderlich, vollständige Namen zu verwenden, und die Leute tun dies selten.
Zeichendaten mit fester Länge können verwendet werden, um Codes zu speichern, deren Länge Standard ist und eine bestimmte "Breite" in Verzeichnissen hat.Ein Beispiel für einen solchen Code ist ein EAN13-Barcode – 13 Zeichen, alle ausgefüllt.
Note
|
|
VARBINARY
{VARBINARY | BINARY VARYING} (length)
Parameter | Beschreibung |
---|---|
length |
Länge in Byte zwischen 1 und 32.765 |
VARBINARY
ist ein binärer Typ mit variabler Länge und ist ein SQL-Standard-kompatibler Alias für VARCHAR(length) CHARACTER SET OCTETS
.
Note
|
Einige Tools melden den Typ möglicherweise als |
VARCHAR
{VARCHAR | {CHAR | CHARACTER} VARYING} (length) [CHARACTER SET <set>] [COLLATE <name>]
Parameter | Beschreibung |
---|---|
length |
Länge in Zeichen.Eine gültige Länge reicht von 1 bis zur maximalen Anzahl von Zeichen, die innerhalb von 32.765 Bytes untergebracht werden können. |
set |
Zeichensatzname |
name |
Kollationsname der Sortierreihenfolge |
VARCHAR
ist der grundlegende Stringtyp zum Speichern von Texten variabler Länge, bis maximal 32.765 Byte.Die gespeicherte Struktur entspricht der tatsächlichen Größe der Daten plus 2 Byte, wobei die Länge der Daten aufgezeichnet wird.
Alle Zeichen, die von der Clientanwendung an die Datenbank gesendet werden, werden als aussagekräftig angesehen, einschließlich der führenden und abschließenden Leerzeichen.
Der vollständige Name dieses Typs ist CHARACTER VARYING
.Eine andere Variante des Namens wird als CHAR VARYING
geschrieben.
Note
|
|
NCHAR
{NCHAR | NATIONAL {CHAR | CHARACTER}} [(length)]
NCHAR
ist ein Zeichendatentyp fester Länge mit dem vordefinierten Zeichensatz ISO8859_1
.Ansonsten ist es dasselbe wie CHAR
.
Note
|
Wenn keine Länge length angegeben ist, wird sie mit 1 angenommen. |
Ein ähnlicher Datentyp ist für den String-Typ variabler Länge verfügbar: NATIONAL {CHAR | CHARAKTER} VERSCHIEDLICH
.
BOOLEAN
BOOLEAN
Der SQL:2008-konforme Datentyp BOOLEAN
(8 Bit) umfasst die unterschiedlichen Wahrheitswerte TRUE
und FALSE
.Sofern nicht durch eine NOT NULL
-Beschränkung verboten, unterstützt der BOOLEAN
-Datentyp auch den Wahrheitswert UNKNOWN
als Nullwert.Die Spezifikation macht keinen Unterschied zwischen dem NULL
-Wert dieses Datentyps und dem Wahrheitswert UNKNOWN
, der das Ergebnis eines SQL-Prädikats, einer Suchbedingung oder eines booleschen Wertausdrucks ist: Sie sind austauschbar und bedeuten das gleiche.
Wie bei vielen Programmiersprachen können die BOOLEAN
-Werte von SQL mit impliziten Wahrheitswerten getestet werden.Beispielsweise sind field1 OR field2
und NOT field1
gültige Ausdrücke.
Prädikate können den Operator Boolean IS [NOT]
zum Abgleich verwenden.Zum Beispiel field1 IS FALSE
oder field1 IS NOT TRUE
.
Note
|
|
BOOLEAN
-BeispieleEinfügen und abfragen
CREATE TABLE TBOOL (ID INT, BVAL BOOLEAN);
COMMIT;
INSERT INTO TBOOL VALUES (1, TRUE);
INSERT INTO TBOOL VALUES (2, 2 = 4);
INSERT INTO TBOOL VALUES (3, NULL = 1);
COMMIT;
SELECT * FROM TBOOL;
ID BVAL
============ =======
1 <true>
2 <false>
3 <null>
Test auf Wert TRUE
SELECT * FROM TBOOL WHERE BVAL;
ID BVAL
============ =======
1 <true>
Test auf Wert FALSE
SELECT * FROM TBOOL WHERE BVAL IS FALSE;
ID BVAL
============ =======
2 <false>
Test auf Wert UNKNOWN
SELECT * FROM TBOOL WHERE BVAL IS UNKNOWN;
ID BVAL
============ =======
3 <null>
Boolean-Werte in SELECT
-Anweisung
SELECT ID, BVAL, BVAL AND ID < 2
FROM TBOOL;
ID BVAL
============ ======= =======
1 <true> <true>
2 <false> <false>
3 <null> <false>
PSQL-Deklaration mit Startwert
DECLARE VARIABLE VAR1 BOOLEAN = TRUE;
Gültige Syntax, aber wie bei einem Vergleich mit NULL
, wird nie ein Datensatz zurückgegeben
SELECT * FROM TBOOL WHERE BVAL = UNKNOWN; SELECT * FROM TBOOL WHERE BVAL <> UNKNOWN;
Obwohl BOOLEAN
von Natur aus in keinen anderen Datentyp konvertierbar ist, werden ab Version 3.0.1 die Strings 'true'
und 'false'
(Groß-/Kleinschreibung nicht beachtet) in Wertausdrücken implizit in BOOLEAN
umgewandelt, z.B.
if (true > 'false') then ...
'false'
wird in BOOLEAN
umgewandelt.Jeder Versuch, die booleschen Operatoren AND
, NOT
, OR
und IS
zu verwenden, schlägt fehl.NOT 'False'
ist beispielsweise ungültig.
Ein BOOLEAN
kann mit CAST
explizit in und aus einem String umgewandelt werden.UNKNOWN
ist für keine Form des Castings verfügbar.
Note
|
Weitere Hinweise
|
Note
|
Die Typen [fblangref40-datatypes-chartypes-binary-de] und [fblangref40-datatypes-chartypes-varbinary-de] werden weiter oben im Abschnitt [fblangref40-datatypes-chartypes-de] behandelt. |
BLOB
s (Binary Large Objects) sind komplexe Strukturen, die verwendet werden, um Text und binäre Daten undefinierter Länge, oft sehr groß, zu speichern.
BLOB [SUB_TYPE <subtype>] [SEGMENT SIZE <segment size>] [CHARACTER SET <character set>] [COLLATE <collation name>]
BLOB (<segment size>) BLOB (<segment size>, <subtype>) BLOB (, <subtype>)
Note
|
Formal ist die |
BLOB
-UntertypenDer optionale Parameter SUB_TYPE
gibt die Art der in die Spalte geschriebenen Daten an.Firebird bietet zwei vordefinierte Untertypen zum Speichern von Benutzerdaten:
BINARY
Wenn kein Subtyp angegeben wird, wird angenommen, dass die Spezifikation für nicht typisierte Daten gilt, und der Standardwert SUB_TYPE 0
wird angewendet.Der Alias für den Subtyp null ist BINARY
.Dies ist der Untertyp, um anzugeben, ob es sich bei den Daten um eine Binärdatei oder einen Stream handelt: Bilder, Audio, Textverarbeitungsdateien, PDFs usw.
TEXT
Subtyp 1 hat einen Alias, TEXT
, der in Deklarationen und Definitionen verwendet werden kann.Zum Beispiel BLOB SUB_TYPE TEXT
.Es ist ein spezialisierter Untertyp, der verwendet wird, um Nur-Text-Daten zu speichern, die zu groß sind, um in einen String-Typ zu passen.Ein CHARACTER SET
kann angegeben werden, wenn das Feld Text mit einer anderen Kodierung als der für die Datenbank angegebenen speichern soll.Ab Firebird 2.0 wird auch eine COLLATE
-Klausel unterstützt.
Die Angabe eines CHARACTER SET
ohne SUB_TYPE
impliziert SUB_TYPE TEXT
.
Es ist auch möglich, benutzerdefinierte Datenuntertypen hinzuzufügen, für die der Aufzählungsbereich von -1 bis -32.768 reserviert ist.Benutzerdefinierte Subtypen, die mit positiven Zahlen aufgezählt werden, sind nicht zulässig, da die Firebird-Engine die Zahlen ab 2 aufwärts für einige interne Subtypen in Metadaten verwendet.
BLOB
-BesonderheitenDie maximale Größe eines 'BLOB'-Feldes ist auf 4 GB begrenzt, unabhängig davon, ob der Server 32-Bit oder 64-Bit ist.(Die internen Strukturen, die sich auf BLOB
s beziehen, unterhalten ihre eigenen 4-Byte-Zähler.)Bei einer Seitengröße von 4 KB (4096 Byte) ist die maximale Größe geringer – etwas weniger als 2 GB.
Text-BLOBs beliebiger Länge und beliebiger Zeichensätze – auch Multibyte – können Operanden für praktisch jede Anweisung oder interne Funktion sein.Die folgenden Operatoren werden vollständig unterstützt:
= |
(Zuweisung) |
=, <>, <, <=, >, >= |
(Vergeleich) |
|
(Verkettung) |
|
|
|
|
|
|
Als eine effiziente Alternative können Sie auch BLOB_APPEND()
verwenden.
Teilunterstützung:
Bei diesen tritt ein Fehler auf, wenn das Suchargument größer oder gleich 32 KB ist:
|
|
|
|
Aggregationsklauseln wirken sich nicht auf den Inhalt des Feldes selbst aus, sondern auf die BLOB-ID. Abgesehen davon gibt es einige Macken:
|
gibt fälschlicherweise mehrere NULL-Werte zurück, wenn sie vorhanden sind |
|
— |
|
verkettet dieselben Zeichenfolgen, wenn sie nebeneinander liegen, tut dies jedoch nicht, wenn sie voneinander entfernt sind |
BLOB
-SpeicherStandardmäßig wird für jedes BLOB ein regulärer Datensatz erstellt und auf einer ihm zugeordneten Datenseite gespeichert.Passt das gesamte BLOB
auf diese Seite, wird es als level 0 BLOB bezeichnet.Die Nummer dieses Sondersatzes wird im Tabellensatz gespeichert und belegt 8 Byte.
Wenn ein BLOB
nicht auf eine Datenseite passt, wird sein Inhalt auf separate, ihm exklusiv zugeordnete Seiten (Blob-Seiten) gelegt, während die Nummern dieser Seiten im BLOB
-Record gespeichert werden.Dies ist ein Level 1 BLOB.
Wenn das Array von Seitennummern, das die BLOB
-Daten enthält, nicht auf eine Datenseite passt, wird das Array auf separate Blob-Seiten gelegt, während die Nummern dieser Seiten in den BLOB
-Datensatz geschrieben werden.Dies ist ein Level-2-BLOB.
Level höher als 2 werden nicht unterstützt.
ARRAY
-Datentyp
Note
|
Firebird bietet nicht viel an Sprache oder Werkzeugen für die Arbeit mit den Inhalten von Arrays, und es gibt keine Pläne, dies zu verbessern.Dies schränkt die Nützlichkeit und Zugänglichkeit von Array-Typen ein.Der allgemeine Rat lautet daher: Verwenden Sie keine Arrays. |
Die Unterstützung von Arrays im Firebird DBMS ist eine Abkehr vom traditionellen relationalen Modell.Die Unterstützung von Arrays im DBMS könnte die Lösung einiger Datenverarbeitungsaufgaben mit großen Mengen ähnlicher Daten erleichtern.
Arrays in Firebird werden in BLOB
eines spezialisierten Typs gespeichert.Arrays können eindimensional und mehrdimensional sein und jeden Datentyp außer BLOB
und ARRAY
haben.
CREATE TABLE SAMPLE_ARR (
ID INTEGER NOT NULL PRIMARY KEY,
ARR_INT INTEGER [4]
);
In diesem Beispiel wird eine Tabelle mit einem Feld vom Typ Array erstellt, das aus vier ganzen Zahlen besteht.Die Indizes dieses Arrays sind von 1 bis 4.
Standardmäßig sind Dimensionen 1-basiert – tiefgestellte Indizes werden ab 1 nummeriert.Verwenden Sie die folgende Syntax, um explizite Ober- und Untergrenzen der tiefgestellten Werte anzugeben:
'[' <lower>:<upper> ']'
Eine neue Dimension wird mit einem Komma in der Syntax hinzugefügt.In diesem Beispiel erstellen wir eine Tabelle mit einem zweidimensionalen Array, wobei die Untergrenze der Indizes in beiden Dimensionen bei Null beginnt:
CREATE TABLE SAMPLE_ARR2 (
ID INTEGER NOT NULL PRIMARY KEY,
ARR_INT INTEGER [0:3, 0:3]
);
Die Datenbank employee.fdb
, die sich im Verzeichnis ../examples/empbuild
eines Firebird-Distributionspakets befindet, enthält eine gespeicherte Beispielprozedur, die einige einfache Arbeiten mit Arrays zeigt:
SHOW_LANGS
, eine Prozedur mit einem ArrayCREATE OR ALTER PROCEDURE SHOW_LANGS (
CODE VARCHAR(5),
GRADE SMALLINT,
CTY VARCHAR(15))
RETURNS (LANGUAGES VARCHAR(15))
AS
DECLARE VARIABLE I INTEGER;
BEGIN
I = 1;
WHILE (I <= 5) DO
BEGIN
SELECT LANGUAGE_REQ[:I]
FROM JOB
WHERE (JOB_CODE = :CODE)
AND (JOB_GRADE = :GRADE)
AND (JOB_COUNTRY = :CTY)
AND (LANGUAGE_REQ IS NOT NULL))
INTO :LANGUAGES;
IF (LANGUAGES = '') THEN
/* 'NULL' ANSTELLE VON LEERZEICHEN AUSGEBEN */
LANGUAGES = 'NULL';
I = I +1;
SUSPEND;
END
END
Wenn die beschriebenen Funktionen für Ihre Aufgaben ausreichen, können Sie in Ihren Projekten Arrays verwenden.Derzeit sind keine Verbesserungen geplant, um die Unterstützung für Arrays in Firebird zu verbessern.
“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