FirebirdSQL logo

CREATE TABLE

Verwendet für

Erstellen einer neuen Tabelle (Relation)

Verfügbar in

DSQL, ESQL

Syntax
CREATE [GLOBAL TEMPORARY] TABLE tablename
  [EXTERNAL [FILE] 'filespec']
  (<col_def> [, {<col_def> | <tconstraint>} ...])
  [{<table_attrs> | <gtt_table_attrs>}]

<col_def> ::=
    <regular_col_def>
  | <computed_col_def>
  | <identity_col_def>

<regular_col_def> ::=
  colname {<datatype> | domainname}
  [DEFAULT {<literal> | NULL | <context_var>}]
  [<col_constraint> ...]
  [COLLATE collation_name]

<computed_col_def> ::=
  colname [{<datatype> | domainname}]
  {COMPUTED [BY] | GENERATED ALWAYS AS} (<expression>)

<identity_col_def> ::=
  colname {<datatype> | domainname}
  GENERATED {ALWAYS | BY DEFAULT} AS IDENTITY
  [(<identity_col_option>...)]
  [<col_constraint> ...]

<identity_col_option> ::=
    START WITH start_value
  | INCREMENT [BY] inc_value

<datatype> ::=
    <scalar_datatype> | <blob_datatype> | <array_datatype>

<scalar_datatype> ::=
  !! Siehe auch Skalardatentypensyntax !!

<blob_datatype> ::=
  !! Siehe auch BLOB-Datentypensyntax !!

<array_datatype> ::=
  !! Siehe auch Array-Datentypensyntax !!

<col_constraint> ::=
  [CONSTRAINT constr_name]
    { PRIMARY KEY [<using_index>]
    | UNIQUE      [<using_index>]
    | REFERENCES other_table [(colname)] [<using_index>]
        [ON DELETE {NO ACTION | CASCADE | SET DEFAULT | SET NULL}]
        [ON UPDATE {NO ACTION | CASCADE | SET DEFAULT | SET NULL}]
    | CHECK (<check_condition>)
    | NOT NULL }

<tconstraint> ::=
  [CONSTRAINT constr_name]
    { PRIMARY KEY (<col_list>) [<using_index>]
    | UNIQUE      (<col_list>) [<using_index>]
    | FOREIGN KEY (<col_list>)
        REFERENCES other_table [(<col_list>)] [<using_index>]
        [ON DELETE {NO ACTION | CASCADE | SET DEFAULT | SET NULL}]
        [ON UPDATE {NO ACTION | CASCADE | SET DEFAULT | SET NULL}]
    | CHECK (<check_condition>) }

<col_list> ::= colname [, colname ...]

<using_index> ::= USING
  [ASC[ENDING] | DESC[ENDING]] INDEX indexname

<check_condition> ::=
    <val> <operator> <val>
  | <val> [NOT] BETWEEN <val> AND <val>
  | <val> [NOT] IN (<val> [, <val> ...] | <select_list>)
  | <val> IS [NOT] NULL
  | <val> IS [NOT] DISTINCT FROM <val>
  | <val> [NOT] CONTAINING <val>
  | <val> [NOT] STARTING [WITH] <val>
  | <val> [NOT] LIKE <val> [ESCAPE <val>]
  | <val> [NOT] SIMILAR TO <val> [ESCAPE <val>]
  | <val> <operator> {ALL | SOME | ANY} (<select_list>)
  | [NOT] EXISTS (<select_expr>)
  | [NOT] SINGULAR (<select_expr>)
  | (<check_condition>)
  | NOT <check_condition>
  | <check_condition> OR <check_condition>
  | <check_condition> AND <check_condition>

<operator> ::=
    <> | != | ^= | ~= | = | < | > | <= | >=
  | !< | ^< | ~< | !> | ^> | ~>

<val> ::=
    colname ['['array_idx [, array_idx ...]']']
  | <literal>
  | <context_var>
  | <expression>
  | NULL
  | NEXT VALUE FOR genname
  | GEN_ID(genname, <val>)
  | CAST(<val> AS <cast_type>)
  | (<select_one>)
  | func([<val> [, <val> ...]])

<cast_type> ::= <domain_or_non_array_type> | <array_datatype>

<domain_or_non_array_type> ::=
  !! Siehe Skalardatentypensyntax !!

<table_attrs> ::= <table_attr> [<table_attr> ...]

<table_attr> ::=
    <sql_security>
  | {ENABLE | DISABLE} PUBLICATION

<sql_security> ::= SQL SECURITY {INVOKER | DEFINER}

<gtt_table_attrs> ::= <gtt_table_attr> [gtt_table_attr> ...]

<gtt_table_attr> ::=
    <sql_security>
  | ON COMMIT {DELETE | PRESERVE} ROWS
Table 1. CREATE TABLE-Anweisungsparameter
Parameter Beschreibung

tablename

Name (Bezeichner) für die Tabelle.Sie darf bis zu 63 Zeichen lang sein und muss in der Datenbank eindeutig sein.

filespec

Dateispezifikation (nur für externe Tabellen).Vollständiger Dateiname und Pfad in einfachen Anführungszeichen, korrekt für das lokale Dateisystem und auf einem Speichergerät, das physisch mit dem Host-Computer von Firebird verbunden ist.

colname

Name (Bezeichner) für eine Spalte in der Tabelle.Darf bis zu 3 Zeichen lang sein und muss in der Tabelle eindeutig sein.

tconstraint

Tabellenbeschränkung

table_attrs

Attribute einer normalen Tabelle

gtt_table_attrs

Attribute einer globalen temporären Tabelle

datatype

SQL-Datentyp

domain_name

Domainname

start_value

Der Anfangswert der Identitätsspalte

inc_value

Der Inkrement- (oder Schritt-)Wert der Identitätsspalte, der Standardwert ist '1';Null (0) ist nicht erlaubt.

col_constraint

Spaltenbeschränkung

constr_name

Der Name (Bezeichner) einer Einschränkung.Kann aus bis zu 63 Zeichen bestehen.

other_table

Der Name der Tabelle, auf die von der Fremdschlüsseleinschränkung verwiesen wird

other_col

Der Name der Spalte in other_table, auf die der Fremdschlüssel verweist

literal

Ein Literalwert, der im angegebenen Kontext zulässig ist

context_var

Jede Kontextvariable, deren Datentyp im angegebenen Kontext zulässig ist

check_condition

Die auf eine CHECK-Einschränkung angewendete Bedingung, die entweder als wahr, falsch oder NULL aufgelöst wird

collation

Collation

select_one

Eine skalare SELECT-Anweisung – Auswahl einer Spalte und Rückgabe nur einer Zeile

select_list

Eine SELECT-Anweisung, die eine Spalte auswählt und null oder mehr Zeilen zurückgibt

select_expr

Eine SELECT-Anweisung, die eine oder mehrere Spalten auswählt und null oder mehr Zeilen zurückgibt

expression

Ein Ausdruck, der zu einem Wert auflöst, der im gegebenen Kontext zulässig ist

genname

Name der Sequenz (Generator)

func

Interne Funktion oder UDF

Die Anweisung CREATE TABLE erstellt eine neue Tabelle.Jeder Benutzer kann es erstellen und sein Name muss unter den Namen aller Tabellen, Ansichten und gespeicherten Prozeduren in der Datenbank eindeutig sein.

Eine Tabelle muss mindestens eine nicht berechnete Spalte enthalten, und die Namen der Spalten müssen in der Tabelle eindeutig sein.

Eine Spalte muss entweder einen expliziten SQL-Datentyp haben, den Namen einer Domäne, deren Attribute für die Spalte kopiert werden, oder als COMPUTED BY einen Ausdruck (ein berechnetes Feld) definiert sein.

Eine Tabelle kann eine beliebige Anzahl von Tabelleneinschränkungen haben, einschließlich keiner.

Zeichenspalten

Sie können die Klausel CHARACTER SET verwenden, um den Zeichensatz für die Typen CHAR, VARCHAR und BLOB (Textsubtyp) anzugeben.Wenn der Zeichensatz nicht angegeben ist, wird der Standardzeichensatz der Datenbank - zum Zeitpunkt der Erstellung der Spalte - verwendet.Wenn die Datenbank keinen Standardzeichensatz hat, wird der Zeichensatz NONE angewendet.In diesem Fall werden die Daten so gespeichert und abgerufen, wie sie übermittelt wurden.Einer solchen Spalte können Daten in einer beliebigen Codierung hinzugefügt werden, es ist jedoch nicht möglich, diese Daten einer Spalte mit einer anderen Codierung hinzuzufügen.Zwischen den Quell- und Zielkodierungen wird keine Transliteration durchgeführt, was zu Fehlern führen kann.

