FirebirdSQL logo
 SQL SprachstrukturAllgemeine Sprachelemente 

Hexadezimales Format für Ganzzahlen

Ab Firebird 2.5 können Konstanten der drei Integer-Typen im hexadezimalen Format mit 9 bis 16 hexadezimalen Stellen für BIGINT bzw. 1 bis 8 Stellen für INTEGER angegeben werden.Die Hex-Darstellung zum Schreiben in SMALLINT wird nicht explizit unterstützt, aber Firebird wandelt eine Hex-Zahl bei Bedarf transparent in SMALLINT um, sofern sie in den negativen und positiven SMALLINT-Bereich fällt.

Note

Die hexadezimalen Integer-Literale unterstützen derzeit keine 'INT128'-Werte.

Die Verwendung und die numerischen Wertebereiche der hexadezimalen Notation werden in der Diskussion zu Zahlenkonstanten im Kapitel Allgemeine Sprachelemente genauer beschrieben.

Beispiele mit Integer-Typen
CREATE TABLE WHOLELOTTARECORDS (
  ID BIGINT NOT NULL PRIMARY KEY,
  DESCRIPTION VARCHAR(32)
);

INSERT INTO MYBIGINTS VALUES (
  -236453287458723,
  328832607832,
  22,
  -56786237632476,
  0X6F55A09D42,       -- 478177959234
  0X7FFFFFFFFFFFFFFF, -- 9223372036854775807
  0XFFFFFFFFFFFFFFFF, -- -1
  0X80000000,         -- -2147483648, ein INTEGER
  0X080000000,        -- 2147483648, ein BIGINT
  0XFFFFFFFF,         -- -1, ein INTEGER
  0X0FFFFFFFF         -- 4294967295, ein BIGINT
);

Die hexadezimalen INTEGERs im obigen Beispiel werden automatisch in BIGINT umgewandelt, bevor sie in die Tabelle eingefügt werden.Dies geschieht jedoch nach der Zahlenwert ermittelt wurde, also werden 0x80000000 (8 Stellen) und 0x080000000 (9 Stellen) als unterschiedliche BIGINT Werte gespeichert.

Benutzerdefinierte Datentypen – Domains

In Firebird ist das Konzept eines “benutzerdefinierten Datentyps” in Form der Domain implementiert.Das Erstellen einer Domain erzeugt natürlich nicht wirklich einen neuen Datentyp.Eine Domain bietet die Möglichkeit, einen vorhandenen Datentyp mit einem Satz von Attributen zu kapseln und diese “Kapsel” für die mehrfache Verwendung in der gesamten Datenbank verfügbar zu machen.Wenn mehrere Tabellen Spalten mit identischen oder nahezu identischen Attributen benötigen, ist eine Domäne sinnvoll.

Die Domänenverwendung ist nicht auf Spaltendefinitionen für Tabellen und Ansichten beschränkt.Domänen können verwendet werden, um Eingabe- und Ausgabeparameter und Variablen in PSQL-Code zu deklarieren.

docnext count = 77

Domaineigenschaften

Eine Domaindefinition enthält erforderliche und optionale Attribute.Der Datentyp ist ein erforderliches Attribut.Zu den optionalen Attributen gehören:

  • ein Standardwert

  • um NULL zu erlauben oder zu verbieten

  • CHECK-Einschränkungen

  • Zeichensatz (für Zeichendatentypen und Text-BLOB-Felder)

  • Sortierung (für Zeichendatentypen)

Beispieldomaindefinition
CREATE DOMAIN BOOL3 AS SMALLINT
  CHECK (VALUE IS NULL OR VALUE IN (0, 1));
Siehe auch

Explizite Datentypumwandlung zur Beschreibung von Unterschieden im Datenkonvertierungsmechanismus, wenn Domänen für die Modifikatoren TYPE OF und TYPE OF COLUMN angegeben werden.

Domain-Überschreibung

Beim Definieren einer Spalte mithilfe einer Domäne ist es möglich, einige der von der Domäne geerbten Attribute zu überschreiben.Tabelle 3.9 fasst die Regeln für die Domänenüberschreibung zusammen.

Table 1. Regeln zum Überschreiben von Domänenattributen in der Spaltendefinition
Attribute Überschreiben? Hinweise

Datentyp

Nein

 

Standardwert

Ja

 

Textzeichensatz

Ja

Es kann auch verwendet werden, um die Standarddatenbankwerte für die Spalte wiederherzustellen

Reihenfolge der Textsortierung

Ja

 

CHECK-Constraints

Ja

Um der Prüfung neue Bedingungen hinzuzufügen, können Sie die entsprechenden CHECK-Klauseln in den Anweisungen CREATE und ALTER auf Tabellenebene verwenden.

NOT NULL

Nein

Oft ist es besser, die Domain in ihrer Definition nullbar zu lassen und zu entscheiden, ob sie auf NOT NULL gesetzt werden soll, wenn die Domain zum Definieren von Spalten verwendet wird.

Erstellen und Verwalten von Domains

Eine Domain wird mit der DDL-Anweisung CREATE DOMAIN erstellt.

Kurzschreibweise
CREATE DOMAIN name [AS] <type>
  [DEFAULT {<const> | <literal> | NULL | <context_var>}]
  [NOT NULL] [CHECK (<condition>)]
  [COLLATE <collation>]
Siehe auch

CREATE DOMAIN im Abschnitt Datendefinitionssprache (DDL).

Domain ändern

Um die Attribute einer Domain zu ändern, verwenden Sie die DDL-Anweisung ALTER DOMAIN.Mit dieser Aussage können Sie:

  • die Domain umbenennen

  • den Datentyp ändern

  • den aktuellen Standardwert löschen

  • einen neuen Standardwert setzen

  • lösche die NOT NULL-Beschränkung

  • setze die NOT NULL-Beschränkung

  • eine bestehende CHECK-Einschränkung löschen

  • füge eine neue CHECK-Einschränkung hinzu

Kurzsyntax
ALTER DOMAIN name
  [{TO new_name}]
  [{SET DEFAULT { <literal> | NULL | <context_var> } |
    DROP DEFAULT}]
  [{SET | DROP} NOT NULL ]
  [{ADD [CONSTRAINT] CHECK (<dom_condition>) |
    DROP CONSTRAINT}]
  [{TYPE <datatype>}]
Beispiel
ALTER DOMAIN STORE_GRP SET DEFAULT -1;

Beim Wechsel einer Domain müssen deren Abhängigkeiten berücksichtigt werden: ob Tabellenspalten, beliebige Variablen, Ein- und/oder Ausgabeparameter mit dem im PSQL-Code deklarierten Typ dieser Domain vorhanden sind.Wenn Sie Domains in Eile ändern, ohne sie sorgfältig zu überprüfen, funktioniert Ihr Code möglicherweise nicht mehr!

Important

Wenn Sie Datentypen in einer Domain konvertieren, dürfen Sie keine Konvertierungen durchführen, die zu Datenverlusten führen können.Wenn Sie beispielsweise VARCHAR in INTEGER konvertieren, prüfen Sie sorgfältig, ob alle Daten, die diese Domain verwenden, erfolgreich konvertiert werden können.

Siehe auch

ALTER DOMAIN im Abschnitt Datendefinitionssprache (DDL).

Löschen (Dropping) einer Domain

Die DDL-Anweisung DROP DOMAIN löscht eine Domain aus der Datenbank, sofern sie nicht von anderen Datenbankobjekten verwendet wird.

Syntax
DROP DOMAIN name
Beispiel
DROP DOMAIN Test_Domain
Siehe auch

