1.5.2 如何在创建表时指定约束
约束可以在创建表的同时指定,也可以在表创建之后再指定。如果与表同时创建,那么在创建表的CREATE语句中通过CONSTRAINT关键字指定约束的名称和约束类型。同时创建表和约束的CREATE语句格式为:
CREATE TABLE表名(
列1 数据类型 CONSTRAINT 约束名1 约束类型,
列2 数据类型 CONSTRAINT 约束名2 约束类型,
……
);
其中约束名是为约束指定的唯一的名称。约束名可以由用户自己指定,也可以自动产生。如果省略关键字CONSTRAINT和约束名称,那么约束名称将自动产生。如果约束名称是自动产生的,那么根据这样的名称无法判断约束所在的表以及约束类型。如果用户自己指定约束名称,则可以在名称中包含表名、约束类型等有用信息。
如果在一个列的定义之后指定该列上的约束时,这种定义约束的方法称为列级约束。例如,下面的CREATE语句用来创建一个表,名为student,在各个列上都指定了约束。
SQL>CREATE TABLE student(
sno number(8)PRIMARY KEY,
sname char(8)NOT NULL,
gender char(2)CHECK(gender in('男','女')),
birthday date,
school varchar(40));
在创建表student时指定了三个约束,第一个约束指定学号sno列为主键,第二个约束指定姓名sname列不为空,第三个约束指定性别gender列的值只能是“男”或“女”,这些约束都是列级约束。在创建表时没有为这几个约束指定名字,系统将自动为它们指定各自的名字。下面的CREATE语句在创建表时指定约束,并为每个约束指定了名字。
SQL>CREATE TABLE student(
sno number(8)CONSTRAINT pk_sno PRIMARY KEY,
sname char(8)CONSTRAINT nn_sname NOT NULL,
gender char(2)CONSTRAINT gen_check CHECK(gender in('男','女')),
birthday date,
school varchar(40));
约束可以在每个列的定义之后分别指定,也可以在所有列的定义之后一起指定。如果一个约束在表定义的最后才指定,这样的约束定义方法称为表级约束。如果一个约束涉及多个列的组合,那么就不能在每个列之后指定约束,而只能定义为表级约束。例如,若表student的主键列不是sno列,而是sno列和sname列的组合,这样的约束就不能在sno列或sname列之后指定,而只能在所有列的定义之后再指定。定义表级约束的CREATE语句格式为:
CREATE TABLE 表名(
列1 数据类型,
列2 数据类型,
……
CONSTRAINT 约束名1 约束类型(列名),
CONSTRAINT 约束名2 约束类型(列名),
……);
在五种约束中,NOT NULL约束只能以列级约束的形式定义,其余四种既可以以列级约束的形式定义,也可以以表级约束的形式定义。因为表级约束是在所有列之后定义的,而不是在某个具体的列之后定义,所以在表级约束中要指定相关的列名。
例如,上面的创建表的CREATE语句也可以改为下面的形式:
CREATE TABLE student(
sno number(8),
sname char(8)CONSTRAINT nn_sname NOT NULL,
gender char(2),
birthday date,
school varchar(40),
CONSTRAINT pk_sno PRIMARY KEY(sno),
CONSTRAINT gen_check CHECK(gender in('男','女'))
);
外键约束的定义形式比较复杂,因为外键要与另一个表的主键进行关联,所以不仅要指定约束的类型和有关的列,还要指定与哪个表的哪个列进行关联。
如果在列级定义外键约束,定义的格式为:
CONSTRAINT约束名REFERENCES表名(列名)
其中约束名是为这个外键约束起的名字。FOREIGN KEY为约束类型,即外键约束。REFERENCES关键字指定与哪个表的哪个列进行关联。例如,在表emp中,外键列为deptno,它与表dept的deptno列进行关联。这个外键的定义语句为:
CONSTRAINT fk_deptno REFERENCES dept(deptno)
这条代码放置在emp表的deptno列定义之后。如果要在表级定义外键约束,那么外键的定义代码放置在所有列的定义之后,它的格式为:
CONSTRAINT约束名FOREIGN KEY(外键列)REFERENCES表名(列名)
例如,在表emp中的deptno列上施加的外键约束也可以通过下面的形式定义:
CONSTRAINT fk_deptno FOREIGN KEY(deptno)REFERENCES dept(deptno)
约束作为一种附加在表上的数据库对象,它的信息也被记录在数据字典中。与约束有关的数据字典有两个,一个是user_constraints;另一个是user_cons_columns。其中在数据字典user_constraints中记录当前用户所拥有的约束的信息,如约束名、约束类型、约束所在的表、约束的状态等。如果是外键,还记录了与之关联的主键名称。例如,下面的SELECT语句用来查询表student上的约束信息:
SQL>SELECT constraint_name AS名称,constraint_type AS约束类型,status AS状态
FROM user_constraints
WHERE table_name='STUDENT';
这条SELECT语句的执行结果为:
约束名 约束类型 状态
NN_SNAME C ENABLED
GEN_CHECK C ENABLED
PK_SNO P ENABLED
如果要进一步查询约束施加在哪个列上,就需要查询另一个数据字典了,它就是USER_CONS_COLUMNS。例如,下面的SELECT语句查询表student中的各个约束是在哪个列上定义的:
SQL>SELECT constraint_name, table_name, column_name
FROM user_cons_columns WHERE table_name='STUDENT';
这条SELECT语句的执行结果为:
CONSTRAINT_NAME TABLE_NAME COLUMN_NAME
NN_SNAME STUDENT SNAME
PK_SNO STUDENT SNO
GEN_CHECK STUDENT GENDER