Mit der optionalen COLLATE-Klausel können Sie die Kollatierungssequenz für Zeichendatentypen angeben, einschließlich BLOB SUB_TYPE TEXT.Wenn keine Kollatierungssequenz angegeben ist, wird die Standardkollatierungssequenz für den angegebenen Zeichensatz - zum Zeitpunkt der Erstellung der Spalte - angewendet.

docnext count = 58

Wer kann eine Tabelle erstellen

Die CREATE TABLE-Anweisung kann ausgeführt werden durch:

Der Benutzer, der die Anweisung CREATE TABLE ausführt, wird Eigentümer der Tabelle.

CREATE TABLE-Beispiele

  1. Erstellen der Tabelle COUNTRY mit dem als Spalteneinschränkung angegebenen Primärschlüssel.

    CREATE TABLE COUNTRY (
      COUNTRY COUNTRYNAME NOT NULL PRIMARY KEY,
      CURRENCY VARCHAR(10) NOT NULL
    );
  2. Erstellen der Tabelle STOCK mit dem benannten Primärschlüssel, der auf Spaltenebene angegeben ist, und dem benannten eindeutigen Schlüssel, der auf Tabellenebene angegeben ist.

    CREATE TABLE STOCK (
      MODEL     SMALLINT NOT NULL CONSTRAINT PK_STOCK PRIMARY KEY,
      MODELNAME CHAR(10) NOT NULL,
      ITEMID    INTEGER NOT NULL,
      CONSTRAINT MOD_UNIQUE UNIQUE (MODELNAME, ITEMID)
    );
  3. Erstellen der Tabelle JOB mit einer Primärschlüssel-Einschränkung, die sich über zwei Spalten erstreckt, einer Fremdschlüssel-Einschränkung für die Tabelle "COUNTRY" und einer "CHECK"-Einschränkung auf Tabellenebene.Die Tabelle enthält auch ein Array von 5 Elementen.

    CREATE TABLE JOB (
      JOB_CODE        JOBCODE NOT NULL,
      JOB_GRADE       JOBGRADE NOT NULL,
      JOB_COUNTRY     COUNTRYNAME,
      JOB_TITLE       VARCHAR(25) NOT NULL,
      MIN_SALARY      NUMERIC(18, 2) DEFAULT 0 NOT NULL,
      MAX_SALARY      NUMERIC(18, 2) NOT NULL,
      JOB_REQUIREMENT BLOB SUB_TYPE 1,
      LANGUAGE_REQ    VARCHAR(15) [1:5],
      PRIMARY KEY (JOB_CODE, JOB_GRADE),
      FOREIGN KEY (JOB_COUNTRY) REFERENCES COUNTRY (COUNTRY)
      ON UPDATE CASCADE
      ON DELETE SET NULL,
      CONSTRAINT CHK_SALARY CHECK (MIN_SALARY < MAX_SALARY)
    );
  4. Erstellen der Tabelle PROJECT mit Einschränkungen für Primär-, Fremd- und eindeutige Schlüssel mit benutzerdefinierten Indexnamen, die mit der Klausel "USING" angegeben werden.

    CREATE TABLE PROJECT (
      PROJ_ID     PROJNO NOT NULL,
      PROJ_NAME   VARCHAR(20) NOT NULL UNIQUE USING DESC INDEX IDX_PROJNAME,
      PROJ_DESC   BLOB SUB_TYPE 1,
      TEAM_LEADER EMPNO,
      PRODUCT     PRODTYPE,
      CONSTRAINT PK_PROJECT PRIMARY KEY (PROJ_ID) USING INDEX IDX_PROJ_ID,
      FOREIGN KEY (TEAM_LEADER) REFERENCES EMPLOYEE (EMP_NO)
        USING INDEX IDX_LEADER
    );
  5. Erstellen einer Tabelle mit einer Identitätsspalte

    create table objects (
      id integer generated by default as identity primary key,
      name varchar(15)
    );
    
    insert into objects (name) values ('Table');
    insert into objects (id, name) values (10, 'Computer');
    insert into objects (name) values ('Book');
    
    select * from objects order by id;
    
              ID NAME
    ============ ===============
               1 Table
               2 Book
              10 Computer
  6. Erstellen der Tabelle SALARY_HISTORY mit zwei berechneten Feldern.Das erste wird gemäß dem SQL:2003-Standard deklariert, während das zweite gemäß der traditionellen Deklaration von berechneten Feldern in Firebird deklariert wird.

    CREATE TABLE SALARY_HISTORY (
      EMP_NO         EMPNO NOT NULL,
      CHANGE_DATE    TIMESTAMP DEFAULT 'NOW' NOT NULL,
      UPDATER_ID     VARCHAR(20) NOT NULL,
      OLD_SALARY     SALARY NOT NULL,
      PERCENT_CHANGE DOUBLE PRECISION DEFAULT 0 NOT NULL,
      SALARY_CHANGE  GENERATED ALWAYS AS
        (OLD_SALARY * PERCENT_CHANGE / 100),
      NEW_SALARY     COMPUTED BY
        (OLD_SALARY + OLD_SALARY * PERCENT_CHANGE / 100)
    );
  7. Wenn DEFINER für die Tabelle t gesetzt ist, benötigt der Benutzer US nur das SELECT-Privileg auf t.Wenn es auf INVOKER gesetzt wäre, würde der Benutzer auch das EXECUTE-Privileg für die Funktion f benötigen.

    set term ^;
    create function f() returns int
    as
    begin
        return 3;
    end^
    set term ;^
    create table t (i integer, c computed by (i + f())) SQL SECURITY DEFINER;
    insert into t values (2);
    grant select on table t to user us;
    
    commit;
    
    connect 'localhost:/tmp/7.fdb' user us password 'pas';
    select * from t;
  8. Wenn DEFINER für die Tabelle tr gesetzt ist, benötigt der Benutzer US nur das INSERT-Privileg auf tr.Wenn es auf INVOKER gesetzt wäre, bräuchte entweder der Benutzer oder der Trigger auch das INSERT-Privileg für die Tabelle t.Das Ergebnis wäre dasselbe, wenn SQL SECURITY DEFINER für den Trigger tr_ins angegeben würde:

    create table tr (i integer) SQL SECURITY DEFINER;
    create table t (i integer);
    set term ^;
    create trigger tr_ins for tr after insert
    as
    begin
      insert into t values (NEW.i);
    end^
    set term ;^
    grant insert on table tr to user us;
    
    commit;
    
    connect 'localhost:/tmp/29.fdb' user us password 'pas';
    insert into tr values(2);

Global Temporary Tables (GTT)

Globale temporäre Tabellen verfügen über persistente Metadaten, ihr Inhalt ist jedoch transaktionsgebunden (Standard) oder verbindungsgebunden.Jede Transaktion oder Verbindung hat ihre eigene private Instanz einer GTT, die von allen anderen isoliert ist.Instanzen werden nur erstellt, wenn und wenn auf die GTT verwiesen wird.Sie werden zerstört, wenn die Transaktion endet oder wenn die Verbindung getrennt wird.Die Metadaten einer GTT können mit ALTER TABLE bzw. DROP TABLE geändert oder entfernt werden.

Syntax
CREATE GLOBAL TEMPORARY TABLE tablename
  (<column_def> [, {<column_def> | <table_constraint>} ...])
  [<gtt_table_attrs>]

<gtt_table_attrs> ::= <gtt_table_attr> [gtt_table_attr> ...]

<gtt_table_attr> ::=
    <sql_security>
  | ON COMMIT {DELETE | PRESERVE} ROWS
Note
Syntax notes
  • ON COMMIT DELETE ROWS erstellt eine GTT auf Transaktionsebene (Standard), ON COMMIT PRESERVE ROWS eine GTT auf Verbindungsebene

  • Eine EXTERNAL [FILE]-Klausel ist in der Definition einer globalen temporären Tabelle nicht erlaubt

GTTs sind in schreibgeschützten Transaktionen beschreibbar.Die Wirkung ist wie folgt:

Schreibgeschützte Transaktion in der Datenbank mit Lese-/Schreibzugriff

Schreibbar in ON COMMIT PRESERVE ROWS und ON COMMIT DELETE ROWS

Schreibgeschützte Transaktion in schreibgeschützter Datenbank

Nur in ON COMMIT DELETE ROWS beschreibbar

Einschränkungen für GTTs

GTTs können mit allen Funktionen und Utensilien gewöhnlicher Tabellen (Schlüssel, Referenzen, Indizes, Trigger usw.) “aufgeputzt” werden, aber es gibt einige Einschränkungen:

  • GTTs und reguläre Tabellen können nicht aufeinander verweisen

  • Eine verbindungsgebundene (“PRESERVE ROWS”) GTT kann nicht auf eine transaktionsgebundene (“DELETE ROWS”) GTT verweisen

  • Domäneneinschränkungen können keine GTT referenzieren

  • Die Zerstörung einer GTT-Instanz am Ende ihres Lebenszyklus führt nicht zum Auslösen von BEFORE/AFTER Delete-Triggern