DROP DOMAIN im Abschnitt Datendefinitionssprache (DDL).

Syntax der Datentyp-Deklaration

In diesem Abschnitt wird die Syntax der Deklaration von Datentypen dokumentiert.Die Datentypdeklaration erfolgt in DDL-Anweisungen, aber auch in CAST und <<fblangref40-dml-execblock-de,EXECUTE BLOCK> >.

Auf die unten dokumentierte Syntax wird von anderen Teilen dieser Sprachreferenz verwiesen.

Syntax für Skalardatentypen

Die skalaren Datentypen sind einfache Datentypen, die einen einzelnen Wert enthalten.Aus organisatorischen Gründen wird die Syntax der BLOB-Typen separat in [fblangref40-datatypes-syntax-blob-de] definiert.

Syntax für skalare Datentypen
<domain_or_non_array_type> ::=
    <scalar_datatype>
  | <blob_datatype>
  | [TYPE OF] domain
  | TYPE OF COLUMN rel.col

<scalar_datatype> ::=
    SMALLINT | INT[EGER] | BIGINT | INT128
  | REAL | FLOAT [(bin_prec)] | DOUBLE PRECISION
  | DECFLOAT [(dec_prec)]
  | BOOLEAN
  | DATE
  | TIME [{WITHOUT | WITH} TIME ZONE]
  | TIMESTAMP [{WITHOUT | WITH} TIME ZONE]
  | {DECIMAL | NUMERIC} [(precision [, scale])]
  | {VARCHAR | {CHAR | CHARACTER} VARYING} (length)
    [CHARACTER SET charset]
  | {CHAR | CHARACTER} [(length)] [CHARACTER SET charset]
  | {NCHAR | NATIONAL {CHARACTER | CHAR}} VARYING (length)
  | {NCHAR | NATIONAL {CHARACTER | CHAR}} [(length)]
  | BINARY [(length)]
  | {VARBINARY | BINARY VARYING} (length)
Table 1. Argumente für die Syntax der skalaren Datentypen
Argument Beschreibung

domain

Domain (nur Nicht-Array-Domains)

rel

Name einer Tabelle oder Ansicht (View)

col

Name einer Spalte in einer Tabelle oder Ansicht (nur Spalten eines Nicht-Array-Typs)

bin_prec

Binäre Genauigkeit, Standard ist 24.

1 - 24: 32 Bit einfache Genauigkeit
25 - 53: 64 Bit doppelte Genauigkeit (Synonym für DOUBLE PRECISION)

dec_prec

Dezimalgenauigkeit von DECFLOAT, entweder 16 oder 34;Standard ist 34

precision

Numerische Genauigkeit in Dezimalstellen.Von 1 bis 38

scale

Skalierung oder Anzahl der Dezimalstellen.Von 0 bis 38.Sie muss kleiner oder gleich precision sein.

length

Die maximale Länge eines Strings in Zeichen oder — für BINARY und VARBINARY — Bytes;optional für Zeichentypen mit fester Breite, standardmäßig 1

charset

Zeichensatz

domain_or_non_array_type

Nicht-Array-Typen, die in PSQL-Code und -Casts verwendet werden können

Verwendung von Domains in Deklarationen

Ein Domainname kann als Typ eines PSQL-Parameters oder einer lokalen Variablen angegeben werden.Der Parameter oder die Variable erbt alle Domänenattribute.Wenn für den Parameter oder die Variable ein Standardwert angegeben wird, überschreibt er den in der Domaindefinition angegebenen Standardwert.

Wenn die TYPE OF-Klausel vor dem Domainnamen hinzugefügt wird, wird nur der Datentyp der Domain verwendet: alle anderen Attribute der Domain — NOT NULL-Einschränkung, CHECK-Einschränkungen, Standardwert — sind weder geprüft noch benutzt.Handelt es sich bei der Domain jedoch um einen Texttyp, werden immer deren Zeichensatz und Kollatierungsreihenfolge verwendet.

Verwendung des Spaltentyps in Deklarationen

Ein- und Ausgabeparameter oder lokale Variablen können auch über den Datentyp von Spalten in bestehenden Tabellen und Views deklariert werden.Dafür wird die TYPE OF COLUMN-Klausel verwendet, die relationname.columnname als Argument angibt.

Wenn TYPE OF COLUMN verwendet wird, erbt der Parameter oder die Variable nur den Datentyp und – bei String-Typen – den Zeichensatz und die Kollatierungssequenz.Die Einschränkungen und der Standardwert der Spalte werden ignoriert.

Syntax der BLOB-Datentypen

Die BLOB-Datentypen enthalten Binär-, Zeichen- oder benutzerdefinierte Formatdaten unbestimmter Größe.Weitere Informationen finden Sie unter [fblangref40-datatypes-bnrytypes-de].

Syntax der BLOB-Datentypen
<blob_datatype> ::=
    BLOB [SUB_TYPE {subtype_num | subtype_name}]
    [SEGMENT SIZE seglen] [CHARACTER SET charset]
  | BLOB [(seglen [, subtype_num])]
Table 1. Argumente für die Syntax der Blob-Datentypen
Argument Beschreibung

charset

Zeichensatz (wird für andere Untertypen als TEXT/1 ignoriert)

subtype_num

BLOB-Untertypnummer

subtype_name

mnemonischer Name des 'BLOB'-Untertyps;dies kann TEXT, BINARY oder einer der (anderen) Standard- oder benutzerdefinierten Namen sein, die in RDB$TYPES für RDB$FIELD_NAME = 'RDB$FIELD_SUB_TYPE' definiert sind.

seglen

Segmentgröße, darf nicht größer als 65.535 sein, Standardwert 80, wenn nicht angegeben.Siehe auch [fblangref40-datatypes-seg-size-de]

Syntax der Array-Datentypen

Die Array-Datentypen enthalten mehrere Skalarwerte in einem ein- oder mehrdimensionalen Array.Weitere Informationen finden Sie unter [fblangref40-datatypes-array-de]

Syntax der Array-Datentypen
<array_datatype> ::=
    {SMALLINT | INT[EGER] | BIGINT | INT128} <array_dim>
  | {REAL | FLOAT [(bin_prec)] | DOUBLE PRECISION} <array_dim>
  | DECFLOAT [(dec_prec)]
  | BOOLEAN <array_dim>
  | DATE <array_dim>
  | TIME [{WITHOUT | WITH} TIME ZONE] <array_dim>
  | TIMESTAMP [{WITHOUT | WITH} TIME ZONE] <array_dim>
  | {DECIMAL | NUMERIC} [(precision [, scale])] <array_dim>
  | {VARCHAR | {CHAR | CHARACTER} VARYING} (length)
    <array_dim> [CHARACTER SET charset]
  | {CHAR | CHARACTER} [(length)] <array_dim>
    [CHARACTER SET charset]
  | {NCHAR | NATIONAL {CHARACTER | CHAR}} VARYING (length)
    <array_dim>
  | {NCHAR | NATIONAL {CHARACTER | CHAR}}
    [(length)] <array_dim>
  | BINARY [(length)] <array_dim>
  | {VARBINARY | BINARY VARYING} (length) <array_dim>

<array_dim> ::= '[' [m:]n [,[m:]n ...] ']'
Table 1. Argumente für die Syntax der Array-Datentypen
Argument Beschreibung

array_dim

Array-Dimensionen

bin_prec

Binäre Genauigkeit, Standard ist 24.

1 - 24: 32 Bit einfache Genauigkeit
25 - 53: 64 Bit doppelte Genauigkeit (Synonym für DOUBLE PRECISION)

