Firebird 2.5 Language Reference → Firebird 2.5 Language Reference → Data Definition (DDL) Statements → TABLE |
Table of Contents
As a relational DBMS, Firebird stores data in tables. A table is a flat, two-dimensional structure containing any number of rows. Table rows are often called records.
All rows in a table have the same structure and consist of columns. Table columns are often called fields. A table must have at least one column. Each column contains a single type of SQL data.
This section describes how to create, alter and delete tables in a database.
Table of Contents
Used for: creating a new table (relation)
Available in: DSQL, ESQL
Syntax:
CREATE [GLOBAL TEMPORARY] TABLE tablename [EXTERNAL [FILE] '<filespec>'] (<col_def> [, {<col_def> | <tconstraint>} ...]) [ON COMMIT {DELETE | PRESERVE} ROWS]; <col_def> ::= <regular_col_def> | <computed_col_def> <regular_col_def> ::= colname {<datatype> | domainname} [DEFAULT {literal | NULL | <context_var>}] [NOT NULL] [<col_constraint>] [COLLATE collation_name] <computed_col_def> ::= colname [<datatype>] {COMPUTED [BY] | GENERATED ALWAYS AS} (<expression>) <datatype> ::= {SMALLINT | INTEGER | BIGINT} [<array_dim>] | {FLOAT | DOUBLE PRECISION} [<array_dim>] | {DATE | TIME | TIMESTAMP} [<array_dim>] | {DECIMAL | NUMERIC} [(precision [, scale])] [<array_dim>] | {CHAR | CHARACTER | CHARACTER VARYING | VARCHAR} [(size)] [<array_dim>] [CHARACTER SET charset_name] | {NCHAR | NATIONAL CHARACTER | NATIONAL CHAR} [VARYING] [(size)] [<array_dim>] | BLOB [SUB_TYPE {subtype_num | subtype_name}] [SEGMENT SIZE seglen] [CHARACTER SET charset_name] | BLOB [(seglen [, subtype_num])] <array_dim> ::= [[m:]n [, [m:]n ...]] <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>) } <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 <datatype>) | (<select_one>) | func([<val> [, <val> ...]])
Table 5.7. CREATE TABLE Statement Parameters
Parameter | Description |
---|---|
tablename | Name (identifier) for the table. It may consist of up to 31 characters and must be unique in the database. |
filespec | File specification (only for external tables). Full file name and path, enclosed in single quotes, correct for the local file system and located on a storage device that is physically connected to Firebird's host computer. |
colname | Name (identifier) for a column in the table. May consist of up to 31 characters and must be unique in the table. |
datatype | SQL data type |
col_constraint | Column constraint |
tconstraint | Table constraint |
constr_name | The name (identifier) of a constraint. May consist of up to 31 characters. |
other_table | The name of the table referenced by the foreign key constraint |
other_col | The name of the column in other_table
that is referenced by the foreign key
|
literal | A literal value that is allowed in the given context |
context_var | Any context variable whose data type is allowed in the given context |
check_condition | The condition applied to a CHECK constraint, that will resolve as either true, false or NULL |
collation | Collation |
array_dim | Array dimensions |
m, n | INTEGER numbers defining the index range of an array dimension |
precision | The total number of significant digits that a value of the datatype can hold (1..18) |
scale | The number of digits after the decimal point (0..precision )
|
size | The maximum size of a string in characters |
charset_name | The name of a valid character set, if the character set of the column is to be different to the default character set of the database |
subtype_num | BLOB subtype number |
subtype_name | BLOB subtype mnemonic name |
seglen | Segment size (max. 65535) |
select_one | A scalar SELECT statement—selecting one column and returning only one row |
select_list | A SELECT statement selecting one column and returning zero or more rows |
select_expr | A SELECT statement selecting one or more columns and returning zero or more rows |
expression | An expression resolving to a value that is is allowed in the given context |
genname | Sequence (generator) name |
func | Internal function or UDF |
The CREATE TABLE statement creates a new table. Any user can create it and its name must be unique among the names of all tables, views and stored procedures in the database.
A table must contain at least one column that is not computed and the names of columns must be unique in the table.
A column must have either an explicit SQL data type, the name of a domain whose attributes will be copied for the column, or be defined as COMPUTED BY an expression (a calculated field).
A table may have any number of table constraints, including none.
In Firebird, columns are nullable by default. The optional NOT NULL clause specifies that the column cannot take NULL in place of a value.
You can use the CHARACTER SET clause to specify the character set for the CHAR, VARCHAR and BLOB (text subtype) types. If the character set is not specified, the character set specified during the creation of the database will be used by default. If no character set was specified during the creation of the database, the NONE character set is applied by default. In this case, data is stored and retrieved the way it was submitted. Data in any encoding can be added to such a column, but it is not possible to add this data to a column with a different encoding. No transliteration is performed between the source and destination encodings, which may result in errors.
The optional COLLATE clause allows you to specify the collation sequence for character data types, including BLOB SUB_TYPE TEXT. If no collation sequence is specified, the collation sequence that is default for the specified character set during the creation of the column is applied by default.
The optional DEFAULT clause allows you to specify the default value for the table column. This value will be added to the column when an INSERT statement is executed if no value was specified for it and that column was omitted from the INSERT command.
The default value can be a literal of a compatible type, a context variable that is type-compatible with the data type of the column, or NULL, if the column allows it. If no default value is explicitly specified, NULL is implied.
An expression cannot be used as a default value.
To define a column, you can use a previously defined domain. If the definition of a column is based on a domain, it may contain a new default value, additional CHECK constraints and a COLLATE clause that will override the values specified in the domain definition. The definition of such a column may contain additional column constraints (for instance, NOT NULL), if the domain does not have it.
Important | |
---|---|
It is not possible to define a domain-based column that is nullable if the domain was defined with the NOT NULL attribute. If you want to have a domain that might be used for defining both nullable and non-nullable columns and variables, it is better practice to make the domain nullable and apply NOT NULL in the downstream column definitions and variable declarations. |
Calculated fields can be defined with the COMPUTED [BY] or GENERATED ALWAYS AS clause (according to the SQL:2003 standard). They mean the same. Describing the data type is not required (but possible) for calculated fields, as the DBMS calculates and stores the appropriate type as a result of the expression analysis. Appropriate operations for the data types included in an expression must be specified precisely.
If the data type is explicitly specified for a calculated field, the calculation result is converted to the specified type. This means, for instance, that the result of a numeric expression could be rendered as a string.
In a query that selects a COMPUTED BY column, the expression is evaluated for each row of the selected data.
Tip | |
---|---|
Instead of a computed column, in some cases it makes sense to use a regular column whose value is evaluated in triggers for adding and updating data. It may reduce the performance of inserting/updating records, but it will increase the performance of data selection. |
num
..1 and a number greater
than 1 defines the range 1..num
.
NULL
.
Four types of constraints can be specified. They are:
Constraints can be specified at column level (“column constraints”) or at table level (“table constraints”). Table-level constraints are needed when keys (uniqueness constraint, Primary Key, Foreign Key) are to be formed across multiple columns and when a CHECK constraint involves other columns in the row besides the column being defined. Syntax for some types of constraint may differ slightly according to whether the constraint is being defined at column or table level.
The system automatically creates the corresponding index for a primary key (PRIMARY KEY), a unique key (UNIQUE) and a foreign key (REFERENCES for a column-level constraint, FOREIGN KEY REFERENCES for one at the table level).
Column-level constraints and their indexes are named automatically:
Automatic naming of table-level constraints and their indexes follows the same pattern, unless the names are supplied explicitly.
A constraint can be named explicitly if the CONSTRAINT clause is used for its definition. While the CONSTRAINT clause is optional for defining column-level constraints, it is mandatory for table-level. By default, the constraint index will have the same name as the constraint. If a different name is wanted for the constraint index, a USING clause can be included.
The PRIMARY KEY constraint is built on one or more key columns, each column having the NOT NULL constraint specified for it. The values across the key columns in any row must be unique. A table can have only one primary key.
The UNIQUE constraint defines the requirement of content uniqueness for the values in a key throughout the table. A table can contain any number of unique key constraints.
As with the Primary Key, the Unique constraint can be multi-column. If so, it must be specified as a table-level constraint.
Firebird's SQL-99-compliant rules for UNIQUE constraints allow one or more NULLs in a column with a UNIQUE constraint. That makes it possible to define a UNIQUEconstraint on a column that does not have the NOT NULL constraint.
For UNIQUE keys that span multiple columns, the logic is a little complicated:
The rules for uniqueness can be summarised thus:
In principle, all nulls are considered distinct. However, if two rows have exactly the same key columns filled with non-null values, the NULL columns are ignored and the uniqueness is determined on the non-null columns as though they constituted the entire key.
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
A Foreign Key ensures that the participating column(s) can contain only values that also exist in the referenced column(s) in the master table. These referenced columns are often called target columns. They must be the primary key or a unique key in the target table. They need not have a NOT NULL constraint defined on them although, if they are the primary key, they will, of course, have that constraint.
The foreign key columns in the referencing table itself do not require a NOT NULL constraint.
A single-column Foreign Key can be defined in the column declaration, using the keyword REFERENCES:
... , ARTIFACT_ID INTEGER REFERENCES COLLECTION (ARTIFACT_ID),
The column ARTIFACT_ID in the example references a column of the same name in the table COLLECTIONS.
Both single-column and multi-column foreign keys can be defined at the table level. For a multi-column Foreign Key, the table-level declaration is is the only option. This method also enables the provision of an optional name for the constraint:
... CONSTRAINT FK_ARTSOURCE FOREIGN KEY(DEALER_ID, COUNTRY) REFERENCES DEALER (DEALER_ID, COUNTRY),
Notice that the column names in the referenced (“master”) table may differ from those in the Foreign Key.
Note | |
---|---|
If no target columns are specified, the Foreign Key automatically references the target table's Primary Key. |
With the sub-clauses ON UPDATE and ON DELETE it is possible to specify an action to be taken on the affected foreign key column(s) when referenced values in the master table are changed:
The specified action, or the default NO ACTION, could cause a Foreign Key column to become invalid. For example, it could get a value that is not present in the master table, or it could become NULL while the column has a NOT NULL constraint. Such conditions will cause the operation on the master table to fail with an error message.
Example:
... CONSTRAINT FK_ORDERS_CUST FOREIGN KEY (CUSTOMER) REFERENCES CUSTOMERS (ID) ON UPDATE CASCADE ON DELETE SET NULL
The CHECK constraint defines the condition the values inserted in this column must satisfy. A condition is a logical expression (also called a predicate) that can return the TRUE, FALSE and UNKNOWN values. A condition is considered satisfied if the predicate returns TRUE or value UNKNOWN (equivalent to NULL). If the predicate returns FALSE, the value will not be accepted. This condition is used for inserting a new row into the table (the INSERT statement) and for updating the existing value of the table column (the UPDATE statement) and also for statements where one of these actions may take place (UPDATE OR INSERT, MERGE).
Important | |
---|---|
A CHECK constraint on a domain-based column does not replace an existing CHECK condition on the domain, but becomes an addition to it. The Firebird engine has no way, during definition, to verify that the extra CHECK does not conflict with the existing one. |
CHECK conditions—whether defined at table level or column level— refer to table columns by their names. The use of the keyword VALUE as a placeholder, as in domain CHECK constraints, is not valid in the context of defining column constraints.
Example: with two column-level constraints and one at table-level:
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) );
Global temporary tables have persistent metadata, but their contents are transaction-bound (the default) or connection-bound. Every transaction or connection has its own private instance of a GTT, isolated from all the others. Instances are only created if and when the GTT is referenced. They are destroyed when the transaction ends or on disconnection. The metadata of a GTT can be modified or removed using ALTER TABLE and DROP TABLE, respectively.
Syntax:
CREATE GLOBAL TEMPORARY TABLEname
(<column_def> [, {<column_def> | <table_constraint>} ...]) [ON COMMIT {DELETE | PRESERVE} ROWS]
Syntax notes | |
---|---|
|
GTTs can be “dressed up” with all the features and paraphernalia of ordinary tables (keys, references, indexes, triggers and so on) but there are a few restrictions:
Tip | |
---|---|
In an existing database, it is not always easy to distinguish a regular table from a GTT, or a transaction-level GTT from a connection-level GTT. Use this query to find out what type of table you are looking at:
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 = ' For an overview of the types of all the relations in the database: 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 The RDB$TYPE_NAME field will show PERSISTENT for a regular table, VIEW for a view, GLOBAL_TEMPORARY_PRESERVE for a connection-bound GTT and GLOBAL_TEMPORARY_DELETE for a transaction_bound GTT. |
The optional EXTERNAL [FILE] clause specifies that the table is stored outside the database in an external text file of fixed-length records. The columns of a table stored in an external file can be of any type except BLOB or ARRAY, although for most purposes, only columns of CHAR types would be useful.
All you can do with a table stored in an external file is insert new rows (INSERT) and query the data (SELECT). Updating existing data (UPDATE) and deleting rows (DELETE) are not possible.
A file that is defined as an external table must be located on a storage device that is physically
present on the machine where the Firebird server runs and, if the parameter ExternalFileAccess
in the firebird.conf
configuration file is Restrict
, it must be
in one of the directories listed there as the argument for Restrict
. If the file does not
exist yet, Firebird will create it on first access.
Important | |
---|---|
The ability to use external files for a table depends on the value set for the
ExternalFileAccess parameter in
|
The “row” format of the external table is fixed length. There are no field delimiters: both field and row boundaries are determined by maximum sizes, in bytes, of the field definitions. It is important to keep this in mind, both when defining the structure of the external table and when designing an input file for an external table that is to import data from another application. The ubiquitous “.csv” format, for example, is of no use as an input file and cannot be generated directly into an external file.
The most useful data type for the columns of external tables is the fixed-length CHAR type, of suitable lengths for the data they are to carry. Date and number types are easily cast to and from strings whereas, unless the files are to be read by another Firebird database, the native data types will appear to external applications as unparseable “alphabetti”.
Of course, there are ways to manipulate typed data so as to generate output files from Firebird that can be read directly as input files to other applications, using stored procedures, with or without employing external tables. Such techniques are beyond the scope of a language reference. Here, we provide some guidelines and tips for producing and working with simple text files, since the external table feature is often used as an easy way to produce or read transaction-independent logs that can be studied off-line in a text editor or auditing application.
Generally, external files are more useful if rows are separated by a delimiter, in the form of a “newline” sequence that is recognised by reader applications on the intended platform. For most contexts on Windows, it is the two-byte 'CRLF' sequence, carriage return (ASCII code decimal 13) and line feed (ASCII code decimal 10). On POSIX, LF on its own is usual; for some MacOSX applications, it may be LFCR. There are various ways to populate this delimiter column. In our example below, it is done by using a Before Insert trigger and the internal function ASCII_CHAR.
For our example, we will define an external log table that might be used by an exception handler in a stored procedure or trigger. The external table is chosen because the messages from any handled exceptions will be retained in the log, even if the transaction that launched the process is eventually rolled back because of another, unhandled exception. For demonstration purposes, it has just two data columns, a time stamp and a message. The third column stores the row delimiter:
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;
Now, a trigger, to write the timestamp and the row delimiter each time a message is written to the file:
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 ;^
Inserting some records (which could have been done by an exception handler or a fan of Shakespeare):
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')
The output:
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
CREATE TABLE COUNTRY ( COUNTRY COUNTRYNAME NOT NULL PRIMARY KEY, CURRENCY VARCHAR(10) NOT NULL);
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));
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) );
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 );
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) );
CREATE GLOBAL TEMPORARY TABLE MYCONNGTT ( ID INTEGER NOT NULL PRIMARY KEY, TXT VARCHAR(32), TS TIMESTAMP DEFAULT CURRENT_TIMESTAMP) ON COMMIT PRESERVE ROWS;
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;
Table of Contents
Used for: altering the structure of a table.
Available in: DSQL, ESQL
Syntax:
ALTER TABLE tablename <operation> [, <operation> ...] <operation> ::= ADD <col_def> ADD <tconstraint> DROPcolname
DROP CONSTRAINTconstr_name
ALTER [COLUMN]colname
<col_mod> <col_def> ::= <regular_col_def> | <computed_col_def> <regular_col_def> ::= colname {<datatype> | domainname} [DEFAULT {literal | NULL | <context_var>}] [NOT NULL] [<col_constraint>] [COLLATE collation_name] <computed_col_def> ::= colname [<datatype>] {COMPUTED [BY] | GENERATED ALWAYS AS} (<expression>) <col_mod> ::= <regular_col_mod> | <computed_col_mod> <regular_col_mod> ::= TOnewname
| POSITIONnewpos
| TYPE {<datatype> |domainname
} | SET DEFAULT {literal
| NULL | <context_var>} | DROP DEFAULT <computed_col_mod> ::= TOnewname
| POSITIONnewpos
| [TYPE <datatype>] {COMPUTED [BY] | GENERATED ALWAYS AS} (<expression>) <datatype> ::= {SMALLINT | INTEGER | BIGINT} [<array_dim>] | {FLOAT | DOUBLE PRECISION} [<array_dim>] | {DATE | TIME | TIMESTAMP} [<array_dim>] | {DECIMAL | NUMERIC} [(precision [, scale])] [<array_dim>] | {CHAR | CHARACTER | CHARACTER VARYING | VARCHAR} [(size)] [<array_dim>] [CHARACTER SET charset_name] | {NCHAR | NATIONAL CHARACTER | NATIONAL CHAR} [VARYING] [(size)] [<array_dim>] | BLOB [SUB_TYPE {subtype_num | subtype_name}] [SEGMENT SIZE seglen] [CHARACTER SET charset_name] | BLOB [(seglen [, subtype_num])] <array_dim> ::= [[m]:n [,[m]:n ...]] <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>) } <tconstraint> ::= [CONSTRAINTconstr_name
] { PRIMARY KEY (col_list
) [<using_index>] | UNIQUE (col_list
) [<using_index>] | FOREIGN KEY (col_list
) REFERENCESother_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]] INDEXindexname
<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>) | (<search_condition>) | NOT <search_condition> | <search_condition> OR <search_condition> | <search_condition> AND <search_condition> <operator> ::= <> | != | ^= | ~= | = | < | > | <= | >= | !< | ^< | ~< | !> | ^> | ~> <val> ::= colname [[<array_idx> [, <array_idx> ...]]] | literal | <context_var> | <expression> | NULL | NEXT VALUE FOR genname | GEN_ID(genname, <val>) | CAST(<val> AS <datatype>) | (<select_one>) | func([<val> [, <val> ...]])
Table 5.8. ALTER TABLE Statement Parameters
Parameter | Description |
---|---|
tablename | Name (identifier) of the table |
operation | One of the available operations altering the structure of the table |
colname | Name (identifier) for a column in the table, max. 31 characters. Must be unique in the table. |
newname | New name (identifier) for the column, max. 31 characters. Must be unique in the table. |
newpos | The new column position (an integer between 1 and the number of columns in the table) |
col_constraint | Column constraint |
tconstraint | Table constraint |
constr_name | The name (identifier) of a constraint. May consist of up to 31 characters. |
other_table | The name of the table referenced by the foreign key constraint |
literal | A literal value that is allowed in the given context |
context_var | A context variable whose type is allowed in the given context |
check_condition | The condition of a CHECK constraint that will be satisfied if it evaluates to TRUE or UNKNOWN/NULL |
collation | Name of a collation sequence that is valid for
charset_name , if it is supplied with
datatype or, otherwise, is valid for the default character
set of the database
|
array_dim | Array dimensions |
m, n | INTEGER numbers defining the index range of an array dimension |
precision | The total number of significant digits that a value of
the datatype can hold (1..18)
|
scale | The number of digits after the decimal point
(0..precision )
|
size | The maximum size of a string in characters |
charset_name | The name of a valid character set, if the character set of the column is to be different to the default character set of the database |
subtype_num | BLOB subtype number |
subtype_name | BLOB subtype mnemonic name |
seglen | Segment size (max. 65535) |
select_one | A scalar SELECT statement—selecting one column and returning only one row |
select_list | A SELECT statement selecting one column and returning zero or more rows |
select_expr | A SELECT statement selecting one or more columns and returning zero or more rows |
expression | An expression resolving to a value that is is allowed in the given context |
genname | Sequence (generator) name |
func | Internal function or UDF |
The ALTER TABLE statement changes the structure of an existing table. With one ALTER TABLE statement it is possible to perform multiple operations, adding/dropping columns and constraints and also altering column specifications.
Multiple operations in an ALTER TABLE statement are separated with commas.
Some changes in the structure of a table increment the metadata change counter (“version count”) assigned to every table. The number of metadata changes is limited to 255 for each table. Once the counter reaches the 255 limit, you will not be able to make any further changes to the structure of the table without resetting the counter.
To reset the metadata change counter: You should back up and restore the database using the gbak utility.
With the ADD clause you can add a new column or a new table constraint. The syntax for defining the column and the syntax of defining the table constraint correspond with those described for CREATE TABLE statement.
Effect on Version Count:
Points to Be Aware of | |
---|---|
|
The DROP <column name> clause deletes the specified column from the table. An attempt to drop a column will fail if anything references it. Consider the following items as sources of potential dependencies:
Effect on Version Count: Each time a column is dropped, the table's metadata change counter is increased by one.
The DROP CONSTRAINT clause deletes the specified column-level or table-level constraint.
A PRIMARY KEY or UNIQUE key constraint cannot be deleted if it is referenced by a FOREIGN KEY constraint in another table. It will be necessary to drop that FOREIGN KEY constraint before attempting to drop the PRIMARY KEY or UNIQUE key constraint it references.
Effect on Version Count: Deleting a column constraint or a table constraint does not increase the metadata change counter.
With the ALTER [COLUMN] clause, attributes of existing columns can be modified without the need to drop and re-add the column. Permitted modifications are:
The TO keyword with a new identifier renames an existing column. The table must not have an existing column that has the same identifier.
It will not be possible to change the name of a column that is included in any constraint: PRIMARY KEY, UNIQUE key, FOREIGN KEY, column constraint or the CHECK constraint of the table.
Renaming a column will also be disallowed if the column is used in any trigger, stored procedure or view.
The keyword TYPE changes the data type of an existing column to another, allowable type. A type change that might result in data loss will be disallowed. As an example, the number of characters in the new type for a CHAR or VARCHAR column cannot be smaller than the existing specification for it.
If the column was declared as an array, no change to its type or its number of dimensions is permitted.
The data type of a column that is involved in a foreign key, primary key or unique constraint cannot be changed at all.
The POSITION keyword changes the position of an existing column in the notional “left-to-right” layout of the record.
Numbering of column positions starts at 1.
The optional DROP DEFAULT clause deletes the default value for the column if it was put there previously by a CREATE TABLE or ALTER TABLE statement.
The optional SET DEFAULT clause sets a default value for the column. If the column already has a default value, it will be replaced with the new one. The default value applied to a column always overrides one inherited from a domain.
The data type and expression underlying a computed column can be modified using a COMPUTED [BY] or GENERATED ALWAYS AS clause in the ALTER TABLE ALTER [COLUMN] statement. Converting a regular column to a computed one and vice versa are not permitted.
The following alterations are not supported:
Only the table owner and administrators have the authority to use ALTER TABLE.
ALTER TABLE COUNTRY ADD CAPITAL VARCHAR(25);
ALTER TABLE COUNTRY ADD CAPITAL VARCHAR(25) NOT NULL UNIQUE, DROP CURRENCY;
ALTER TABLE JOB ADD CONSTRAINT CHK_SALARY CHECK (MIN_SALARY < MAX_SALARY), ADD FOREIGN KEY (JOB_COUNTRY) REFERENCES COUNTRY (COUNTRY);
ALTER TABLE STOCK ALTER COLUMN MODEL SET DEFAULT 1, ALTER COLUMN ITEMID TYPE BIGINT, ALTER COLUMN MODELNAME TO NAME;
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);
See also: CREATE TABLE, DROP TABLE, CREATE DOMAIN
Used for: deleting a table
Available in: DSQL, ESQL
Syntax:
drop tabletablename
;
Table 5.9. DROP TABLE Statement Parameter
Parameter | Description |
---|---|
tablename | Name (identifier) of the table |
The DROP TABLE statement deletes an existing table. If the table has dependencies, the DROP TABLE statement will fail with an execution error.
When a table is dropped, all triggers for its events and indexes built for its fields will be deleted as well.
Only the table owner and administrators have the authority to use DROP TABLE.
Example: Deleting the COUNTRY table.
DROP TABLE COUNTRY;
See also: CREATE TABLE, ALTER TABLE, RECREATE TABLE
Used for: creating a new table (relation) or recreating an existing one
Available in: DSQL
Syntax:
RECREATE [GLOBAL TEMPORARY] TABLEtablename
[EXTERNAL [FILE] '<filespec>'] (<col_def> [, {<col_def> | <tconstraint>} ...]) [ON COMMIT {DELETE | PRESERVE} ROWS]
See the CREATE TABLE section for the full syntax of CREATE TABLE and descriptions of defining tables, columns and constraints.
RECREATE TABLE creates or recreates a table. If a table with this name already exists, the RECREATE TABLE statement will try to drop it and create a new one. Existing dependencies will prevent the statement from executing.
Example: Creating or recreating the COUNTRY table.
RECREATE TABLE COUNTRY ( COUNTRY COUNTRYNAME NOT NULL PRIMARY KEY, CURRENCY VARCHAR(10) NOT NULL);
See also: CREATE TABLE, DROP TABLE
Firebird 2.5 Language Reference → Firebird 2.5 Language Reference → Data Definition (DDL) Statements → TABLE |