Tip

In einer bestehenden Datenbank ist es nicht immer einfach, eine reguläre Tabelle von einer GTT oder eine GTT auf Transaktionsebene von einer GTT auf Verbindungsebene zu unterscheiden.Verwenden Sie diese Abfrage, um herauszufinden, welche Art von Tabelle Sie betrachten:

select t.rdb$type_name
from rdb$relations r
join rdb$types t on r.rdb$relation_type = t.rdb$type
where t.rdb$field_name = 'RDB$RELATION_TYPE'
and r.rdb$relation_name = 'TABLENAME'

Für einen Überblick über die Typen aller Relationen in der Datenbank:

select r.rdb$relation_name, t.rdb$type_name
from rdb$relations r
join rdb$types t on r.rdb$relation_type = t.rdb$type
where t.rdb$field_name = 'RDB$RELATION_TYPE'
and coalesce (r.rdb$system_flag, 0) = 0

Das Feld RDB$TYPE_NAME zeigt PERSISTENT für eine reguläre Tabelle, VIEW für eine Ansicht, GLOBAL_TEMPORARY_PRESERVE für eine verbindungsgebundene GTT und GLOBAL_TEMPORARY_DELETE für eine transaktionsgebundene GTT.

Beispiele für globale temporäre Tabellen

  1. Erstellen einer globalen temporären Tabelle mit Verbindungsbereich.

    CREATE GLOBAL TEMPORARY TABLE MYCONNGTT (
      ID  INTEGER NOT NULL PRIMARY KEY,
      TXT VARCHAR(32),
      TS  TIMESTAMP DEFAULT CURRENT_TIMESTAMP)
    ON COMMIT PRESERVE ROWS;
  2. Erstellen einer transaktionsbezogenen globalen temporären Tabelle, die einen Fremdschlüssel verwendet, um auf eine verbindungsbezogene globale temporäre Tabelle zu verweisen.Die Unterklausel ON COMMIT ist optional, da DELETE ROWS die Vorgabe ist.

    CREATE GLOBAL TEMPORARY TABLE MYTXGTT (
      ID        INTEGER NOT NULL PRIMARY KEY,
      PARENT_ID INTEGER NOT NULL REFERENCES MYCONNGTT(ID),
      TXT       VARCHAR(32),
      TS        TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    ) ON COMMIT DELETE ROWS;

Externe Tabellen

Die optionale EXTERNAL [FILE]-Klausel gibt an, dass die Tabelle außerhalb der Datenbank in einer externen Textdatei mit Datensätzen fester Länge gespeichert wird.Die Spalten einer Tabelle, die in einer externen Datei gespeichert sind, können jeden beliebigen Typ haben, außer 'BLOB' oder 'ARRAY', obwohl für die meisten Zwecke nur Spalten des Typs 'CHAR' nützlich wären.

Mit einer in einer externen Datei gespeicherten Tabelle können Sie nur neue Zeilen einfügen (INSERT) und die Daten abfragen (SELECT).Das Aktualisieren vorhandener Daten (UPDATE) und das Löschen von Zeilen (DELETE) sind nicht möglich.

Eine Datei, die als externe Tabelle definiert ist, muss sich auf einem Speichergerät befinden, das physisch auf dem Computer vorhanden ist, auf dem der Firebird-Server läuft, und wenn der Parameter ExternalFileAccess in der Konfigurationsdatei firebird.conf den Wert Restrict hat , muss es in einem der dort aufgeführten Verzeichnisse als Argument für Restrict liegen.Wenn die Datei noch nicht existiert, erstellt Firebird sie beim ersten Zugriff.

Important

Die Möglichkeit, externe Dateien für eine Tabelle zu verwenden, hängt vom Wert ab, der für den Parameter ExternalFileAccess in firebird.conf festgelegt wurde:

  • Wenn es auf None (Standard) gesetzt ist, wird jeder Versuch, auf eine externe Datei zuzugreifen, abgelehnt.

  • Die Einstellung Beschränken wird empfohlen, um den externen Dateizugriff auf Verzeichnisse einzuschränken, die explizit für diesen Zweck vom Serveradministrator erstellt wurden.Zum Beispiel:

    • ExternalFileAccess = Restrict externalfiles beschränkt den Zugriff auf ein Verzeichnis namens externalfiles direkt unter dem Firebird-Stammverzeichnis

    • ExternalFileAccess = d:\databases\outfiles; e:\infiles beschränkt den Zugriff auf nur diese beiden Verzeichnisse auf dem Windows-Hostserver.Beachten Sie, dass alle Pfade, die eine Netzwerkzuordnung darstellen, nicht funktionieren.Pfade, die in einfache oder doppelte Anführungszeichen eingeschlossen sind, funktionieren ebenfalls nicht.

  • Wenn dieser Parameter auf Full gesetzt ist, kann auf externe Dateien überall im Host-Dateisystem zugegriffen werden.Dies schafft eine Sicherheitslücke und wird nicht empfohlen.

Externes Dateiformat

Das “row”-Format der externen Tabelle hat eine feste Länge und ist binär.Es gibt keine Feldbegrenzer: Sowohl Feld- als auch Zeilengrenzen werden durch die maximale Größe der Felddefinitionen in Byte bestimmt.Dies ist sowohl bei der Definition der Struktur der externen Tabelle als auch beim Entwurf einer Eingabedatei für eine externe Tabelle wichtig, die Daten aus einer anderen Anwendung importieren soll.Das allgegenwärtige Format “.csv” zum Beispiel ist als Eingabedatei unbrauchbar und kann nicht direkt in eine externe Datei generiert werden.

Der nützlichste Datentyp für die Spalten externer Tabellen ist der Typ "CHAR" mit fester Länge und geeigneter Länge für die zu übertragenden Daten.Datums- und Zahlentypen lassen sich leicht in und aus Strings umwandeln, während die nativen Datentypen – Binärdaten – für externe Anwendungen als nicht zu analysierendes "Alphabetti" erscheinen, es sei denn, die Dateien sollen von einer anderen Firebird-Datenbank gelesen werden.

Natürlich gibt es Möglichkeiten, typisierte Daten zu manipulieren, um Ausgabedateien von Firebird zu erzeugen, die direkt als Eingabedateien für andere Anwendungen gelesen werden können, unter Verwendung von gespeicherten Prozeduren, mit oder ohne Verwendung externer Tabellen.Solche Techniken gehen über den Umfang einer Sprachreferenz hinaus.Hier geben wir einige Richtlinien und Tipps zum Erstellen und Arbeiten mit einfachen Textdateien, da die externe Tabellenfunktion oft als einfache Möglichkeit verwendet wird, transaktionsunabhängige Protokolle zu erstellen oder zu lesen, die offline in einem Texteditor oder Auditing untersucht werden können Anwendung.

Zeilentrennzeichen

Im Allgemeinen sind externe Dateien nützlicher, wenn Zeilen durch ein Trennzeichen in Form einer “newline”-Sequenz getrennt werden, die von Reader-Anwendungen auf der vorgesehenen Plattform erkannt wird.Für die meisten Kontexte unter Windows ist es die Zwei-Byte-'CRLF'-Sequenz, Wagenrücklauf (ASCII-Code dezimal 13) und Zeilenvorschub (ASCII-Code dezimal 10).Auf POSIX ist LF allein üblich;bei einigen MacOSX-Anwendungen kann es LFCR sein.Es gibt verschiedene Möglichkeiten, diese Trennzeichenspalte zu füllen.In unserem Beispiel unten geschieht dies mit einem BEFORE INSERT Trigger und der internen Funktion ASCII_CHAR.

Beispiel für eine externe Tabelle

In unserem Beispiel definieren wir eine externe Protokolltabelle, die von einem Ausnahmehandler in einer gespeicherten Prozedur oder einem Trigger verwendet werden könnte.Die externe Tabelle wird ausgewählt, weil die Nachrichten von allen behandelten Ausnahmen im Protokoll aufbewahrt werden, selbst wenn die Transaktion, die den Prozess gestartet hat, schließlich aufgrund einer anderen, nicht behandelten Ausnahme zurückgesetzt wird.Zu Demonstrationszwecken hat es nur zwei Datenspalten, einen Zeitstempel und eine Nachricht.Die dritte Spalte speichert das Zeilentrennzeichen:

CREATE TABLE ext_log
  EXTERNAL FILE 'd:\externals\log_me.txt' (
  stamp CHAR (24),
  message CHAR(100),
  crlf CHAR(2) -- for a Windows context
);
COMMIT;