dec_prec

Dezimalgenauigkeit von DECFLOAT, entweder 16 oder 34;Standard ist 34

precision

Numerische Genauigkeit in Dezimalstellen.Von 1 bis 38

scale

Skala oder Anzahl der Dezimalstellen.Von 0 bis 38.Sie muss kleiner oder gleich precision sein.

length

Die maximale Länge einer Zeichenfolge in Zeichen;optional für Zeichentypen mit fester Breite, standardmäßig 1

charset

Zeichensatz

m, n

Ganzzahlen, die den Indexbereich einer Array-Dimension definieren

Gleitkomma-Datentypen

Firebird unterstützt zwei Arten von Gleitkomma-Datentypen: ungefähre oder binäre Gleitkomma-Datentypen (FLOAT und DOUBLE PRECISION) und dezimale Gleitkomma-Typen (DECFLOAT).

Ungefähre Gleitkomma-Datentypen

Ungefähre Gleitkomma-Datentypen werden in einem IEEE 754-Binärformat gespeichert, das Vorzeichen, Exponent und Mantisse umfasst.Die Genauigkeit ist dynamisch und entspricht dem physischen Speicherformat des Werts, das genau 4 Byte für den Typ FLOAT und 8 Byte für DOUBLE PRECISION beträgt.

Angesichts der Besonderheiten beim Speichern von Gleitkommazahlen in einer Datenbank werden diese Datentypen nicht zum Speichern von Gelddaten empfohlen.Aus den gleichen Gründen werden Spalten mit Gleitkommadaten nicht für die Verwendung als Schlüssel oder für die Anwendung von Eindeutigkeitsbeschränkungen empfohlen.

Zum Testen von Daten in Spalten mit Gleitkomma-Datentypen sollten Ausdrücke anhand eines Bereichs, beispielsweise BETWEEN, prüfen, anstatt nach genauen Übereinstimmungen zu suchen.

Bei der Verwendung dieser Datentypen in Ausdrücken ist bei der Rundung der Auswertungsergebnisse äußerste Vorsicht geboten.

FLOAT

Datentyp-Deklarationsformat
FLOAT [(bin_prec)]
Table 1. FLOAT-Datentypparameter
Parameter Beschreibung

bin_prec

Genauigkeit in Binärziffern, Standard ist 24

1 - 24: 32-Bit einfache Genauigkeit25 - 53: 64-Bit doppelte Genauigkeit

Der Datentyp FLOAT ist standardmäßig ein 32-Bit-Gleitkommatyp mit einfacher Genauigkeit mit einer ungefähren Genauigkeit von 7 Dezimalstellen nach dem Komma (24 Binärstellen).Um die Sicherheit der Lagerung zu gewährleisten, verlassen Sie sich auf eine Genauigkeit von 6 Dezimalstellen.

Die Syntax FLOAT(bin_prec) wurde in Firebird 4.0 eingeführt und verhält sich wie folgt:

  • 1 <= _bin_prec <= 23: 32 Bit einfache Genauigkeit (Synonym für FLOAT)

  • 25 <= _bin_prec <= 53: 64 Bit doppelte Genauigkeit (Synonym für DOUBLE PRECISION)

Das Verhalten von FLOAT (ohne explizite Genauigkeit) verhält sich wie der SQL-Standardtyp [fblangref40-datatypes-real-de].

Note
Kompatibilitätshinweise
  • Firebird 3.0 und früher unterstützten FLOAT(dec_prec), wobei dec_prec die ungefähre Genauigkeit in Dezimalstellen war, wobei 0 <= dec_prec <= 7 auf 32-Bit-Einfachgenauigkeit und P > 7 abgebildet bis 64-Bit-Doppelgenauigkeit.Diese Syntax wurde nie dokumentiert.

  • Für bin_prec in FLOAT(bin_prec) werden die Werte 1 <= bin_prec <= 24 alle als bin_prec = 24 behandelt, Werte 25 <= bin_prec +<= + 53 werden alle als bin_prec = 53 behandelt.

  • Die meisten Firebird-Tools behandeln FLOAT(1) - FLOAT(24) als FLOAT und FLOAT(25) - FLOAT(53) als DOUBLE PRECISION.

REAL

Datentyp-Deklarationsformat
REAL

Der Datentyp REAL ist ein Synonym für FLOAT und wird aus Gründen der Syntaxkompatibilität bereitgestellt.Wenn es zum Definieren einer Spalte oder eines Parameters verwendet wird, ist es nicht von der Verwendung von FLOAT oder FLOAT(1) - FLOAT(24) zu unterscheiden.

Note
Kompatibilitätshinweis
  • REAL ist seit Firebird 1.0 und noch früher als Synonym für FLOAT verfügbar, wurde aber nie dokumentiert.

  • Die meisten Firebird-Tools melden FLOAT als REAL.

DOUBLE PRECISION

Datentyp-Deklarationsformat
DOUBLE PRECISION

Der Datentyp DOUBLE PRECISION wird mit einer ungefähren Genauigkeit von 15 Stellen gespeichert.

Note
Kompatibilitätshinweise
  • Firebird hat auch die — bisher undokumentierten — Synonyme für DOUBLE PRECISION: LONG FLOAT und LONG FLOAT(bin_prec), mit 1 <= bin_prec <= 53.

    Diese nicht standardmäßigen Typennamen sind veraltet und werden möglicherweise in einer zukünftigen Firebird-Version entfernt.

  • Firebird 3.0 und früher unterstützten LONG FLOAT(dec_prec), wobei dec_prec die ungefähre Genauigkeit in Dezimalstellen war, wobei jeder Wert für dec_prec auf 64-Bit-Doppelgenauigkeit abgebildet wurde.

Dezimale Gleitkommatypen

Dezimale Gleitkommazahlen werden in einem IEEE 754-Dezimalformat gespeichert, das Vorzeichen, Exponent und Koeffizient umfasst.Im Gegensatz zu den ungefähren Gleitkomma-Datentypen beträgt die Genauigkeit entweder 16 oder 34 Dezimalstellen.

DECFLOAT

Datentyp-Deklarationsformat
DECFLOAT [(precision)]
Table 1. DECFLOAT-Datentypparameter
Parameter Beschreibung

precision

Genauigkeit in Dezimalstellen, entweder 16 oder 34.Standard ist 34.

DECFLOAT ist ein SQL:2016 standardkonformer numerischer Typ, der Gleitkommazahlen präzise speichert (dezimaler Gleitkommatyp), im Gegensatz zu FLOAT oder DOUBLE PRECISION, die eine binäre Annäherung an die angebliche Genauigkeit bieten.

Der Typ wird als IEEE 754-Standardtypen Decimal64 (DECFLOAT(16)) oder Decimal128 (DECFLOAT(34)) gespeichert und übertragen.

Alle Zwischenrechnungen werden mit 34-stelligen Werten durchgeführt.

16-stellig und 34-stellig

Die “16” und “34” beziehen sich auf die maximale Genauigkeit in 10er-Basis-Stellen.Siehe auch https://en/wikipedia.org/wiki/iEEE_754#Basic_and_interchange_formats for a comprehensive table.

Table 2. Wertebereich
Typ Höchste Präzision Geringste Präzision Maximaler Exponent Kleinster Wert Größter Wert

DECFLOAT(16)

16

-383

+384

1E-398

9.9..9E+384

DECFLOAT(34)

34

-6143

+6144

1E-6176

9.9..9E+6144

