admin 管理员组文章数量: 887021
约束
约束是针对列的。在用户添加或修改列数据时,它用来对列数据用出一些限制。例如,非空约束限制了列不能为空。这就是约束。
我们可以在创建表的同时,创建约束。也可以先创建表,以后在有需要时,添回约束。下面我们先说在创建表的同时,创建约束。
1、建立表时指定约束
先看一个例子:
Table dropped.
gyj@OCM> create table t2(id number(10) constraint c_id not null, name varchar2(20));
Table created.
上面的命令创建T2表,并在ID列上创建名为C_ID的非空约束。其中,CONSTRAINT c_id的C_ID就是约束的名字。如果我们在创建约束时,也可以不为约束起名字,这样就可以省略CONSTRAINTc_id,那么系统将自动为约束命名:
Table dropped.
gyj@OCM> create table t2(id number(10) not null,name varchar2(20));
Table created.
只需要在列名后添加NOT NULL就可以了。这样很简单,但是ORACLE将自动为此约束起一个非常复杂的名字。
这是在创建表的同时创建约束。有些表是在创建之后,才发现应该为表中的某些列添加约束。
下面我们说一下如何在创建表之后,添加约束。
2、在创建表后添加非空约束
语法形式为:alter table 表名 modify (列名 类型(长度)[DEFAULT 默认值] [非空约束]) ;
这条命令的大部分,我们在前一章已经讲过,它可以更改表中指定列的长度、类型和默认值。当然,它还可以为表添加非空约束。注意,这条命令只能为表添加非空约束。其他类型的约束不使用此命令。
Table dropped.
gyj@OCM> create table t2(id number(10), name varchar2(20));
Table created.
gyj@OCM> alter table t2 modify (id constraint c_id not null);
Table altered.
同样,约束名可以省略,如果省略,系统将自定约束名。
3、删除约束
删除约束非常简单,我们看下面的测试吧,删除上面刚建立的t2_ID_NN约束。
Table altered.
二、条件检查约束 CHECK
CHECK非常简单,我们看下面的例子。我想将T2表的ID列值的大小,限制为正整数,也就是说能是0或负数:
Table dropped.
gyj@OCM> create table t2(id number(10) constraint c_id_1 check (id>=1),name varchar2(20));
Table created.
向ID列插入一个0试试:
insert into t2(id) values(0)
*
ERROR at line 1:
ORA-02290: check constraint (GYJ.C_ID_1) violated
像上面这样把约束的创建,直接放在列的后,这种方式创建的约束,被称为列级约束,也简称列约束。除了列级约束,还有表级约束,简称表约束。从隶属关系上来讲,列约束的相关信息,和列存储在一起,因此说列约束是属于列的。而表约束的相关信息,则和表存贮在一起,表约束属于表。从功能上讲,列约束和表约束是一样的。创建方式也非常的相似,下面我们建立一个属于表的CHECK约束:
Table dropped.
gyj@OCM> create table t2(id number(10), name varchar2(20),constraint t2_id_1 check (id>=1) );
Table created.
约束中,非空约束必须是列约束。其他类型的约束都即可以是列约束,也可以创建为表约束。不过和列约束相比,表约束有一个列约束所不能提供的功能,就是,一个表约束中可以涉及多列:
Table dropped.
gyj@OCM> create table t2(id number(10),
2 age number(3),
3 name varchar2(20),
4 company varchar2(40),
5 constraint t2_id_1 check (id>=age ) );
Table created.
如果是在创建表后再添加约束,命令如下:
gyj@OCM> drop table t2;
Table dropped.
gyj@OCM> create table t2(id number(10), age number(3), name varchar2(20), company varchar2(40));
Table created.
gyj@OCM> alter table t2 add(constraint t2_id_age_c check (id>age));
Table altered.
和添加非空约束相比,仍然是使用ALTER TABLE命令,但不在是MODIFY,而是ADD。这条命令也可以用来为表新增列除了非空约束外,其他类型的约束必须使用此命令添加。这样添加的约束,都是表级约束。
还有就是,在添加约束时,CHECK约束的条件有可能互相冲突:
Table dropped.
gyj@OCM> create table t2(id number(10), age number(3), name varchar2(20), company varchar2(40));
Table created.
gyj@OCM> alter table t2 add(constraint t2_id_11 check (id>=1 ));
Table altered.
gyj@OCM> alter table t2 add(constraint t2_id_12 check (id<=0 ));
Table altered.
我添加了两个约束,分别是t2_id_11和t2_id_12,两个约束都针对ID列,一个约束规定ID列的值一定要大于等于1,另一约束规定ID定必须小于等于0。现在,除了NULL值,ID列再也插入不进去任何值。
三、唯一约束 UNIQUE
唯一约束限制了列的值不能有重复。唯一约束必须依赖索引,在创建唯一约束时,将会同时创建相应的索引。有关索引的内容,我们到后面再讲。下面看一下如何创建唯一约束:
Table dropped.
gyj@OCM> create table t2(id number(10) constraint c_t2_id unique, age number(3), name varchar2(20));
Table created.
这是在列级定义约束,约束只针对一列。如果想让ID列和AGE列合起来唯一,而单独的ID列和AGE列可以重复,这就是在表中定义约束了。涉及多列的约束,只能在表级创建。
Table dropped.
gyj@OCM> create table t2(id number(10),
2 age number(3),
3 name varchar2(20),
4 constraint t2_id_age_u unique(id,age));
Table created.
在表创建后添加索引命令和添回CHECK差不多,我就不再做测试了。
四、主键 PRIMARY KEY
主键约束在效果上,相当于唯一约束+非空约束。也就是,即要求列值不能重复,又要求列值必须非空。
主键约束的创建方式、注意事项,除了把UNIQUE换为PRIMARY KEY外,都和唯一约束相同,关于他的创建,我们到下面和外键约束一起试。要注意的是,在同一列上,不能即有主键约束,又有唯一约束。
五、外键 FOREIGN KEY
主键约束可以单独发挥作用,它的作用相当于唯一+非空。而外键约束则必须主键结合在一起使用。在创建创建约束时,先必须先有一个主键,然后,根据此主键,创建一个相关联的外键约束。也就是说,外键约束必须对应一个主键,不能创建独立的外键约束。
主、外键约束通常创建在不同的表上,通过主、外键关系,可以将不同的表关联起来。外键约束的创建方式、注意事项,和主键约束、唯一约束相同。下面我们通过一个例子,来了解一下他的创建方式和作用:
我建立如下两个表:
Table created.
gyj@OCM> create table dept1(dept_id number(10), dept_name varchar2(20));
Table created.
emp1表是雇员表,包含雇员ID(ID)、姓名(NAME)和部门编号(DEPT)三列。
dept1表是部门表,包括部门编号(DEPT)、部门名称(DEPT_NAME)两列。
这两个表有对应的关系,雇员表的部门编号(DEPT)列,和部门表的部门编号(DEPT)列就是对应的。通常我们可以用这个列作等值连接,将两个表连接在一起显示更详细的信息。现在,需要对这两个表中的相关部门的列作出一些限制。比如,部门表中有A、B、C三个部门,哪么,雇员表中雇员的部门,也只能有A、B、C。也就是部门表中有什么部门,雇员才能是什么部门。不能雇员是D部门,但在部门表中根本就没有此部门。
像这样的限制,我们就可以通过主、外键约束来实现。dept1(部门表)表中的dept_id(部门编号)列应该被设为主键。而雇员表emp11中的dept_id列为外键:
Table altered.
gyj@OCM> alter table emp1 add(constraint c_emp1_dept1_f foreign key(dept_id) references dept1(dept_id));
Table altered.
注意添加外键约束的命令,foreign key(dept_id)说明要在本表上dept_id列上创建外键约束,references dept1(dept_id)说明此约束关联于DEPT1表中的DEPT_ID列上的主键。在执行此命令前,DEPT1表的DEPT_ID列必须有主键约束或唯一约束。注意,外键约束也可以关联到唯一约束。
现在,向部门表插入三个部门。
1 row created.
gyj@OCM> insert into dept1 values(2,'Administration');
1 row created.
gyj@OCM> insert into dept1 values(3,'Sales');
1 row created.
gyj@OCM> commit;
Commit complete.
如果向EMP1中插入这三个部门的雇员,是没有问题的:
1 row created.
如上,我插入了一个雇员编号为1,姓名为“Joe”的雇员,他属于销售部。但如果我插入部门编号为5的行,插入将会失败:
insert into emp1 values(2,'Rose',5)
*
ERROR at line 1:
ORA-02291: integrity constraint (GYJ.C_EMP1_DEPT1_F) violated - parent key not found
此时,以已有一条部门编号为3的雇员,再在主键中删除部门编号为3的行,会出现什么情况呢:
delete dept1 where dept_id=3
*
ERROR at line 1:
ORA-02292: integrity constraint (GYJ.C_EMP1_DEPT1_F) violated - child record found
ORACLE不允许你这么做。你必须先到子表中,删除所有部门编号为3的行,这样才能删除父表中部门编号为3的行。ORACLE可以自动为你做这个工作,但你要把子表的外键,设为级联删除,命令如下:
Table altered.
我先使用上面的命令将原来的外键约束删除。然后再用下面的命令添加可以级联删除的外键约束。
2 foreign key(dept_id)
3 references dept1(dept_id)
4 on delete cascade);
Table altered.
on delete cascade表示的就是级联删除行。级联删除的意思,也就是删除主表的部门编号为3的行时,子表中所有部门为3的行都跟着删除。
1 row deleted.
gyj@OCM> select * from emp1;
no rows selected
不过,有一点需要注意,这里的级联,并不是针对所有的DML命令,只能针对删除。on delete cascade中有一个DELETE单词,这就说明了这只是“级联删除”。不能级联更新、插入等等。
但更新命令是不可级联的:
1 row created.
gyj@OCM> update dept1 set dept_id=4 where dept_id=2;
update dept1 set dept_id=4 where dept_id=2
*
ERROR at line 1:
ORA-02292: integrity constraint (GYJ.C_EMP1_DEPT1_F) violated - child record found
外键必须对应主键,也就是子表必能对应一个父表。如果父表被删除了,子表怎么办,看试验:
drop table dept1
*
ERROR at line 1:
ORA-02449: unique/primary keys in table referenced by foreign keys
ORACLE不允许删除父表。除非使用级联约束:
2 /
Table dropped.
cascade constraints(级联约束)将先删除子表上的外键,再删除父表。cascade constraints在所有涉及约束的命令中都可以使用。比如,我们前面已经讲过的删除列,这可以使用这个选项,在删除列的同时,删除约束。
**********本博客所有内容均为原创,如有转载请注明作者和出处!!!**********
Name: guoyJoe
QQ: 252803295
Email: oracledba_cn@hotmail.com
Blog:
ITPUB: .html
OCM: .HTM
_____________________________________________________________
加群验证问题:哪些SGA结构是必需的,哪些是可选的?否则拒绝申请!!!
答案在:
Oracle@Paradise 总群:127149411
Oracle@Paradise No.1群:177089463(已满)
Oracle@Paradise No.2群:121341761
Oracle@Paradise No.3群:140856036
本文标签: 约束
版权声明:本文标题:约束 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1686514377h4519.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论