Jetzt ein Trigger, um den Zeitstempel und das Zeilentrennzeichen jedes Mal zu schreiben, wenn eine Nachricht in die Datei geschrieben wird:

SET TERM ^;
CREATE TRIGGER bi_ext_log FOR ext_log
ACTIVE BEFORE INSERT
AS
BEGIN
  IF (new.stamp is NULL) then
    new.stamp = CAST (CURRENT_TIMESTAMP as CHAR(24));
  new.crlf = ASCII_CHAR(13) || ASCII_CHAR(10);
END ^
COMMIT ^
SET TERM ;^

Einfügen einiger Datensätze (was von einem Ausnahmehandler oder einem Shakespeare-Fan hätte erfolgen können):

insert into ext_log (message)
values('Shall I compare thee to a summer''s day?');
insert into ext_log (message)
values('Thou art more lovely and more temperate');

Die Ausgabe:

2015-10-07 15:19:03.4110Shall I compare thee to a summer's day?
2015-10-07 15:19:58.7600Thou art more lovely and more temperate

Einstellen eines DEFAULT-Wertes

Mit der optionalen DEFAULT-Klausel können Sie den Standardwert für die Tabellenspalte angeben.Dieser Wert wird der Spalte hinzugefügt, wenn eine INSERT-Anweisung ausgeführt wird, wenn kein Wert dafür angegeben wurde und diese Spalte im INSERT-Befehl weggelassen wurde.

Der Standardwert kann ein Literal eines kompatiblen Typs sein, eine Kontextvariable, die mit dem Datentyp der Spalte typkompatibel ist, oder NULL, wenn die Spalte dies zulässt.Wenn kein Standardwert explizit angegeben wird, wird NULL impliziert.

Ein Ausdruck kann nicht als Standardwert verwendet werden.

Domainenbasierte Spalten

Um eine Spalte zu definieren, können Sie eine zuvor definierte Domäne verwenden.Wenn die Definition einer Spalte auf einer Domäne basiert, kann sie einen neuen Standardwert, zusätzliche CHECK-Einschränkungen und eine COLLATE-Klausel enthalten, die die in der Domänendefinition angegebenen Werte überschreibt.Die Definition einer solchen Spalte kann zusätzliche Spaltenbeschränkungen enthalten (zB NOT NULL), wenn die Domäne sie nicht hat.

Important

Es ist nicht möglich, eine domänenbasierte Spalte zu definieren, die NULL-Werte zulässt, wenn die Domäne mit dem Attribut NOT NULL definiert wurde.Wenn Sie eine Domäne haben möchten, die sowohl zum Definieren von nullbaren als auch nicht-nullbaren Spalten und Variablen verwendet werden kann, ist es besser, die Domäne nullable zu definieren und NOT NULL in den nachfolgenden Spaltendefinitionen und Variablendeklarationen anzuwenden.

Identitätsspalten (Autoinkrement)

Identitätsspalten werden mit dem GENERATED {ALWAYS | BY DEFAULT} AS IDENTITY-Klausel.Die Identitätsspalte ist eine Spalte, die einem internen Sequenzgenerator zugeordnet ist.Sein Wert wird jedes Mal automatisch gesetzt, wenn er nicht in der INSERT-Anweisung angegeben wird oder wenn der Spaltenwert als DEFAULT angegeben wird.

Regeln
  • Eine Identitätsspalte kann nicht in eine reguläre Spalte geändert werden.Erlaubte Typen sind SMALLINT, INTEGER, BIGINT, NUMERIC(p[,0]) und DECIMAL(p[,0]) mit p <= 18.

    • Der Typ "INT128" und numerische Typen mit einer Genauigkeit von mehr als 18 werden nicht unterstützt.

  • Eine Identitätsspalte darf keinen DEFAULT- oder COMPUTED-Wert haben.

  • Eine Identitätsspalte kann zu einer regulären Spalte geändert werden.

  • Eine reguläre Spalte kann nicht in eine Identitätsspalte geändert werden.

  • Identitätsspalten sind implizit NOT NULL (non-nullable) und können nicht nullable gemacht werden.

  • Eindeutigkeit wird nicht automatisch erzwungen.Eine UNIQUE- oder PRIMARY KEY-Beschränkung ist erforderlich, um die Eindeutigkeit zu garantieren.

  • Die Verwendung anderer Methoden zur Generierung von Schlüsselwerten für Identitätsspalten, z. B. durch Trigger-Generator-Code oder indem Benutzern erlaubt wird, sie zu ändern oder hinzuzufügen, wird davon abgeraten, unerwartete Schlüsselverletzungen zu vermeiden.

  • Der Wert INCREMENT darf nicht null (0) sein.

GENERATED ALWAYS

Eine Identitätsspalte vom Typ GENERATED ALWAYS generiert beim Einfügen immer einen Spaltenwert.Das explizite Einfügen eines Werts in eine Spalte dieses Typs ist nicht zulässig, es sei denn:

  1. der angegebene Wert ist DEFAULT;Dadurch wird der Identitätswert wie gewohnt generiert.

  2. die OVERRIDING SYSTEM VALUE-Klausel wird in der INSERT-Anweisung angegeben;Dadurch kann ein Benutzerwert eingefügt werden.

GENERATED BY DEFAULT

Eine Identitätsspalte vom Typ GENERATED BY DEFAULT erzeugt beim Einfügen einen Wert, wenn beim Einfügen kein Wert — außer DEFAULT — angegeben wird.Wenn die OVERRIDING USER VALUE-Klausel in der INSERT-Anweisung angegeben wird, wird der vom Benutzer bereitgestellte Wert ignoriert und ein Identitätswert generiert (als ob die Spalte nicht in der Einfügung enthalten oder der Wert DEFAULT wurde angegeben).

START WITH-Option

Mit der optionalen START WITH-Klausel können Sie einen anderen Anfangswert als 1 angeben.

Note

Frühere Versionen von Firebird verwendeten stattdessen den angegebenen Wert als Anfangswert des internen Generators, der die Identitätsspalte unterstützt, sodass der erste Wert um 1 höher war als der START WITH-Wert.

Dies wurde in Firebird 4.0 behoben und jetzt ist der erste generierte Wert der START WITH-Wert, siehe auch firebird#6615.

INCREMENT-Option

Mit der optionalen INCREMENT-Klausel können Sie einen anderen Schrittwert ungleich Null als 1 angeben.

Warning

Der SQL-Standard gibt an, dass, wenn INCREMENT mit einem negativen Wert angegeben wird und START WITH nicht angegeben wird, der erste generierte Wert das Maximum des Spaltentyps sein soll (zB 231 - 1 für INTEGER ).Stattdessen startet Firebird bei 1.

Berechnete Felder

Berechnete Felder können mit der COMPUTED [BY]- oder GENERATED ALWAYS AS-Klausel (gemäß SQL:2003-Standard) definiert werden.Sie meinen dasselbe.Die Beschreibung des Datentyps ist für berechnete Felder nicht erforderlich (aber möglich), da das DBMS als Ergebnis der Ausdrucksanalyse den entsprechenden Typ berechnet und speichert.Entsprechende Operationen für die in einem Ausdruck enthaltenen Datentypen müssen genau angegeben werden.

Wenn der Datentyp für ein berechnetes Feld explizit angegeben wird, wird das Berechnungsergebnis in den angegebenen Typ konvertiert.Das bedeutet zum Beispiel, dass das Ergebnis eines numerischen Ausdrucks als String ausgegeben werden könnte.

In einer Abfrage, die eine COMPUTED BY-Spalte auswählt, wird der Ausdruck für jede Zeile der ausgewählten Daten ausgewertet.

Tip

Anstelle einer berechneten Spalte ist es in manchen Fällen sinnvoll, eine reguläre Spalte zu verwenden, deren Wert in Triggern zum Hinzufügen und Aktualisieren von Daten ausgewertet wird.Dies kann die Leistung beim Einfügen/Aktualisieren von Datensätzen verringern, aber die Leistung der Datenauswahl erhöhen.

Definieren einer Array-Spalte

  • Wenn die Spalte ein Array sein soll, kann der Basistyp ein beliebiger SQL-Datentyp außer BLOB und Array sein.

  • Die Abmessungen des Arrays sind in eckigen Klammern angegeben.(Im Syntax block erscheinen diese Klammern in Anführungszeichen, um sie von den eckigen Klammern zu unterscheiden, die optionale Syntaxelemente kennzeichnen.)

  • Für jede Array-Dimension definieren eine oder zwei ganze Zahlen die untere und obere Grenze ihres Indexbereichs:

    • Arrays sind standardmäßig 1-basiert.Die untere Grenze ist implizit und nur die obere Grenze muss angegeben werden.Eine einzelne Zahl kleiner als 1 definiert den Bereich num..1 und eine Zahl größer als 1 definiert den Bereich 1..num.

    • Zwei durch einen Doppelpunkt getrennte Zahlen (‘:’) und optionales Leerzeichen, das zweite größer als das erste, können verwendet werden, um den Bereich explizit zu definieren.Eine oder beide Grenzen können kleiner als Null sein, solange die obere Grenze größer als die untere ist.

  • Wenn das Array mehrere Dimensionen hat, müssen die Bereichsdefinitionen für jede Dimension durch Kommas und optionales Leerzeichen getrennt werden.

  • Indizes werden nur validiert, wenn tatsächlich ein Array existiert.Das bedeutet, dass keine Fehlermeldungen bezüglich ungültiger Indizes zurückgegeben werden, wenn die Auswahl eines bestimmten Elements nichts zurückgibt oder wenn ein Array-Feld [constant] NULL ist.