Beachten Sie, dass, obwohl der kleinste Exponent für DECFLOAT(16) -383 ist, der kleinste Wert einen Exponenten von -398 hat, aber 15 Stellen weniger.Und ähnlich für DECFLOAT(34) ist der kleinste Exponent -6143, aber der kleinste Wert hat einen Exponenten von -6176, aber 33 Stellen weniger.Der Grund dafür ist, dass die Präzision "geopfert" wurde, um einen kleineren Wert speichern zu können.

Dies ergibt sich aus der Speicherung des Wertes: als Dezimalwert mit 16 oder 34 Stellen und einem Exponenten.Zum Beispiel wird '1.234567890123456e-383' tatsächlich als Koeffizient '1234567890123456' und Exponent '-398' gespeichert, während '1E-398' als Koeffizient '1', Exponent '-398' gespeichert wird.

Verhalten von DECFLOAT-Operationen

Das Verhalten von DECFLOAT-Operationen in einer Sitzung, insbesondere Rundungs- und Fehlerverhalten, kann mit der Management-Anweisung SET DECFLOAT konfiguriert werden.

Länge der DECFLOAT-Literale

Es ist möglich, DECFLOAT(34)-Werte in ungefähren numerischen Literalen auszudrücken, jedoch nur für Werte mit einer Mantisse von 20 oder mehr Stellen oder einem absoluten Exponenten größer als 308.Wissenschaftliche Notationsliterale mit weniger Ziffern oder einem kleineren absoluten Exponenten sind DOUBLE PRECISION-Literale.Genaue numerische Literale mit 40 oder mehr Stellen – tatsächlich 39 Stellen, wenn sie größer als der maximale INT128-Wert sind – werden auch als DECFLOAT(34) behandelt.

Alternativ können Sie ein String-Literal verwenden und explizit in den gewünschten DECFLOAT-Typ umwandeln.

Die Länge der DECFLOAT-Literale darf 1024 Zeichen nicht überschreiten.Für größere Werte ist eine wissenschaftliche Schreibweise erforderlich.Zum Beispiel kann 0.0<1020 Nullen>11 nicht als Literal verwendet werden, das Äquivalent in wissenschaftlicher Schreibweise 1.1E-1022 ist gültig.Ähnlich kann '10<1022 Nullen>0' als '1.0E1024' dargestellt werden.Literale mit mehr als 34 signifikanten Stellen werden mit dem Rundungsmodus DECFLOAT der Sitzung gerundet.

DECFLOAT und Funktionen
Verwendung mit Standardfunktionen

Eine Reihe von Standardskalarfunktionen können mit Ausdrücken und Werten vom Typ DECFLOAT verwendet werden.Sie sind:

ABS

CEILING

EXP

FLOOR

LN

LOG

LOG10

POWER

SIGN

SQRT

Die Aggregatfunktionen SUM, AVG, MAX und MIN arbeiten mit DECFLOAT-Daten, ebenso wie alle Statistikaggregate (einschließlich aber nicht beschränkt auf STDDEV oder CORR).

Spezielle Funktionen für DECFLOAT

Firebird unterstützt vier Funktionen, die speziell für die Unterstützung von DECFLOAT-Daten entwickelt wurden:

COMPARE_DECFLOAT

vergleicht zwei DECFLOAT-Werte, um gleich, unterschiedlich oder ungeordnet zu sein

NORMALIZE_DECFLOAT

nimmt ein einzelnes DECFLOAT-Argument und gibt es in seiner einfachsten Form zurück

QUANTIZE

nimmt zwei DECFLOAT-Argumente und gibt das erste Argument skaliert mit dem zweiten Wert als Muster zurück

TOTALORDER

führt einen genauen Vergleich mit zwei DECFLOAT-Werten durch

Detaillierte Beschreibungen finden Sie im Abschnitt Spezialfunktionen für DECFLOAT des Kapitels Eingebaute Skalarfunktionen.

Festkomma-Datentypen

Festkomma-Datentypen stellen die Vorhersagbarkeit von Multiplikations- und Divisionsoperationen sicher und machen sie zur ersten Wahl zum Speichern von Geldwerten.Firebird implementiert zwei Festkomma-Datentypen: NUMERIC und DECIMAL.Beide Typen begrenzen laut Norm die gespeicherte Zahl auf die angegebene Skala (die Anzahl der Nachkommastellen).

Unterschiedliche Behandlungen begrenzen die Genauigkeit für jeden Typ: Die Genauigkeit für NUMERIC-Spalten ist genau „wie deklariert“, während DECIMAL-Spalten Zahlen akzeptieren, deren Genauigkeit mindestens der Deklaration entspricht.

Note

Das Verhalten von NUMERIC und DECIMAL in Firebird entspricht dem SQL-Standard DECIMAL;die Genauigkeit entspricht mindestens der Deklaration.

Beispielsweise definiert NUMERIC(4, 2) eine Zahl, die insgesamt aus vier Ziffern besteht, einschließlich zweier Nachkommastellen;das heißt, er kann bis zu zwei Ziffern vor dem Punkt und nicht mehr als zwei Ziffern nach dem Punkt haben.Wird in eine Spalte mit dieser Datentypdefinition die Zahl 3.1415 geschrieben, wird der Wert 3.14 in der Spalte NUMERIC(4, 2) gespeichert.

Die Deklarationsform für Festkommadaten, zB NUMERIC(p, s), ist beiden Typen gemeinsam.Es ist wichtig zu wissen, dass das Argument s in dieser Vorlage scale ist und nicht “eine Anzahl von Stellen nach dem Komma”.Das Verständnis des Mechanismus zum Speichern und Abrufen von Festkommadaten sollte dabei helfen, zu veranschaulichen, warum: Zum Speichern wird die Zahl mit 10s (10 hoch s) multipliziert und in eine ganze Zahl umgewandelt;beim Lesen wird die ganze Zahl zurückkonvertiert.

Die Methode zum Speichern von Festkommadaten in der Datenbank hängt von mehreren Faktoren ab: Deklarierte Genauigkeit, Datenbankdialekt, Deklarationstyp.

Table 1. Methode der physischen Speicherung für Festkommazahlen
Skalierung Datentyp Dialekt 1 Dialekt 3

1 - 4

NUMERIC

SMALLINT

SMALLINT

1 - 4

DECIMAL

INTEGER

INTEGER

5 - 9

NUMERIC oder DECIMAL

INTEGER

INTEGER

10 - 18

NUMERIC oder DECIMAL

DOUBLE PRECISION

BIGINT

19 - 38

NUMERIC oder DECIMAL

INT128

INT128

Note

Numeriken mit einer Genauigkeit von weniger als 19 Stellen verwenden SMALLINT, INTEGER, BIGINT oder DOUBLE PRECISION als Basisdatentyp, abhängig von der Anzahl der Stellen und dem SQL-Dialekt.Wenn die Genauigkeit zwischen 19 und 38 Stellen liegt, wird eine 128-Bit-Ganzzahl für den internen Speicher verwendet, und die tatsächliche Genauigkeit wird immer auf die vollen 38 Stellen erweitert.

Bei komplexen Berechnungen werden diese Ziffern intern in DECFLOAT(34) umgewandelt.Das Ergebnis verschiedener mathematischer Operationen, wie LOG(), EXP() und so weiter, und Aggregatfunktionen, die ein hochpräzises numerisches Argument verwenden, ist DECFLOAT(34).

NUMERIC

Datentyp-Deklarationsformat
  NUMERIC
| NUMERIC(precision)
| NUMERIC(precision, scale)
Table 1. NUMERIC-Typparameter
Parameter Beschreibung

precision

Präzision zwischen 1 und 38.Standardmäßig auf 9.

scale

