表
作为一个关系数据库管理系统,Firebird在表中存储数据.表是扁平的二维结构包含所有的行数,表行通常被称为记录。
表中的所有行具有相同的结构和包含的列。表列通常被称为字段。一个表必须至少有一列,每个列包含一个单独的SQL数据类刑。
本部分描述如何在数据库中创建、更改和删除表。
作用: 创建一个新的表(关联)
用于: DSQL, ESQL
语法:
CREATE [GLOBAL TEMPORARY] TABLE tablename
[EXTERNAL [FILE] '']
( [, { | } ...])
[ON COMMIT {DELETE | PRESERVE} ROWS];
::= |
::=
colname { | domainname}
[DEFAULT {literal | NULL | }]
[NOT NULL]
[]
[COLLATE collation_name]
::=
colname []
{COMPUTED [BY] | GENERATED ALWAYS AS} ()
::=
{SMALLINT | INTEGER | BIGINT} []
| {FLOAT | DOUBLE PRECISION} []
| {DATE | TIME | TIMESTAMP} []
| {DECIMAL | NUMERIC} [(precision [, scale])] []
| {CHAR | CHARACTER | CHARACTER VARYING | VARCHAR} [(size)]
[] [CHARACTER SET charset_name]
| {NCHAR | NATIONAL CHARACTER | NATIONAL CHAR} [VARYING]
[(size)] []
| BLOB [SUB_TYPE {subtype_num | subtype_name}]
[SEGMENT SIZE seglen] [CHARACTER SET charset_name]
| BLOB [(seglen [, subtype_num])]
::= [[m:]n [, [m:]n ...]]
::=
[CONSTRAINT constr_name]
{ PRIMARY KEY []
| UNIQUE []
| REFERENCES other_table [(colname)] []
[ON DELETE {NO ACTION | CASCADE | SET DEFAULT | SET NULL}]
[ON UPDATE {NO ACTION | CASCADE | SET DEFAULT | SET NULL}]
| CHECK () }
::=
[CONSTRAINT constr_name]
{ PRIMARY KEY (col_list) []
| UNIQUE (col_list) []
| FOREIGN KEY (col_list)
REFERENCES other_table [(col_list)] []
[ON DELETE {NO ACTION | CASCADE | SET DEFAULT | SET NULL}]
[ON UPDATE {NO ACTION | CASCADE | SET DEFAULT | SET NULL}]
| CHECK () }"
::= colname [, colname ...]
::= USING
[ASC[ENDING] | DESC[ENDING]] INDEX indexname
::=
| [NOT] BETWEEN AND
| [NOT] IN ( [, ...] | )
| IS [NOT] NULL
| IS [NOT] DISTINCT FROM
| [NOT] CONTAINING
| [NOT] STARTING [WITH]
| [NOT] LIKE [ESCAPE ]
| [NOT] SIMILAR TO [ESCAPE ]
| {ALL | SOME | ANY} ()
| [NOT] EXISTS ()
| [NOT] SINGULAR ()
| ()
| NOT
| OR
| AND
::=
<> | != | ^= | ~= | = | < | > | <= | >= | !< | ^< | ~< | !> | ^> | ~>
::=
colname [[ [, ...]]]
| literal
|
|
| NULL
| NEXT VALUE FOR genname
| GEN_ID(genname, )
| CAST( AS )
| ()
| func([ [, ...]])
表5.7. CREATE TABLE语句参数
参数 | 描述 |
tablename | 表的名称 (标识符)。它可能由达 31 个字符组成,并在数据库中必须唯一。 |
filespec | 文件规范 (仅对于外部表)。完整的文件名称和路径,括在单引号中,正确的本地文件系统且位于一个存储设备上,也就是物理连接到Firebird的计算机主机。 |
colname | 新表中的列的名称 (标识符)。可能包含达 31 个字符并且必须是唯一的表中。 |
datatype | SQL 数据类型 |
col_constraint | 列约束 |
tconstraint | 表约束 |
constr_name | 约束的名称 (标识符)。可能包括达 31 个字符。 |
other_table | 由外键约束引用的表的名称 |
other_col | 在other_table 中由外键引用的列的名称 |
literal | 允许在给定的上下文中使用的文本值 |
context_var | 其数据类型是在给定的上下文中被允许的任何上下文变量, |
check_condition | 应用于 CHECK 约束,将解析为 true,false 或空的条件 |
collation | 排序规则 |
array_dim | 数组维数 |
m,n | 整数定义数组维度的索引范围 |
precision | 数据类型的值可以 hold(1..18) 的有效位数总数 |
scale | 小数点 (0..precision) 后的数字位数 |
size | 字符的字符串的最大大小 |
charset_name | 一个有效的字符集,如果列的字符集是不同于数据库的默认字符集 |
subtype_num | BLOB 子类型数量 |
subtype_name | BLOB 子类型助记符名称 |
seglen | 段大小 (最大 65535) |
select_one | 一个标量的 SELECT 语句 — — 选择一列并返回唯一行 |
select_list | 选择一列并返回零个或更多行的 SELECT 语句 |
select_expr | 选择一个或多个列并返回零个或更多行的 SELECT 语句 |
expression | 表达式解析为一个值,被允许在给定的上下文中 |
genname | 序列 (生成器) 名称 |
func | 内部函数或 UDF |
CREATE TABLE语句创建一个新的表。任何用户都能创建它且它的名称必须是唯一的,在数据库的所有表、视图、存储过程的称中。
表中必须包含至少一个不计算的列且列的名称在表中必须是唯一的。
一列必须有一个明确的SQL数据类型,一个域的名称的属性将被复制列,或者被定义为一个计算表达式(计算字段)。
一个表可以有任意数量的表约束,包括没有约束。
使一个列为非空
在Firebird数据库中,列默为是可以有为空值。选择NOT NULL子句规定一个列不能用NULL来取代一个值。
列的字符
可以使用CHARACTER SET了句来为CHAR,VARCHAR和BLOB(text 子类) 类型指定字符集。如果字符集没有被指定,将默认使用数据库创建时被指定的字符集。如果在数据库创建时没有指定字符集,NONE字符集将被默认应用。在这种情况下,提交字符数据存储和检索的方式使用字符集NONE。任何数据编码可以添加到这样的列,但它是不可能将此数据以一种不同的编码添加到列的。因为没有音译补执行在源和目标的编码之间,可能会导致错误。
可选项 COLLATE子句允许为字符数据类型指定排序序列,包括BLOB SUB_TYPE TEXT.如果没有指定排序规则序列,创建列时将指定一个默认的字符集的排序序列。
设置一个默认值
可选项DEFAULT子句允许为表列指定个默认值。当INSERT语句被执行时如果没有值被指定且这个列从INSERT中被小省略,那么这个值将被增加到这个列中
默认值可以是一个兼容类型的文本,一个上下文变量,也就是同列的数据类型兼容,或NULL,如果列允许它.如果没有默认值被显示的指定,那么NULL是隐含的.
表达式不能被用于作为默认值。
基于域的列
为定义一个列,可以使用预先定义的域。如果一个列定义是基于一个域,那么它可能包含一个新的默认值,附加CHECK约束和一个COLLATE子句将覆盖在域中定义的指定的值。这样的列定义可能包含附加列约束(如:NOT NULL),如果域中没有。
重要
不可能是去定义一个基于域的列是可以为NULL值如果域被定义为NOT NULL属性。如果你想有一个域,可能是用于定义NULL和 NOT NULL的列和变量,最好实践域为NULL,在下游应用NOT NULL列定义和变量声明。
计算字段
计算字段可以定义用COMPUTED [BY] 或 GENERATED ALWAYS AS子句(根据SQL:2003标准)。它们的意思是相同的。对于计算字段描述数据类型不是必需的(但可能),作为DBMS计算并存储表达式的结果分析的适当类型。对数据类型适当的操作包括在表达式中必须指定精度。
如果计算字段的数据类型显式指定,那么计算结果转换为指定的类型。这意味着,例如,一个数值表达式的结果可以呈现为一个字符串。在一个查询中,选择一个COMPUTED BY列,表达式为选定的每一行数据进行求值。
小技巧
使用一个常规列取代一个计算列,在某些情况下是有意义的,增加和更新数据时在触发器中对其求值,它将降低插入/更新记录的性能,但是它将提升数据选择的性能。
定义一个数组列
• 如果列是一个数组,基本类型可以是任何SQL数据类型除了BLOB和ARRAY之外。
• 数组的维数被规定在方括号中. (在语法块中,这些括号使用黑体出现,以区别于方括号标识的可选语法元素.)
• 对于每个数组维度,一个或两个整数数字定义其索引的上下边界范围:
- 默认情况下,数组是基于 1 的。下限是隐式的和仅上限边界需要指定。一个单独的数字小于 1 定义范围num..1 。和大于 1 的数字定义范围 1..num。
-用冒号(':')分隔的两个数字 和可选的空白,第二数大比第一大,可以用于显式的定义范围。一个或两个边界可以小于零,只要在上限边界是大于下限。
• 当数组具有多个维度时,每个维度的范围定义必须用逗号分隔和可选的空白。
• 仅当数组实际上存在时下标才会被验证。这意味着没有关于无效下标的错误消息将被返回,如果选择特定元素返回无,或者如果数组字段为空。
约束
四种约束类型可以指定.它们是:
• 主键(PRIMARY KEY)
• 唯一键 (UNIQUE)
• 外键 (REFERENCES)
• CHECK约束(CHECK)
约束可以指定在列级("列约束")或表级("表约束").表级的约束是需要的当键(唯一性约束、 主键、 外键)跨多个列组成时和 CHECK 约束当涉及除了被定义的列外的行中的其他列。根据约束是否被定义列或表级别上,对于某些类型的约束语法可能略有不同。
•一个列级的约束在列定义时被指定,毕竟除了排序规则列属性指定,可以只涉及定义中指定的列.
•表级的约束被指定在所有的列定义之后,它们是一个更灵活的方式来设置约束,因为他们可以满足涉及多个列的约束.
•可以混合列级和表级约束在同一CREATE TABLE语句,系统自动创建相应的主键(PRIMARY KEY),一个唯一键(UNIQUE)和一个外键(REFERENCES为列级约束,FOREIGN KEY REFERENCES在表级别)。
约束名和它们的索引
列级约束和它们索引是自动命名的:
• 约束名称的形式为INTEG_n,其中的n代表一个或多个数字
• 索引名称的形式为RDB$PRIMARYn(对一个主键索引)、 RDB$FOREIGNn(对一个外键索引)或RDB$n(对一个唯一键索引),同样的,其中的n代表一个或多个数字
表级约束和它们的索引自命名遵循相同的模式,除非名称被显式的提供.
命名约束
如果CONSTRAINT子句用于定义约束,一个约束能明确的命名,而CONSTRAINT子句是对于定义列级约束是可选的,对于表级是强制性的。默认情况下,约束索引将具有同约束相同的名称。如果需要一个不同名称的约束索引,一个 USING 子句可以被包含。
USING子句
USING子句允许为索引指定一个用户定义的名称也就是自动被建的,(可选)若要定义索引的方向--升序或降序(默认)。
主键
PRIMARY KEY约束被建立在一个或多个键列上,每个有一个NOT NULL约束被指定。在任何行中的跨键列的值必须是唯一的。一个表可以有只有一个主键。
• 单列主键可以被定义为列级或表级约束。
• 多列主键必须被定义为表级约束。
唯一性约束
UNIQUE约束定义内容唯一性的要求为值在一个键中贯穿整个表。一个表可以包含任意数量的唯一键约束。作为主键,唯一约束可以是多列。如果是这样,它必须指定为一个表级约束。
NULL在唯一键中
Firebird的SQL-99兼容规则为UNIQUE约束允许一个或多个NULL值在带有UNIQUE约束的列中.这使得它可以定义一个UNIQUE约束在没有not NULL的列上。
对于UNIQUE键,跨越多个列,逻辑有点复杂:
• 在键的的所有列中多行为NULL值是允许的
• 多行的键值中NULL值和非NULL值的不同组合是允许的
• 多行有相同的键列为NULL且余下填充为非NULL值是允许的,在至少一列中提供不同的值
•多行有相同的键列为NULL且余下填充为非NULL值是允许的,也就是在每一列将违反相同的约束
唯一性的规则可以这样概括:
例证:
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 ); -- 允许
INSERT INTO t values( NULL, NULL, 1 ); -- 不允许
FOREIGN KEY
外键可确保参与列可以包含只存在于被引用主表中的列值。这些被引用的列通常称为目标列。他们必须是主要关键或目标表中的唯一键。虽然它们不需要定义它们的 NOT NULL 约束,但如果它们是主键,当然它们是需要约束的。
外键列中引用的表本身不需要 NOT NULL 约束。
单列的外键可以定义在列声明中,使用关键字REFERENCES:
...,
ARTIFACT_ID INTEGER REFERENCES COLLECTION (ARTIFACT_ID),
列 ARTIFACT_ID在例子中引用一个相同名称列在的表COLLECTIONS中.
单列和多列外键可以被定义在表级别。多列外键,表级声明是唯一的选项。这种方法也可以提供一个可选的约束名字:
...
CONSTRAINT FK_ARTSOURCE FOREIGN KEY(DEALER_ID, COUNTRY)
REFERENCES DEALER (DEALER_ID, COUNTRY),
注意,列的名称在引用("主")表可以不同于那些外键原表中的名称。
备注
如果没有目标列被指定,外键自动引用目标表的主键。
外键动作
有关ON UPDATE和 ON DELETE 的子句是可以指定外键列在受影响应采取行动,当更改主表中的引用的值的时:
• NO ACTION (默认) - 什么都不做
• CASCADE - 主表的变化是传播到子表中相应的行。如果一个键值改变时,相应的键在子记录更改为新的值;如果主行删除,删除子记录.
• SET DEFAULT - 受影响的行中的外键列将被设置为它们的默认值,当外键约束被定义的时候。
• SET NULL - 受影响的行中的外键列将被设置为NULL值.
指定一个动作或默认的NO ACTION能导致一个外键列无效. 例如,它可以获取一个值,目前不在主表中,或它可能成为空,同时列具有 NOT NULL 约束。这种情况将导致操作在主表上失败与错误消息。
例子:
CONSTRAINT FK_ORDERS_CUST
FOREIGN KEY (CUSTOMER) REFERENCES CUSTOMERS (ID)
ON UPDATE CASCADE ON DELETE SET NULL
CHECK Constraint
CHECK约束定义在本列中插入的值必须满足条件。一个条件是一个逻辑表达式(也称为一个判断式)可以返TRUE、FALSE和UNKNOWN 的值。一个条件被认为是满足如果判断式返回TRUE或值UNKNOWN的(相当于NULL)。如果谓词返回FALSE,值不会被接受。这个条件是用于插入一个新行到表中(INSERT语句)和为更新表列的现有值(UPDATE语句)和对语句的这些行动之一也可能发生(UPDATE或INSERT、MERGE)。
重要
一个CHECK约束在一个基于域的列中不会取代在域上CHECK条件,但会变成一个附加的。Firebird数据引擎没有办法,在定义期间验证额外的CHECK不同存在的冲突。
CHECK条件 — — 是否定义在表级别或列级别 — — 通过他们的名字引用表中的列。
使用关键字VALUE作为一个占位符,作为域CHECK约束,使用上下文中变量定义列约束是无效的。
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.
例如: 使用两个列级约束和一个表约束:
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)
);
全局临时表
全局临时表有持久性元数据,但它们的内容是事务-绑定(默认值)或连接-绑定。每个事务或连接有自己私有的 GTT,隔绝所有的其他实例。当引用 GTT 时,才会创建实例。当事务记录结束或断线时它们被销毁。GTT 的元数据可以分别使用 ALTER TABLE 和DROP TABLE语句修改或删除。
语法:
CREATE GLOBAL TEMPORARY TABLE name
( [, { | } ...])
[ON COMMIT {DELETE | PRESERVE} ROWS]
语法注释
• ON COMMIT DELETE ROWS 创建一个事务级 GTT (默认值), ON COMMIT PRESERVE ROWS创建一个连接级 GTT
• An EXTERNAL [FILE] 子句在定义一个全局临时表时是不允的
GTT表的限制
Gtt 可以被"打扮"成具有普通表(键、 引用、 索引、触发器,等等)的所有的功能和,但有几个限制 ︰
• GTT表和普通表互相不能引用对方
•连接-绑定("PRESERVE ROWS") GTT 不能引用事务-绑定 ("DELETE ROWS") GTT
• 域约束不能引用任何GTT
• GTT 实例在其生命周期结束的 销毁不会导致任何 BEFORE/AFTER删除触发器的触发
小技巧
在一个存在的数据库中,它不是总是容易区分一个普通表从一个GTT 或事务级别GTT, 从连接级 GTT.使用此查询以找出正在查找的哪种类型的表:
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'
在数据库中所有关系类型的概况:
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
RDB$TYPE_NAME字段将显示PERSISTENT为一个普通表 , VIEW为一个视图, GLOBAL_TEMPORARY_PRESERVE 为连接-绑定GTT及GLOBAL_TEMPORARY_DELETE为事务-绑定GTT.
外部表
可选的EXTERNAL [FILE]子句指定表存储在数据库外部定长的外部文本文件记录。一个存储在外部文件中的表列可以是除外BLOB或ARRAY外任何类型的 ,虽然在大多数情况下,只有CHAR类型的列会是有用的。对一个表存储在外部文件中,所能做的是插入新行(INSERT)和查询数据(SELECT)。更新现有数据(更新)和删除行(删除)是不可能的。
文件定义为外部表必须位于一个物理存储设备上,也就Firebird服务器运行的机器上,如果参数 ExternalFileAccess 在firebird.conf中配置文件是限制的,它必须是在那里作为参数限制所列出的目录之一。如果文件尚不存在,Firebird将在首次访问时创建它。
重要
对一个表使用外部文件的能力依赖于在firebird.conf文件中ExternalFileAccess参数值的设置f:
• 如果被设置为None (默认值), 任何试图访问一个外部文件都将被拒绝
• 建议使用限制设置,目的是由服务器管理员用于限制外部文件访问显式创建的目录.例如:
- ExternalFileAccess = Restrict externalfiles 将限制存取Firebird根目录下被命名为externalfiles的目录。
- ExternalFileAccess = d:\databases\outfiles; e:\infiles 在Windows主机上将限制只能存取这两个目录,注释,任何网络映射将路径将无效,封闭在单引或双引号之间路径也将无效.
• 如果这个参数设置为Full,在这个主机文件系统上的任何地方外部文件都可存取,它创建一个安全漏洞,并不建议。
外部格式
外部表的"行"格式是定长的。没有字段分隔符:字段和行边界是由字段定义的最大字节数决定的。牢记这一点很重要,当定义外部表的结构,当设计一个输入文件为一个外部表来自导入另一个应用程序的数据时。例如,无处不在的".csv"格式,作为一个输入文件是无用的,并不能直接生成到外部文件中。
最有用的外部表的列的数据类型是固定长度的CHAR类型,它们是要传输的数据的适合的长度.日期和数字类型很容易地强制转换以及从成字符串,然而,除非文件是由另一个Firebird 数据库读取,本地数据类型将作为无法分析的"alphabetti" 出现在外部应用程序中。
当然,有办法操作输入数据,以便从Firebird生成输出文件,可以直接读取作为其他应用程序的输入文件到,使用存储过程,有或没有使用外部表。这种技术是超出了语言的参考范围。在这里,我们提供了一些指导和建议产生和使用简单的文本文件,因为外部表特性常常是作为一个简单的方法,生产或读取事务独立日志,它可以在文本编辑器中离线研究或审计应用程序。
行分隔符
一般来说,外部文件更有用如果行由一个分隔符,以“换行”序列的形式,它由目标平台上的阅读应用程序识别
读者认可的应用程序在目标平台上。
对于在Windows上的大多数上下文,是两个字节的“CRLF”序列,回车(ASCII代码十进制13)和换行(ASCII码十进制10)。在POSIX中,LF通常是它本身的;对一些MacOSX应用程序来说,这可能是LFCR。有多种方法填充这个分隔符列。在我们的示例中,它是通过使用Before Insert触发器和内部ASCII_CHAR函数。
外部表例子
在我们的示例中,我们将定义一个外部日志表,它可能被一个在存储过程或触发器中的异常处理程序使用,外部表被选择,因为来自任何处理的异常的消息将被保留在日志中,即使由于另一个未处理的异常启动进程最终回滚事务。出于演示的目的,它有两个数据列、 一个时间戳和一条消息。
第三列存储行分隔符:
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;
现在,用一个触发器在每一次的消息写入到文件时写入时间戳和行分隔符:
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 ;^
插入一些记录(这可能是由异常处理程序或莎士比亚的粉丝做的):
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')
输出:
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例子
1.创建COUNTRY表具有主键指定为列约束。
CREATE TABLE COUNTRY (
COUNTRY COUNTRYNAME NOT NULL PRIMARY KEY,
CURRENCY VARCHAR(10) NOT NULL);
2.创建STOCK表具有列级别指定命名的主键和在表级别指定的命名的唯一键 .
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.创建JOB表有一个主键约束跨越两列,一个对COUNTRY表的外键约束和表级CHECK约束。表还包含一数组有5个元素.
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.创建PROJECT表具有主键,外键和唯一键约束与自定义索引的名称,使用 USING 子句指定。
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. .创建SALARY_HISTORY表具有两个计算字段,第一个被声明根据SQL:2003 标准,而第二个声明根据Firebird传统的计算字段声明。
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)
);
6. 创建一个连接范围的全局临时表.
CREATE GLOBAL TEMPORARY TABLE MYCONNGTT (
ID INTEGER NOT NULL PRIMARY KEY,
TXT VARCHAR(32),
TS TIMESTAMP DEFAULT CURRENT_TIMESTAMP)
ON COMMIT PRESERVE ROWS;
7. 创建一个事务范围的全局临时表,使用一个外键引用一个连接范围的全局临时表。ON COMMIT是可选的,因为DELETE 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;