Constraints

Es können fünf Arten von Einschränkungen angegeben werden.Sie sind:

  • Primärschlüssel (PRIMARY KEY)

  • Eindeutiger Schlüssel (UNIQUE)

  • Fremdschlüssel (REFERENCES)

  • CHECK-Einschränkung (CHECK)

  • NOT NULL-Einschränkung (NOT NULL)

Einschränkungen können auf Spaltenebene (“Spaltenbeschränkungen”) oder auf Tabellenebene (“Tabellenbeschränkungen”) angegeben werden.Einschränkungen auf Tabellenebene sind erforderlich, wenn Schlüssel (eindeutige Einschränkung, Primärschlüssel, Fremdschlüssel) aus mehreren Spalten bestehen und wenn eine CHECK-Einschränkung andere Spalten in der Zeile als die definierte Spalte umfasst.Die Einschränkung NOT NULL kann nur als Spalteneinschränkung angegeben werden.Die Syntax einiger Einschränkungstypen kann geringfügig abweichen, je nachdem, ob die Einschränkung auf Spalten- oder Tabellenebene definiert ist.

  • Eine Einschränkung auf Spaltenebene wird während einer Spaltendefinition angegeben, nachdem alle Spaltenattribute außer COLLATION angegeben wurden, und kann nur die in dieser Definition angegebene Spalte betreffen

  • Einschränkungen auf Tabellenebene können nur nach den Definitionen der Spalten angegeben werden, die in der Einschränkung verwendet werden.

  • Einschränkungen auf Tabellenebene sind eine flexiblere Möglichkeit, Einschränkungen festzulegen, da sie Einschränkungen mit mehreren Spalten berücksichtigen können

  • Sie können Einschränkungen auf Spaltenebene und auf Tabellenebene in derselben CREATE TABLE-Anweisung mischen

Das System erstellt automatisch den entsprechenden Index für einen Primärschlüssel (PRIMARY KEY), einen eindeutigen Schlüssel (UNIQUE) und einen Fremdschlüssel (REFERENCES für eine Einschränkung auf Spaltenebene, FOREIGN KEY REFERENCES für eine auf der Tabellenebene).

Namen für Einschränkungen und ihre Indizes

Einschränkungen auf Spaltenebene und ihre Indizes werden automatisch benannt:

  • Der Name der Einschränkung hat die Form INTEG_n, wobei n eine oder mehrere Ziffern darstellt

  • Der Indexname hat die Form RDB$PRIMARYn (für einen Primärschlüsselindex), RDB$FOREIGNn (für einen Fremdschlüsselindex) oder RDB$n (für einen eindeutigen Schlüsselindex).Auch hier steht n für eine oder mehrere Ziffern.

Die automatische Benennung von Integritätsbedingungen auf Tabellenebene und ihrer Indizes folgt demselben Muster, es sei denn, die Namen werden explizit angegeben.

Benannte Constraints

Eine Einschränkung kann explizit benannt werden, wenn die CONSTRAINT-Klausel für ihre Definition verwendet wird.Während die Klausel CONSTRAINT zum Definieren von Einschränkungen auf Spaltenebene optional ist, ist sie für Einschränkungen auf Tabellenebene obligatorisch.Standardmäßig hat der Einschränkungsindex denselben Namen wie die Einschränkung.Wenn für den Constraint-Index ein anderer Name gewünscht wird, kann eine USING-Klausel eingefügt werden.

Die USING-Klausel

Mit der USING-Klausel können Sie einen benutzerdefinierten Namen für den automatisch erstellten Index angeben und optional die Richtung des Index festlegen – entweder aufsteigend (Standard) oder absteigend.

PRIMARY KEY

Die Einschränkung PRIMARY KEY basiert auf einer oder mehreren Schlüsselspalten, wobei für jede Spalte die Einschränkung NOT NULL angegeben ist.Die Werte in den Schlüsselspalten in jeder Zeile müssen eindeutig sein.Eine Tabelle kann nur einen Primärschlüssel haben.

  • Ein einspaltiger Primärschlüssel kann als Einschränkung auf Spaltenebene oder als Einschränkung auf Tabellenebene definiert werden

  • Als Einschränkung auf Tabellenebene muss ein mehrspaltiger Primärschlüssel angegeben werden

Die UNIQUE-Einschränkung

Die Einschränkung UNIQUE definiert die Anforderung der Eindeutigkeit des Inhalts für die Werte in einem Schlüssel in der gesamten Tabelle.Eine Tabelle kann eine beliebige Anzahl eindeutiger Schlüsseleinschränkungen enthalten.

Wie beim Primärschlüssel kann die Unique-Einschränkung mehrspaltig sein.Wenn dies der Fall ist, muss sie als Einschränkung auf Tabellenebene angegeben werden.

NULL in Unique Keys

Die SQL-99-kompatiblen Regeln von Firebird für UNIQUE-Beschränkungen erlauben eine oder mehrere NULLs in einer Spalte mit einer UNIQUE-Beschränkung.Dadurch ist es möglich, eine UNIQUE-Beschränkung für eine Spalte zu definieren, die nicht die NOT NULL-Beschränkung hat.

Bei UNIQUE-Schlüsseln, die sich über mehrere Spalten erstrecken, ist die Logik etwas kompliziert:

  • Mehrere Zeilen mit Null in allen Spalten des Schlüssels sind zulässig

  • Mehrere Zeilen mit Schlüsseln mit unterschiedlichen Kombinationen von Nullen und Nicht-Null-Werten sind zulässig

  • Mehrere Zeilen mit den gleichen Schlüsselspalten null und der Rest mit Werten ungleich null sind erlaubt, sofern sich die Werte in mindestens einer Spalte unterscheiden

  • Mehrere Zeilen mit den gleichen Schlüsselspalten null und der Rest mit Werten ungleich null gefüllt, die in jeder Spalte gleich sind, verletzen die Einschränkung

Die Regeln für die Eindeutigkeit lassen sich wie folgt zusammenfassen:

Im Prinzip werden alle Nullen als verschieden betrachtet. Wenn jedoch zwei Zeilen genau die gleichen Schlüsselspalten haben, die mit Nicht-Null-Werten gefüllt sind, werden die 'NULL'-Spalten ignoriert und die Eindeutigkeit der Nicht-Null-Spalten wird so bestimmt, als ob sie den gesamten Schlüssel bilden würden.
Illustration
RECREATE TABLE t( x int, y int, z int, unique(x,y,z));
INSERT INTO t values( NULL, 1, 1 );
INSERT INTO t values( NULL, NULL, 1 );
INSERT INTO t values( NULL, NULL, NULL );
INSERT INTO t values( NULL, NULL, NULL ); -- Permitted
INSERT INTO t values( NULL, NULL, 1 );    -- Not permitted

FOREIGN KEY

Ein Fremdschlüssel stellt sicher, dass die teilnehmende(n) Spalte(n) nur Werte enthalten können, die auch in der/den referenzierten Spalte(n) der Mastertabelle vorhanden sind.Diese referenzierten Spalten werden oft als target column bezeichnet.Sie müssen der Primärschlüssel oder ein eindeutiger Schlüssel in der Zieltabelle sein.Für sie muss keine NOT NULL-Beschränkung definiert sein, obwohl sie, wenn sie der Primärschlüssel sind, natürlich diese Einschränkung haben.

Die Fremdschlüsselspalten in der referenzierenden Tabelle selbst erfordern keine NOT NULL-Einschränkung.

Ein einspaltiger Fremdschlüssel kann in der Spaltendeklaration mit dem Schlüsselwort REFERENCES definiert werden:

... ,
  ARTIFACT_ID INTEGER REFERENCES COLLECTION (ARTIFACT_ID),

Die Spalte ARTIFACT_ID im Beispiel verweist auf eine gleichnamige Spalte in der Tabelle COLLECTIONS.

Auf der Tabellenebene können sowohl einspaltige als auch mehrspaltige Fremdschlüssel definiert werden.Bei einem mehrspaltigen Fremdschlüssel ist die Deklaration auf Tabellenebene die einzige Option.Diese Methode ermöglicht auch die Bereitstellung eines optionalen Namens für die Einschränkung:

...
  CONSTRAINT FK_ARTSOURCE FOREIGN KEY(DEALER_ID, COUNTRY)
    REFERENCES DEALER (DEALER_ID, COUNTRY),

Beachten Sie, dass sich die Spaltennamen in der referenzierten Tabelle (“master”) von denen im Fremdschlüssel unterscheiden können.

Note

Wenn keine Zielspalten angegeben sind, verweist der Fremdschlüssel automatisch auf den Primärschlüssel der Zieltabelle.

Fremdschlüsselaktionen

Mit den Unterklauseln ON UPDATE und ON DELETE ist es möglich, eine Aktion für die betroffene(n) Fremdschlüsselspalte(n) festzulegen, wenn referenzierte Werte in der Mastertabelle geändert werden:

KEINE AKTION

(Standard) - Nichts wird getan

CASCADE

Die Änderung in der Master-Tabelle wird an die entsprechende(n) Zeile(n) in der Child-Tabelle weitergegeben.Wenn sich ein Schlüsselwert ändert, ändert sich der entsprechende Schlüssel in den untergeordneten Datensätzen auf den neuen Wert;Wenn die Masterzeile gelöscht wird, werden die untergeordneten Datensätze gelöscht.

SET DEFAULT

Die Fremdschlüsselspalten in den betroffenen Zeilen werden auf ihre Standardwerte gesetzt wie sie waren, als die Fremdschlüsseleinschränkung definiert wurde.

SET NULL

Die Fremdschlüsselspalten in den betroffenen Zeilen werden auf NULL gesetzt.

Die angegebene Aktion oder die Standardeinstellung NO ACTION kann dazu führen, dass eine Fremdschlüsselspalte ungültig wird.Sie könnte beispielsweise einen Wert erhalten, der in der Mastertabelle nicht vorhanden ist, oder er könnte NULL werden, während die Spalte eine NOT NULL-Einschränkung hat.Solche Bedingungen führen dazu, dass die Operation in der Mastertabelle mit einer Fehlermeldung fehlschlägt.

Beispiel
...
  CONSTRAINT FK_ORDERS_CUST
    FOREIGN KEY (CUSTOMER) REFERENCES CUSTOMERS (ID)
      ON UPDATE CASCADE ON DELETE SET NULL

CHECK-Einschränkung

Die Einschränkung CHECK definiert die Bedingung, die die in diese Spalte eingefügten Werte erfüllen müssen.Eine Bedingung ist ein logischer Ausdruck (auch Prädikat genannt), der die Werte TRUE, FALSE und UNKNOWN zurückgeben kann.Eine Bedingung gilt als erfüllt, wenn das Prädikat TRUE oder den Wert UNKNOWN (entspricht NULL) zurückgibt.Wenn das Prädikat FALSE zurückgibt, wird der Wert nicht akzeptiert.Diese Bedingung wird zum Einfügen einer neuen Zeile in die Tabelle (die INSERT-Anweisung) und zum Aktualisieren des vorhandenen Wertes der Tabellenspalte (die UPDATE-Anweisung) und auch für Anweisungen verwendet, bei denen eine dieser Aktionen stattfinden kann (UPDATE ODER EINFÜGEN, MERGE).

Important

Eine CHECK-Bedingung für eine domänenbasierte Spalte ersetzt keine vorhandene CHECK-Bedingung in der Domäne, sondern wird zu einer Ergänzung dazu.Die Firebird-Engine hat während der Definition keine Möglichkeit zu überprüfen, ob das zusätzliche CHECK nicht mit dem vorhandenen kollidiert.

CHECK-Einschränkungen — ob auf Tabellen- oder Spaltenebene definiert — beziehen sich auf Tabellenspalten nach ihren Namen.Die Verwendung des Schlüsselworts VALUE als Platzhalter – wie in den CHECK-Einschränkungen der Domäne – ist im Kontext der Definition von Spalteneinschränkungen nicht gültig.

Beispiel

mit zwei Einschränkungen auf Spaltenebene und einer auf Tabellenebene:

CREATE TABLE PLACES (
  ...
  LAT DECIMAL(9, 6) CHECK (ABS(LAT) <=  90),
  LON DECIMAL(9, 6) CHECK (ABS(LON) <= 180),
  ...
  CONSTRAINT CHK_POLES CHECK (ABS(LAT) < 90 OR LON = 0)
);

NOT NULL-Einschränkung

In Firebird sind Spalten standardmäßig nullable.Die Einschränkung NOT NULL gibt an, dass die Spalte nicht NULL anstelle eines Werts annehmen kann.

Ein NOT NULL-Constraint kann nur als Spalten-Constraint definiert werden, nicht als Tabellen-Constraint.

SQL SECURITY-Klausel

Die Klausel SQL SECURITY gibt den Sicherheitskontext zum Ausführen von Funktionen an, auf die in berechneten Spalten verwiesen wird, und Check-Einschränkungen sowie den Standardkontext, der für Trigger verwendet wird, die für diese Tabelle ausgelöst werden.Wenn SQL-Sicherheit nicht angegeben ist, wird der Standardwert der Datenbank zur Laufzeit angewendet.

Siehe auch SQL-Sicherheit im Kapitel Sicherheit.

Replikationsverwaltung

Wenn die Datenbank mit ALTER DATABASE INCLUDE ALL TO PUBLICATION konfiguriert wurde, werden neue Tabellen automatisch zur Veröffentlichung hinzugefügt, sofern sie nicht mit der DISABLE PUBLICATION-Klausel überschrieben werden.

Wenn die Datenbank nicht für INCLUDE ALL konfiguriert wurde (oder später mit ALTER DATABASE EXCLUDE ALL FROM PUBLICATION neu konfiguriert wurde), werden neue Tabellen nicht automatisch zur Veröffentlichung hinzugefügt.Um Tabellen für die Veröffentlichung einzuschließen, muss die Klausel ENABLE PUBLICATION verwendet werden.

ALTER TABLE

Verwendet für

Ändern der Struktur einer Tabelle.

Verfügbar in

DSQL, ESQL

Syntax
ALTER TABLE tablename
  <operation> [, <operation> ...]

<operation> ::=
    ADD <col_def>
  | ADD <tconstraint>
  | DROP colname
  | DROP CONSTRAINT constr_name
  | ALTER [COLUMN] colname <col_mod>
  | ALTER SQL SECURITY {INVOKER | DEFINER}
  | DROP SQL SECURITY
  | {ENABLE | DISABLE} PUBLICATION

<col_mod> ::=
    TO newname
  | POSITION newpos
  | <regular_col_mod>
  | <computed_col_mod>
  | <identity_col_mod>

<regular_col_mod> ::=
    TYPE {<datatype> | domainname}
  | SET DEFAULT {<literal> | NULL | <context_var>}
  | DROP DEFAULT
  | {SET | DROP} NOT NULL

<computed_col_mod> ::=
    [TYPE <datatype>] {COMPUTED [BY] | GENERATED ALWAYS AS} (<expression>)

<identity_col_mod> ::=
    SET GENERATED {ALWAYS | BY DEFAULT} [<identity_mod_option>...]
  | <identity_mod_options>...
  | DROP IDENTITY

<identity_mod_options> ::=
    RESTART [WITH restart_value]
  | SET INCREMENT [BY] inc_value

!! Siehe auch CREATE TABLE-Syntax für weitere Regel !!
Table 1. ALTER TABLE-Anweisungsparameter
Parameter Beschreibung

tablename

Name (Bezeichner) der Tabelle

operation

Eine der verfügbaren Operationen, die die Struktur der Tabelle ändern

colname

Name (Bezeichner) für eine Spalte in der Tabelle.Die maximale Länge beträgt 63 Zeichen.Muss in der Tabelle eindeutig sein.

domain_name

Domainname

newname

Neuer Name (Bezeichner) für die Spalte.Die maximale Länge beträgt 63 Zeichen.Muss in der Tabelle eindeutig sein.

newpos

Die neue Spaltenposition (eine ganze Zahl zwischen 1 und der Anzahl der Spalten in der Tabelle)

other_table

Der Name der Tabelle, auf die von der Fremdschlüsseleinschränkung verwiesen wird

literal

Ein Literalwert, der im angegebenen Kontext zulässig ist

context_var

Eine Kontextvariable, deren Typ im angegebenen Kontext zulässig ist

check_condition

Die Bedingung einer CHECK-Einschränkung, die erfüllt wird, wenn sie als TRUE oder UNKNOWN/NULL ausgewertet wird

restart_value

Der erste Wert der Identitätsspalte nach dem Neustart

inc_value

Der Inkrement- (oder Schritt-)Wert der Identitätsspalte;Null (0) ist nicht erlaubt.