Skala, zwischen 0 und precision.Standardmäßig auf 0.

Speicherbeispiele

Zusätzlich zu der obigen Erklärung speichert Firebird NUMERIC-Daten gemäß der deklarierten precision und scale.Einige weitere Beispiele sind:

NUMERIC(4) gespeichert als SMALLINT (genaue Daten)
NUMERIC(4,2)               SMALLINT (Daten * 102)
NUMERIC(10,4) (Dialekt 1)  DOUBLE PRECISION
              (Dialekt 3)  BIGINT (Daten * 104)
NUMERIC(38,6)              INT128 (Daten * 106)
Caution

Denken Sie immer daran, dass das Speicherformat von der Genauigkeit abhängt.Zum Beispiel definieren Sie den Spaltentyp als NUMERIC(2,2) unter der Annahme, dass sein Wertebereich -0,99…​0,99 beträgt.Der tatsächliche Wertebereich für die Spalte beträgt jedoch -327,68…​327,67, was darauf zurückzuführen ist, dass der Datentyp NUMERIC(2,2) im SMALLINT-Format gespeichert ist.Im Speicher sind die Datentypen NUMERIC(4,2), NUMERIC(3,2) und NUMERIC(2,2) tatsächlich gleich.Das heißt, wenn Sie wirklich Daten in einer Spalte mit dem Datentyp NUMERIC(2,2) speichern und den Bereich auf -0,99…​0,99 begrenzen möchten, müssen Sie dafür eine Einschränkung erstellen.

DECIMAL

Datendeklarationsformat
  DECIMAL
| DECIMAL(precision)
| DECIMAL(precision, scale)
Table 1. DECIMAL-Typparameter
Parameter Beschreibung

precision

Präzision zwischen 1 und 38.Standardmäßig auf 9.

scale

Skala, zwischen 0 und precision.Standardmäßig auf 0.

Speicherbeispiele

Das Speicherformat in der Datenbank für DECIMAL ist NUMERIC sehr ähnlich, mit einigen Unterschieden, die anhand einiger weiterer Beispiele leichter zu erkennen sind:

NUMERIC(4) gespeichert als SMALLINT (genaue Daten)
NUMERIC(4,2)               SMALLINT (Daten * 102)
NUMERIC(10,4) (Dialekt 1)  DOUBLE PRECISION
              (Dialekt 3)  BIGINT (Daten * 104)
NUMERIC(38,6)              INT128 (Daten * 106)

Datentypen für Datum und Uhrzeit

Die Datentypen DATE, TIME und TIMESTAMP werden verwendet, um mit Daten zu arbeiten, die Datums- und Uhrzeitangaben enthalten.

Firebird 4.0 führt Zeitzonenunterstützung ein und verwendet die Typen TIME WITH TIME ZONE und TIMESTAMP WITH TIME ZONE.In dieser Sprachreferenz verwenden wir TIME und TIMESTAMP, um auf die spezifischen Typen ohne Zeitzone zu verweisen – TIME [WITHOUT TIME ZONE] und TIMESTAMP [WITHOUT TIME ZONE] – wie auch auf die Typen mit Zeitzone. Welche wir meinen, ist normalerweise aus dem Kontext klar.

Important

Die Datentypen ZEIT OHNE ZEITZONE, ZEITSTAMP OHNE ZEITZONE und DATUM sind so definiert, dass sie die Sitzungszeitzone bei der Konvertierung von oder in eine ZEIT MIT ZEITZONE oder ZEITSTAMP MIT ZEITZONE verwenden.TIME und TIMESTAMP sind gleichbedeutend mit ihren jeweiligen OHNE ZEITZONE-Datentypen.

Dialekt 3 unterstützt alle fünf Typen, während Dialekt 1 nur DATE hat.Der DATE-Typ in Dialekt 3 bedeutet “nur Datum”, während der DATE-Typ von Dialekt 1 sowohl Datum als auch Uhrzeit speichert, was TIMESTAMP in Dialekt 3 entspricht.Dialekt 1 hat keinen Typ “nur Datum”.

Note

Dialekt 1 DATE Daten können alternativ als TIMESTAMP definiert werden und dies wird für neue Definitionen in Dialekt 1 Datenbanken empfohlen.

  1. SekundenbruchteileWenn Sekundenbruchteile in Datums- und Zeitdatentypen gespeichert sind, speichert Firebird sie auf Zehntausendstelsekunden.Wenn eine niedrigere Granularität bevorzugt wird, kann der Bruchteil in Dialekt-3-Datenbanken von ODS 11 oder höher explizit als Tausendstel, Hundertstel oder Zehntelsekunde oder Sekunde angegeben werden.

Note
Einige nützliche Kenntnisse über die Präzision im Sekundenbereich

Der Zeitteil von TIME oder TIMESTAMP ist ein 4-Byte-WORD, mit Platz für Dezimillisekunden-Genauigkeit und Zeitwerte werden als die Anzahl der seit Mitternacht verstrichenen Dezimillisekunden gespeichert.Die tatsächliche Genauigkeit von Werten, die in Zeit(stempel)-Funktionen und -Variablen gespeichert oder daraus gelesen werden, beträgt:

  • CURRENT_TIME und LOCALTIME sind standardmäßig auf Sekunden genau und kann mit CURRENT_TIME (0|1|2|3) bis auf Millisekunden genau angegeben werden

  • CURRENT_TIMESTAMP und LOCALTIMESTAMP sind standardmäßig auf Millisekunden genau.Die Genauigkeit von Sekunden bis Millisekunden kann mit CURRENT_TIMESTAMP (0|1|2|3) oder LOCALTIMESTAMP (0|1|2|3) angegeben werden

  • Das Literal 'NOW' hat standardmäßig eine Genauigkeit von Millisekunden

  • Die Funktion DATEADD() unterstützt mit MILLISECOND . eine Genauigkeit von bis zu Dezi-Millisekunden

  • Funktion DATEDIFF() unterstützt nur bis zu Millisekunden Genauigkeit

  • Die Funktion EXTRACT() gibt mit den Argumenten SECOND und MILLISECOND eine Genauigkeit von Dezi-Millisekunden zurück

  • die Operatoren ‘+’ und ‘-’ arbeiten mit Dezimillisekunden-Präzision.

Die Genauigkeit von Dezi-Millisekunden ist selten und wird nicht von allen Treibern und Zugriffskomponenten unterstützt.Die beste Annahme aus all dem ist, dass, obwohl Firebird TIME und die TIMESTAMP-Zeitteilwerte als die Anzahl der seit Mitternacht verstrichenen Dezi-Millisekunden (10-4 Sekunden) speichert, die tatsächliche Genauigkeit variieren kann von Sekunden bis Millisekunden.

Speicherung von Zeitzonentypen

Die Zeitzonentypen werden als Werte bei UTC (Offset 0) gespeichert, wobei die Struktur von TIME oder TIMESTAMP + zwei zusätzliche Bytes für Zeitzoneninformationen verwendet wird (entweder ein Offset in Minuten oder die ID einer benannten Zeit Zone).Das Speichern als UTC ermöglicht es Firebird, zwei Werte in verschiedenen Zeitzonen zu indizieren und zu vergleichen.

Das Speichern bei UTC hat einige Fallstricke:

  • Wenn Sie benannte Zonen verwenden und sich die Zeitzonenregeln für diese Zone ändern, bleibt die UTC-Zeit gleich, aber die Ortszeit in der benannten Zone kann sich ändern.

  • Für TIME WITH TIME ZONE gilt für die Berechnung eines Zeitzonen-Offsets für eine benannte Zone, um die lokale Zeit in der Zone zu erhalten, die am 1. Januar 2020 gültigen Regeln, um einen stabilen Wert zu gewährleisten.Dies kann zu unerwarteten oder verwirrenden Ergebnissen führen.

  • Wenn sich die Regeln einer benannten Zeitzone ändern, kann ein Wert im betroffenen Datumsbereich länger mit dem beabsichtigten Wert übereinstimmen, wenn sich der tatsächliche Offset in dieser benannten Zone ändert.

DATE

Syntax
DATE

Der Datentyp DATE in Dialect 3 speichert nur das Datum ohne Uhrzeit.Der verfügbare Bereich zum Speichern von Daten reicht vom 01. Januar bis zum 31. Dezember 9999.

Dialekt 1 hat keinen Typ “nur Datum”.

Tip

In Dialekt 1 erhalten Datumsliterale ohne Zeitteil sowie Umwandlungen von Datumsmnemoniken 'TODAY', 'YESTERDAY' und 'TOMORROW' automatisch einen Nullzeitteil.

Wenn es Ihnen aus irgendeinem Grund wichtig ist, ein Dialekt-1-Zeitstempelliteral mit einem expliziten Zeitteil Null zu speichern, akzeptiert die Engine ein Literal wie '2016-12-25 00:00:00.0000'.Allerdings hätte '2016-12-25' genau den gleichen Effekt, mit weniger Tastenanschlägen!

TIME

Syntax
TIME [{ WITHOUT | WITH } TIME ZONE]

Für die reine Zeit TIME, ist WITHOUT TIME ZONE.

Der Datentyp TIME ist nur in Dialekt 3 verfügbar.Es speichert die Tageszeit im Bereich von 00:00:00.0000 bis 23:59:59,9999.

Wenn Sie den Zeitteil von DATE in Dialekt 1 benötigen, können Sie die EXTRACT-Funktion verwenden.

Beispiele für die Verwendung von EXTRACT()
EXTRACT (HOUR FROM DATE_FIELD)
EXTRACT (MINUTE FROM DATE_FIELD)
EXTRACT (SECOND FROM DATE_FIELD)

Siehe auch EXTRACT()-Funktion im Kapitel Eingebaute Funktionen.

TIME [WITHOUT TIME ZONE]

TIME (oder Synonym TIME WITHOUT TIME ZONE) repräsentiert eine Zeit ohne Zeitzoneninformationen.

TIME WITH TIME ZONE

TIME WITH TIME ZONE repräsentiert eine Zeit mit Zeitzoneninformationen (entweder ein Offset oder eine benannte Zone).

Firebird verwendet die ICU-Implementierung der IANA-Zeitzonendatenbank für benannte Zonen.

Beispiele mit EXTRACT()
EXTRACT (TIMEZONE_HOUR FROM TIME_TZ_FIELD)
EXTRACT (TIMEZONE_MINUTE FROM TIME_TZ_FIELD)

TIMESTAMP

Syntax
TIMESTAMP [{ WITHOUT | WITH } TIME ZONE]

Für den reinen Zeitstempel TIMESTAMP, ist WITHOUT TIME ZONE vorgesehen.

Der Datentyp TIMESTAMP ist in Dialekt 3 und Dialekt 1 verfügbar.Es besteht aus zwei 32-Bit-Wörtern – einem Datumsteil und einem Zeitteil – um eine Struktur zu bilden, die sowohl Datum als auch Uhrzeit speichert.Es ist das gleiche wie der Typ DATE in Dialekt 1.

Die Funktion EXTRACT funktioniert mit TIMESTAMP genauso gut wie mit dem Dialekt 1 DATE-Typ.

TIMESTAMP [WITHOUT TIME ZONE]

TIMESTAMP (oder das Synonym TIMESTAMP WITHOUT TIME ZONE) repräsentiert Zeit und Datum ohne eine Zeitzoneninformation.

TIMESTAMP WITH TIME ZONE

TIMESTAMP WITH TIME ZONE repräsentiert eine Zeit mit einer Zeitzoneninformation (als Offset oder benannte Zone).

Sitzungszeitzone

Wie der Name schon sagt, kann die Sitzungszeitzone für jeden Datenbankanhang unterschiedlich sein.Sie kann explizit im DPB mit dem Item isc_dpb_session_time_zone gesetzt werden;andernfalls verwendet es standardmäßig dieselbe Zeitzone wie das Betriebssystem des Firebird-Serverprozesses.Diese Vorgabe kann in firebird.conf überschrieben werden, indem DefaultTimeZone eingestellt wird.

Note

Treiber können unterschiedliche Standardwerte anwenden, beispielsweise die Client-Zeitzone als Standard-Sitzungszeitzone angeben.Weitere Informationen finden Sie in Ihrer Treiberdokumentation.

Anschließend kann die Zeitzone mit einem SET TIME ZONE-Statement auf eine vorgegebene Zeitzone geändert oder mit SET TIME ZONE LOCAL auf den ursprünglichen Wert zurückgesetzt werden.

Zeitzonenformat