Die Anweisung ALTER TABLE ändert die Struktur einer bestehenden Tabelle.Mit einer ALTER TABLE-Anweisung ist es möglich, mehrere Operationen auszuführen, Spalten und Einschränkungen hinzuzufügen/zu löschen und auch Spaltenspezifikationen zu ändern.

Mehrere Operationen in einer ALTER TABLE-Anweisung werden durch Kommas getrennt.

Versionsanzahl-Inkremente

Einige Änderungen in der Struktur einer Tabelle erhöhen den Metadaten-Änderungszähler (“version count”), der jeder Tabelle zugewiesen ist.Die Anzahl der Metadatenänderungen ist für jede Tabelle auf 255 begrenzt.Sobald der Zähler die Grenze von 255 erreicht hat, können Sie keine weiteren Änderungen an der Struktur der Tabelle vornehmen, ohne den Zähler zurückzusetzen.

So setzen Sie den Metadaten-Änderungszähler zurück
Sie müssen die Datenbank mit dem Dienstprogramm gbak sichern und wiederherstellen.

Die Klauseln SET NOT NULL und DROP NOT NULL

Die SET NOT NULL-Klausel fügt einer vorhandenen Tabellenspalte eine NOT NULL-Einschränkung hinzu.Im Gegensatz zur Definition in CREATE TABLE ist die Angabe eines Constraint-Namens nicht möglich.

Note

Das erfolgreiche Hinzufügen der NOT NULL-Einschränkung unterliegt einer vollständigen Datenvalidierung für die Tabelle. Stellen Sie daher sicher, dass die Spalte keine Nullen enthält, bevor Sie die Änderung vornehmen.

Eine explizite NOT NULL-Einschränkung für domänenbasierte Spalten überschreibt Domäneneinstellungen.In diesem Szenario erstreckt sich das Ändern der Domäne in NULL-Zulässigkeit nicht auf eine Tabellenspalte.

Das Löschen der NOT NULL-Beschränkung aus der Spalte, wenn ihr Typ eine Domäne ist, die auch eine NOT NULL-Beschränkung hat, hat keine beobachtbaren Auswirkungen, bis die NOT NULL-Beschränkung ebenfalls aus der Domäne gelöscht wird.

Die Klauseln COMPUTED [BY] oder GENERATED ALWAYS AS

Der einer berechneten Spalte zugrunde liegende Datentyp und Ausdruck können mit einer COMPUTED [BY]- oder GENERATED ALWAYS AS-Klausel in der ALTER TABLE ALTER [COLUMN]-Anweisung geändert werden.Das Konvertieren einer regulären Spalte in eine berechnete und umgekehrt ist nicht zulässig.

Identitätsspalten ändern

Für Identitätsspalten (SET GENERATED {ALWAYS | BY DEFAULT}) ist es möglich, mehrere Eigenschaften mit den folgenden Klauseln zu ändern.

Identitätstyp

Das SET GENERATED {ALWAYS | BY DEFAULT} ändert eine Identitätsspalte von ALWAYS in BY DEFAULT und umgekehrt.Dies ist nicht möglich, um eine reguläre Spalte in eine Identitätsspalte zu ändern.

RESTART

Die RESTART-Klausel startet die Sequenz neu, die zum Generieren von Identitätswerten verwendet wird.Wenn nur die RESTART-Klausel angegeben wird, wird die Sequenz auf den Anfangswert zurückgesetzt, der bei der Definition der Identitätsspalte angegeben wurde.Wenn die optionale WITH restart_value-Klausel angegeben wird, wird die Sequenz mit dem angegebenen Wert neu gestartet.

Note

In Firebird 3.0 würde RESTART WITH restart_value auch den konfigurierten Anfangswert in restart_value ändern.Dies war nicht mit dem SQL-Standard konform, daher wird in Firebird 4.0 RESTART WITH restart_value die Sequenz nur mit dem angegebenen Wert neu starten.Nachfolgende RESTARTs (ohne WITH) verwenden den START WITH-Wert, der bei der Definition der Identitätsspalte angegeben wurde.

Es ist derzeit nicht möglich, den konfigurierten Startwert zu ändern.

SET INCREMENT

Die Klausel SET INCREMENT ändert das Inkrement der Identitätsspalte.

DROP IDENTITY

Die Klausel DROP IDENTITY ändert eine Identitätsspalte in eine reguläre Spalte.

Note

Es ist nicht möglich, eine reguläre Spalte in eine Identitätsspalte zu ändern.

Ändern der SQL-Sicherheit

Mit den Klauseln ALTER SQL SECURITY oder DROP SQL SECURITY ist es möglich, die SQL-Sicherheitseigenschaft einer Tabelle zu ändern oder zu löschen.Nach dem Löschen von SQL Security wird der Standardwert der Datenbank zur Laufzeit angewendet.

Note

Wenn die SQL-Sicherheitseigenschaft für eine Tabelle geändert wird, sehen Trigger, die keine explizite SQL-Sicherheitseigenschaft haben, die Auswirkung der Änderung erst, wenn der Trigger das nächste Mal in den Metadatencache geladen wird.

Replikationsverwaltung

Um die Replikation einer Tabelle zu stoppen, verwenden Sie die Klausel DISABLE PUBLICATION.Um die Replikation einer Tabelle zu starten, verwenden Sie die Klausel ENABLE PUBLICATION.

Die Änderung des Veröffentlichungsstatus wird beim Commit wirksam.

Attribute, die nicht geändert werden können

Die folgenden Änderungen werden nicht unterstützt:

  • Ändern der Sortierung einer Zeichentypspalte

Wer kann eine Tabelle ändern?

Die ALTER TABLE-Anweisung kann ausgeführt werden durch:

  • Administratoren

  • Der Besitzer der Tabelle

  • Benutzer mit der Berechtigung ALTER ANY TABLE

Beispiele für die Verwendung von ALTER TABLE

  1. Hinzufügen der Spalte "CAPITAL" zur Tabelle "COUNTRY".

    ALTER TABLE COUNTRY
      ADD CAPITAL VARCHAR(25);
  2. Hinzufügen der Spalte "CAPITAL" mit den Einschränkungen "NOT NULL" und "UNIQUE" und Löschen der Spalte "CURRENCY".

    ALTER TABLE COUNTRY
      ADD CAPITAL VARCHAR(25) NOT NULL UNIQUE,
      DROP CURRENCY;
  3. Hinzufügen der Prüfbedingung CHK_SALARY und eines Fremdschlüssels zur Tabelle JOB.

    ALTER TABLE JOB
      ADD CONSTRAINT CHK_SALARY CHECK (MIN_SALARY < MAX_SALARY),
      ADD FOREIGN KEY (JOB_COUNTRY) REFERENCES COUNTRY (COUNTRY);
  4. Festlegen des Standardwerts für das Feld "MODEL", Ändern des Typs der Spalte "ITEMID" und Umbenennen der Spalte MODELNAME.

    ALTER TABLE STOCK
      ALTER COLUMN MODEL SET DEFAULT 1,
      ALTER COLUMN ITEMID TYPE BIGINT,
      ALTER COLUMN MODELNAME TO NAME;
  5. Neustart der Sequenz einer Identitätsspalte.

    ALTER TABLE objects
      ALTER ID RESTART WITH 100;
  6. Ändern der berechneten Spalten NEW_SALARY und SALARY_CHANGE.

    ALTER TABLE SALARY_HISTORY
      ALTER NEW_SALARY GENERATED ALWAYS AS
        (OLD_SALARY + OLD_SALARY * PERCENT_CHANGE / 100),
      ALTER SALARY_CHANGE COMPUTED BY
        (OLD_SALARY * PERCENT_CHANGE / 100);

Die ADD-Klausel

Mit der ADD-Klausel können Sie eine neue Spalte oder eine neue Tabelleneinschränkung hinzufügen.Die Syntax zum Definieren der Spalte und die Syntax zum Definieren der Tabelleneinschränkung entsprechen denen, die für die CREATE TABLE-Anweisung beschrieben wurden.

Auswirkung auf die Versionsanzahl
  • Jedes Mal, wenn eine neue Spalte hinzugefügt wird, wird der Metadatenänderungszähler um eins erhöht

  • Das Hinzufügen einer neuen Tabelleneinschränkung erhöht nicht den Metadatenänderungszähler