Eine Zeitzone wird als Zeichenfolge angegeben, entweder eine Zeitzonenregion (z. B. 'America/Sao_Paulo') oder eine Verschiebung von GMT in Stunden:Minuten (z. B. ’-03:00' `).

Eine Zeit/ein Zeitstempel mit Zeitzone wird mit einer anderen Zeit/einem anderen Zeitstempel mit Zeitzone gleichgesetzt, wenn ihre Umrechnungen in UTC äquivalent sind.Zum Beispiel sind time '10:00 -02:00' und time '09:00 -03:00' äquivalent, da beide gleich time '12:00 GMT' sind.

Important

Die gleiche Äquivalenz gilt in UNIQUE-Beschränkungen und für Sortierzwecke.

Operationen mit Datums- und Uhrzeitwerten

Die Methode der Speicherung von Datums- und Uhrzeitwerten ermöglicht es, diese als Operanden in einige arithmetische Operationen einzubeziehen.Im Speicher wird ein Datumswert oder ein Datumsteil eines Zeitstempels als die Anzahl von Tagen dargestellt, die seit “Datum Null” - 17. November 1898 - verstrichen sind, während ein Zeitwert oder der Zeitteil eines Zeitstempels dargestellt wird als Anzahl der Sekunden (mit Berücksichtigung von Sekundenbruchteilen) seit Mitternacht.

Ein Beispiel ist das Subtrahieren eines früheren Datums, einer früheren Zeit oder eines Zeitstempels von einem späteren, was zu einem Zeitintervall in Tagen und Bruchteilen von Tagen führt.

Table 1. Arithmetische Operationen für Datums- und Uhrzeitdatentypen
Operand 1 Operation Operand 2 Ergebnis

DATE

+

TIME

TIMESTAMP

DATE

+

TIME WITH TIME ZONE

TIMESTAMP WITH TIME ZONE

DATE

+

Numerischer Wert n

DATE um n ganze Tage erhöht.Gebrochene Werte werden auf die nächste Ganzzahl gerundet (nicht abgeschnitten).

TIME

+

DATE

TIMESTAMP

TIME WITH TIME ZONE

+

DATE

TIMESTAMP WITH TIME ZONE

TIME

+

Numerischer Wert n

TIME um n Sekunden erhöht.Bruchteile werden berücksichtigt.

TIME WITH TIME ZONE

+

Numeric value n

TIME WITH TIME ZONE um n Sekunden erhöht.Der Bruchteil wird berücksichtigt

TIMESTAMP

+

Numerischer Wert n

TIMESTAMP, wobei das Datum um die Anzahl der Tage und der Teil eines Tages durch die Zahl n repräsentiert wird — somit wird “+ 2.75” das Datum um 2 Tage und 18 Stunden weiterstellen wird

TIMESTAMP WITH TIME ZONE

+

Numerischer Wert n

TIMESTAMP WITH TIME ZONE, wobei das Datum um die Anzahl der Tage und ein Teil eines Tages, dargestellt durch die Zahl n, vorrückt — also wird “+ 2.75” das Datum um 2 Tage und 18 Std. vorrücken

DATE

-

DATE

Anzahl der vergangenen Tage innerhalb des Bereichs DECIMAL(9, 0)

DATE

-

Numerischer Wert n

DATE um n ganze Tage reduziert.Gebrochene Werte werden auf die nächste Ganzzahl gerundet (nicht abgeschnitten).

TIME

-

TIME

Anzahl der vergangenen Sekunden, innerhalb des Bereichs DECIMAL(9, 4)

TIME

-

TIME WITH TIME ZONE

Der Wert ohne Zeitzone wird in WITH TIME ZONE in der aktuellen Sitzungszeitzone umgewandelt.Anzahl der zwischen den UTC-Werten verstrichenen Sekunden im Bereich DECIMAL(9, 4).Gilt auch beim Typentausch.

TIME WITH TIME ZONE

-

TIME WITH TIME ZONE

Anzahl der zwischen den UTC-Werten verstrichenen Sekunden im Bereich DECIMAL(9, 4)

TIME

-

Numerischer Wert n

TIME um n Sekunden reduziert.Bruchteile werden berücksichtigt.

TIMESTAMP

-

TIMESTAMP

Anzahl der Tage und der Tageszeit, innerhalb des Bereichs DECIMAL(18, 9)

TIMESTAMP

-

TIMESTAMP WITH TIME ZONE

Der Wert ohne Zeitzone wird in WITH TIME ZONE in der aktuellen Sitzungszeitzone umgewandelt.Anzahl der Tage und Teiltage zwischen UTC-Werten im Bereich DECIMAL(18, 9).Gilt auch beim Tausch der Datentypen.

TIMESTAMP WITH TIME ZONE

-

TIMESTAMP WITH TIME ZONE

Anzahl der Tage und Teiltage zwischen UTC-Werten im Bereich DECIMAL(18, 9)

TIMESTAMP

-

Numerischer Wert n

TIMESTAMP wobei das Datum sich auf der Anzahl der Tage und der Tageszeit beruht, die durch die Zahl n repräsentiert wird — somit wird “- 2.25” das Datum um 2 Tage und 6 Stunden reduzieren.

Note
Hinweise

Der Typ DATE wird in Dialekt 1 als TIMESTAMP betrachtet.

Siehe auch

DATEADD, DATEDIFF

Zusätzliche Zeitzonenfunktionen

Firebird 4.0 bietet eine Reihe von Funktionen zum Ermitteln von Zeitzoneninformationen.

Virtuelle Tabelle RDB$TIME_ZONES

Eine virtuelle Tabelle, die die von der Engine unterstützten Zeitzonen auflistet.

Siehe auch RDB$TIME_ZONES in Systemtabellen.

Paket RDB$TIME_ZONE_UTIL

Ein Paket von Zeitzonen-Dienstprogrammfunktionen und -prozeduren:

Funktion DATABASE_VERSION

RDB$TIME_ZONE_UTIL.DATABASE_VERSION gibt die Version der Zeitzonendatenbank als VARCHAR(10) CHARACTER SET ASCII zurück.

Beispiel
select rdb$time_zone_util.database_version() from rdb$database;

Returns:

DATABASE_VERSION
================
2021a
Prozedur TRANSITIONS

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)

Beispiel
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

Aktualisieren der Zeitzonendatenbank

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

/tzdata ist das Standardverzeichnis, in dem Firebird nach der Zeitzonendatenbank sucht.Sie kann mit der Umgebungsvariablen ICU_TIMEZONE_FILES_DIR überschrieben werden.

Zeichendatentypen

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.

Unicode

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 WIN1251 belegen 2 Byte in UTF8, Zeichen anderer Codierungen können bis zu 4 Byte belegen.

Der in Firebird implementierte UTF8-Zeichensatz unterstützt die neueste Version des Unicode-Standards und empfiehlt daher seine Verwendung für internationale Datenbanken.

Client-Zeichensatz

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.

Sonderzeichensätze

Zeichensatz 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.

Zeichensatz 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.

Sortierreihenfolge

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 collation-Klausel in der Spaltendefinition angegeben werden.

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.

Suche ohne Berücksichtigung der Groß-/Kleinschreibung

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
Siehe auch

CONTAINING

UTF8-Sortierreihenfolgen

Die folgende Tabelle zeigt die möglichen Sortierfolgen für den Zeichensatz UTF8.

Table 1. Sortierfolgen für Zeichensatz UTF8
Kollation Eigenschaften

UCS_BASIC

Die Sortierung funktioniert nach der Position des Zeichens in der Tabelle (binär).In Firebird 2.0 hinzugefügt

UNICODE

Die Sortierung funktioniert nach dem UCA-Algorithmus (Unicode Collation Algorithm) (alphabetisch).In Firebird 2.0 hinzugefügt

UTF8

Die standardmäßige, binäre Sortierung, identisch mit UCS_BASIC, die aus Gründen der SQL-Kompatibilität hinzugefügt wurde

UNICODE_CI

Sortierung ohne Berücksichtigung der Groß-/Kleinschreibung, funktioniert ohne Berücksichtigung der Groß-/Kleinschreibung.Hinzugefügt in Firebird 2.1

UNICODE_CI_AI

Groß-/Kleinschreibung, akzentunabhängige Sortierung, arbeitet alphabetisch ohne Berücksichtigung von Groß-/Kleinschreibung oder Akzenten.Hinzugefügt in Firebird 2.5

Beispiel

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

Zeichenindizes

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.

Berechnen der maximalen Länge eines indizierten Zeichenfolgenfelds

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.

Table 1. Maximale Indexlängen nach Seitengröße und Zeichengröße

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.

Zeichenarten im Detail

BINARY

Datentyp-Deklarationsformat
BINARY [(length)]
Table 1. BINARY-Datentypparameter
Parameter Beschreibung

length

Länge in Byte zwischen 1 und 32.767;standardmäßig 1.

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 CHARACTER SET OCTETS anstelle von BINARY zurück.

CHAR

Data Type Declaration Format
{CHAR | CHARACTER} [(length)]
  [CHARACTER SET <set>] [COLLATE <name>]
Table 1. CHAR-Datentypparameter
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
  • Seit Firebird 4.0 hat CHAR CHARACTER SET OCTETS den Alias BINARY

  • Formal ist die COLLATE-Klausel nicht Teil der Datentyp-Deklaration und ihre Position hängt von der Syntax der Anweisung ab.

VARBINARY

Datentyp-Deklarationsformat
{VARBINARY | BINARY VARYING} (length)
Table 1. VARBINARY-Datentypparameter
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 CHARACTER SET OCTETS statt als VARBINARY zurück.

VARCHAR

Datentyp-Deklarationsformat
{VARCHAR | {CHAR | CHARACTER} VARYING} (length)
  [CHARACTER SET <set>] [COLLATE <name>]
Table 1. VARCHAR-Datentypparameter
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
  • Seit Firebird 4.0 hat VARCHAR CHARACTER SET OCTETS den Alias VARBINARY

  • Formal ist die COLLATE-Klausel nicht Teil der Datentyp-Deklaration und ihre Position hängt von der Syntax der Anweisung ab.

NCHAR

Datentyp-Deklarationsformat
{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-Datentyp

BOOLEAN

Datentyp-Deklarationsformat
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.

Der IS-Operator

Prädikate können den Operator Boolean IS [NOT] zum Abgleich verwenden.Zum Beispiel field1 IS FALSE oder field1 IS NOT TRUE.

Note
  • Äquivalenzoperatoren (“=”, “!=”, “<>” und so weiter) sind in allen Vergleichen gültig.

BOOLEAN-Beispiele

  1. Einfü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>
  2. Test auf Wert TRUE

    SELECT * FROM TBOOL WHERE BVAL;
              ID    BVAL
    ============ =======
               1 <true>
  3. Test auf Wert FALSE

    SELECT * FROM TBOOL WHERE BVAL IS FALSE;
              ID    BVAL
    ============ =======
               2 <false>
  4. Test auf Wert UNKNOWN

    SELECT * FROM TBOOL WHERE BVAL IS UNKNOWN;
              ID    BVAL
    ============ =======
               3 <null>
  5. 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>
  6. PSQL-Deklaration mit Startwert

    DECLARE VARIABLE VAR1 BOOLEAN = TRUE;
  7. 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;
Verwendung von Boolean gegen andere Datentypen

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
  • Der Typ wird in der API mit dem Typ FB_BOOLEAN und den Konstanten FB_TRUE und FB_FALSE dargestellt.

  • Der Wert TRUE ist größer als der Wert FALSE.

Binärdatentypen

BLOBs (Binary Large Objects) sind komplexe Strukturen, die verwendet werden, um Text und binäre Daten undefinierter Länge, oft sehr groß, zu speichern.

Syntax
BLOB [SUB_TYPE <subtype>]
  [SEGMENT SIZE <segment size>]
  [CHARACTER SET <character set>]
  [COLLATE <collation name>]
Verkürzte Syntax
BLOB (<segment size>)
BLOB (<segment size>, <subtype>)
BLOB (, <subtype>)
Note

Formal ist die COLLATE-Klausel nicht Teil der Datentyp-Deklaration und ihre Position hängt von der Syntax der Anweisung ab.

Segmentgröße
Die Angabe der BLOB-Segmentgröße ist ein Rückfall in vergangene Zeiten, als Anwendungen zum Arbeiten mit BLOB-Daten in C (Embedded SQL) mit Hilfe des Pre-Compilers gpre geschrieben wurden. Heutzutage ist es praktisch irrelevant. Die Segmentgröße für BLOB-Daten wird von der Clientseite bestimmt und ist in der Regel auf jeden Fall größer als die Datenseitengröße.

BLOB-Untertypen

Der optionale Parameter SUB_TYPE gibt die Art der in die Spalte geschriebenen Daten an.Firebird bietet zwei vordefinierte Untertypen zum Speichern von Benutzerdaten:

Subtyp 0: 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.

Untertyp 1: 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.

Benutzerdefinierte Untertypen

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-Besonderheiten

Größe

Die 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 BLOBs 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.

Operationen und Ausdrücke

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)

BETWEEN,

IS [NOT] DISTINCT FROM,

IN,

ANY | SOME,

ALL

 

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:

    STARTING [WITH],

    LIKE,

    CONTAINING

     

  • Aggregationsklauseln wirken sich nicht auf den Inhalt des Feldes selbst aus, sondern auf die BLOB-ID. Abgesehen davon gibt es einige Macken:

    SELECT DISTINCT

    gibt fälschlicherweise mehrere NULL-Werte zurück, wenn sie vorhanden sind

    ORDER BY

     — 

    GROUP BY

    verkettet dieselben Zeichenfolgen, wenn sie nebeneinander liegen, tut dies jedoch nicht, wenn sie voneinander entfernt sind

BLOB-Speicher
  • Standardmäß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.

Beispiel
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.

Angeben von expliziten Grenzen für Bemaßungen

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> ']'

Hinzufügen weiterer Dimensionen

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:

PSQL-Quelle für SHOW_LANGS, eine Prozedur mit einem Array

CREATE 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

“Spezielle” Datentypen …​

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 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)

Der Benutzer hat das Feld leer gelassen

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.

Konvertierung von Datentypen

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.

Explizite Datentypkonvertierung

Die CAST-Funktion ermöglicht die explizite Konvertierung zwischen vielen Paaren von Datentypen.

Syntax
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.

Casting auf eine Domain

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.

Casting in 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.

Beispiel
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;

Konvertierungen für die CAST-Funktion möglich

Table 1. Umwandlungen mit CAST
Von Datentyp Zu Datentyp

Numerische Typen

Numerische Typen, [VAR]CHAR, BLOB

[VAR]CHAR

[VAR]CHAR, BLOB, Numerische Typen, DATE, TIME, TIMESTAMP, BOOLEAN

BLOB

[VAR]CHAR, BLOB, Numerische Typen, DATE, TIME, TIMESTAMP, BOOLEAN

DATE, TIME

[VAR]CHAR, BLOB, TIMESTAMP

TIMESTAMP

[VAR]CHAR, BLOB, DATE, TIME

BOOLEAN

BOOLEAN, [VAR]CHAR, BLOB

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 TIMESTAMP in den Datentyp DATE umwandeln, geht der Zeitteil verloren.

Datum-Zeit-Formate

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),

Table 1. Vordefinierte Datum/Uhrzeit-Mnemonik

Literal

Beschreibung

'NOW'

Aktuelle Zeit und Datum

'TODAY'

Aktuelles Datum

'TOMORROW'

Aktuelles Datum + 1 (Tag)

'YESTERDAY'

Aktuelles Datum - 1 (Tag)

Note

Das Umwandeln der Datumsmnemonik 'TODAY', 'TOMORROW' oder 'YESTERDAY' in einen TIMESTAMP WITH TIME ZONE erzeugt einen Wert um 00:00:00 UTC, basierend auf der Sitzungszeitzone.

Zum Beispiel erzeugt cast('TODAY' as timestamp with time zone) on 2021-05-02 20:00 - 2021-05-03 19:59 New York (oder 2021-05-03 00:00 - 2021-05- 03 23:59 UTC) mit der Sitzungszeitzone America/New_York den Wert TIMESTAMP '2021-05-02 20:00:00.0000 America/New_York'. Dementgegen erzeugt cast('TODAY' as date) oder CURRENT_DATE ` je nach aktuellem Datum entweder `DATE '2021-05-02' oder DATE '2021-05-03'.

Wörtliche Interpretationen des Beispieldatums
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

Kurzformumwandlungen für Datums- und Zeitdatentypen

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.

Syntax
<data_type> 'date_format_string'
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 'NOW' zu unerwarteten oder verwirrenden Ergebnissen führte, insbesondere in PSQL-Code, sind die Datetime-Mnemoniken in Datetime-Literalen seit Firebird 4.0 nicht mehr erlaubt.

Um Datetime-Mnemonik zu verwenden, verwenden Sie die vollständige CAST-Syntax.Ein Beispiel für die Verwendung eines solchen Ausdrucks in einem Trigger:

NEW.CHANGE_DATE = CAST('now' AS TIMESTAMP);

Implizite Datentypkonvertierung

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.

Implizite Konvertierung während der String-Verkettung

Wenn mehrere Datenelemente verkettet werden, werden alle Nicht-String-Daten nach Möglichkeit implizit in Strings umgewandelt.

Beispiel
SELECT 30||' days hath September, April, June and November' CONCAT$
  FROM RDB$DATABASE;

CONCAT$
------------------------------------------------
30 days hath September, April, June and November