Caution
Zu beachtende Punkte
  1. Das Hinzufügen einer Spalte mit einer NOT NULL-Einschränkung ohne einen DEFAULT-Wert wird fehlschlagen, wenn die Tabelle bereits Zeilen enthält.Beim Hinzufügen einer Nicht-Nullable-Spalte wird empfohlen, entweder einen Standardwert dafür festzulegen oder sie als Nullable-fähig zu erstellen, die Spalte in vorhandenen Zeilen mit einem Nicht-Null-Wert zu aktualisieren und dann eine NOT NULL-Einschränkung hinzuzufügen.

  2. Wenn eine neue 'CHECK'-Beschränkung hinzugefügt wird, werden vorhandene Daten nicht auf Übereinstimmung getestet.Es wird empfohlen, vorhandene Daten vorab mit dem neuen 'CHECK'-Ausdruck zu testen.

  3. Obwohl das Hinzufügen einer Identitätsspalte unterstützt wird, ist dies nur erfolgreich, wenn die Tabelle leer ist.Das Hinzufügen einer Identitätsspalte schlägt fehl, wenn die Tabelle eine oder mehrere Zeilen enthält.

Die DROP-Klausel

Die Klausel DROP colname löscht die angegebene Spalte aus der Tabelle.Ein Versuch, eine Spalte zu löschen, schlägt fehl, wenn etwas darauf verweist.Betrachten Sie die folgenden Elemente als Quellen potenzieller Abhängigkeiten:

  • Spalten- oder Tabellenbeschränkungen

  • Indizes

  • gespeicherte Prozeduren und Trigger

  • Aufrufe

Auswirkung auf die Versionsanzahl
  • Jedes Mal, wenn eine Spalte gelöscht wird, wird der Metadaten-Änderungszähler der Tabelle um eins erhöht.

Die DROP CONSTRAINT-Klausel

Die Klausel DROP CONSTRAINT löscht die angegebene Einschränkung auf Spalten- oder Tabellenebene.

Eine PRIMARY KEY- oder UNIQUE-Schlüsseleinschränkung kann nicht gelöscht werden, wenn sie von einer FOREIGN KEY-Einschränkung in einer anderen Tabelle referenziert wird.Es wird notwendig sein, diese FOREIGN KEY-Beschränkung zu löschen, bevor versucht wird, die PRIMARY KEY- oder UNIQUE-Schlüssel-Beschränkung, auf die sie verweist, zu löschen.

Auswirkung auf die Versionsanzahl
  • Das Löschen einer Spalteneinschränkung oder einer Tabelleneinschränkung erhöht den Metadatenänderungszähler nicht.

Die ALTER [COLUMN]-Klausel

Mit der ALTER [COLUMN]-Klausel können Attribute vorhandener Spalten geändert werden, ohne dass die Spalte gelöscht und erneut hinzugefügt werden muss.Erlaubte Modifikationen sind:

  • den Namen ändern (hat keinen Einfluss auf den Metadaten-Änderungszähler)

  • den Datentyp ändern (erhöht den Metadaten-Änderungszähler um eins)

  • die Spaltenposition in der Spaltenliste der Tabelle ändern (hat keinen Einfluss auf den Metadaten-Änderungszähler)

  • den Standardspaltenwert löschen (hat keinen Einfluss auf den Metadaten-Änderungszähler)

  • einen Standardspaltenwert festlegen oder den vorhandenen Standardwert ändern (hat keinen Einfluss auf den Metadatenänderungszähler)

  • Typ und Ausdruck für eine berechnete Spalte ändern (hat keinen Einfluss auf den Metadaten-Änderungszähler)

  • Setzen Sie die Einschränkung NOT NULL (hat keinen Einfluss auf den Metadaten-Änderungszähler)

  • lösche die NOT NULL-Beschränkung (hat keinen Einfluss auf den Metadaten-Änderungszähler)

  • Ändern Sie den Typ einer Identitätsspalte oder ändern Sie eine Identitätsspalte in eine normale Spalte

  • eine Identitätsspalte neu starten

  • Inkrement einer Identitätsspalte ändern

Umbenennen einer Spalte: die TO-Klausel

Das Schlüsselwort TO mit einem neuen Bezeichner benennt eine vorhandene Spalte um.Die Tabelle darf keine vorhandene Spalte mit demselben Bezeichner aufweisen.

Es ist nicht möglich, den Namen einer Spalte zu ändern, die in einer Einschränkung enthalten ist: PRIMARY KEY, UNIQUE-Schlüssel, FOREIGN KEY, Spaltenbeschränkung oder die CHECK-Beschränkung der Tabelle.

Das Umbenennen einer Spalte ist auch nicht zulässig, wenn die Spalte in einem Trigger, einer gespeicherten Prozedur oder einer Ansicht verwendet wird.

Ändern des Datentyps einer Spalte: die TYPE-Klausel

Das Schlüsselwort TYPE ändert den Datentyp einer existierenden Spalte in einen anderen zulässigen Typ.Eine Typänderung, die zu Datenverlust führen könnte, wird nicht zugelassen.Beispielsweise darf die Anzahl der Zeichen im neuen Typ für eine CHAR- oder VARCHAR-Spalte nicht kleiner sein als die dafür vorhandene Spezifikation.

Wurde die Spalte als Array deklariert, darf weder der Typ noch die Anzahl der Dimensionen geändert werden.

Der Datentyp einer Spalte, die an einem Fremdschlüssel, Primärschlüssel oder einer eindeutigen Einschränkung beteiligt ist, kann nicht geändert werden.

Ändern der Position einer Spalte: die POSITION-Klausel

Das Schlüsselwort POSITION ändert die Position einer vorhandenen Spalte im fiktiven "von links nach rechts"-Layout des Datensatzes.

Die Nummerierung der Spaltenpositionen beginnt bei 1.

  • Wenn eine Position kleiner als 1 angegeben wird, wird eine Fehlermeldung zurückgegeben

  • Wenn eine Positionsnummer größer als die Anzahl der Spalten in der Tabelle ist, wird ihre neue Position stillschweigend an die Anzahl der Spalten angepasst.

Die Klauseln DROP DEFAULT und SET DEFAULT

Die optionale DROP DEFAULT-Klausel löscht den Standardwert für die Spalte, wenn er zuvor durch eine CREATE TABLE- oder ALTER TABLE-Anweisung dort abgelegt wurde.

  • Wenn die Spalte auf einer Domäne mit einem Standardwert basiert, wird der Standardwert auf den Domänenstandard zurückgesetzt

  • Ein Ausführungsfehler wird ausgelöst, wenn versucht wird, den Standardwert einer Spalte zu löschen, die keinen Standardwert hat oder deren Standardwert domänenbasiert ist

Die optionale SET DEFAULT-Klausel setzt einen Standardwert für die Spalte.Wenn die Spalte bereits einen Standardwert hat, wird dieser durch den neuen ersetzt.Der auf eine Spalte angewendete Standardwert überschreibt immer einen von einer Domäne geerbten Wert.

DROP TABLE

Verwendet für

Löschen (Löschen) einer Tabelle

Verfügbar in

DSQL, ESQL

Syntax
DROP TABLE tablename
Table 1. DROP TABLE-Anweisungsparameter
Parameter Beschreibung

tablename

Name (Bezeichner) der Tabelle

Die Anweisung DROP TABLE löscht (löscht) eine vorhandene Tabelle.Wenn die Tabelle Abhängigkeiten aufweist, schlägt die Anweisung DROP TABLE mit einem Ausführungsfehler fehl.

Wenn eine Tabelle gelöscht wird, werden auch alle ihre Trigger und Indizes gelöscht.

Wer kann eine Tabelle löschen?

Die DROP TABLE-Anweisung kann ausgeführt werden durch:

  • Administratoren

  • Der Besitzer der Tabelle

  • Benutzer mit dem Privileg DROP ANY TABLE

Beispiel für DROP TABLE

Löschen der 'COUNTRY'-Tabelle.
DROP TABLE COUNTRY;

RECREATE TABLE

Verwendet für

Erstellen einer neuen Tabelle (Relation) oder Wiederherstellen einer bestehenden Tabelle

Verfügbar in

DSQL

Syntax
RECREATE [GLOBAL TEMPORARY] TABLE tablename
  [EXTERNAL [FILE] 'filespec']
  (<col_def> [, {<col_def> | <tconstraint>} ...])
  [{<table_attrs> | <gtt_table_attrs>}]

Siehe Abschnitt CREATE TABLE für die vollständige Syntax von CREATE TABLE und Beschreibungen zur Definition von Tabellen, Spalten und Einschränkungen.

RECREATE TABLE erstellt oder erstellt eine Tabelle neu.Existiert bereits eine Tabelle mit diesem Namen, versucht die Anweisung RECREATE TABLE, sie zu löschen und eine neue zu erstellen.Vorhandene Abhängigkeiten verhindern die Ausführung der Anweisung.

Beispiel für RECREATE TABLE

Erstellen oder Neuerstellen der Tabelle 'COUNTRY'.
RECREATE TABLE COUNTRY (
  COUNTRY COUNTRYNAME NOT NULL PRIMARY KEY,
  CURRENCY VARCHAR(10) NOT NULL
);