我们又在实验楼做实验啦,这次是Oracle数据库的关于表的“约束”的那些事

表的约束

也称为表的完整性约束,是Oracle数据库中应用在表数据上的一系列强制性规则。

完整性约束 是保证用户对数据库所做的修改不会破坏数据的一致性,是保护数据正确性和相容性的一种手段。

当向已创建的表中插入数据或者修改表中的数据时,必须满足表的完整性约束所规定的条件。

表的完整性约束,既可以在创建表时指定,也可以在表创建之后再指定。一般建议在创建表时指定约束,因为建好表后,不一定再满足条件成功约束。

按照约束的作用域,可将表的完整性约束进行如下分类:

(1)表级约束,对表中多个字段起作用。

(2)字段级约束,对一个字段起作用,一般在该字段定义完毕后指定。

按约束的用途,将表的完整性约束分为:

(1)Not NULL

(2)UNIQUE

(3)PRIMARY KEY

(4)FOREIGN KEY

(5)CHECK

2.1 非空约束(NOT NULL)

默认情况下,表中所有字段值都允许为空,NULL为各字段的默认值。

not null 约束规定表中相应字段上的值不能为空。

例1:创建表student_2,表中包括学号(sno),姓名(sname),性别(ssex),出生日期(sbirthday),邮箱(semail),所在系(sdept),要求为姓名字段定义not null约束

create table student_2(
sno char(10),
sname varchar2(30) constraint sname_notnull NOT NULL,
ssex char(3),
sbirthday DATE,
semail varchar2(25),
sdept varchar2(30)
);

查看是否成功定义了NOT NULL约束

desc student_2

例2:向student_2表中添加数据,检验约束是否起作用

insert into student_2 values(
'202004081001','zhangsan''M',to_date('12-dec-2020'),'[email protected]','Math'
);
//再插入一条记录
insert into student_2 values(
'202004081001',,'M',to_date('12-dec-2020'),'[email protected]','Math'
);
//再来一条记录
insert into student_2 values(
'202004081001',NULL'M',to_date('12-dec-2020'),'[email protected]','Math'
);
//再来一条记录
insert into student_2(sno,ssex,sbirthday,semail,sdept) values(
'202004081001','M',to_date('12-dec-2020'),'[email protected]','Math'
);

关于not null约束的修改操作

例3:为表student_2的ssex字段添加非空约束。

alter table student_2
modify ssex constraint ssex_notnull NOT NULL;

关于约束名称,为方便对表中约束进行管理,可起名为constraint_name = column_notnull

如何删除已存在的非空约束?

例4:删掉sudent_2表中的ssex的非空约束。

alter table student_2 
modify ssex null;
2.2 唯一性约束(UNIQUE)UK

unique约束要求表中一个字段或者一组字段中的每个值都是唯一的。

唯一性约束允许字段为空,除非该列使用了非空约束。

例5:定义单个字段的unique约束,创建一个表student_3,表中各字段均和student_2相同,要求邮箱定义unique约束。

create table student_3(
sno char(10),
sname varchar2(30),
ssex char(3),
sbirthday DATE,
semail varchar2(25) constraint semail_unique UNIQUE
    );

例6:向表student_3中semail字段插入数据

insert into student_3(semail) values('[email protected]');
//再次插入数据
insert into student_3(semail) values('[email protected]');
//看看系统有个反应

多个字段的unique约束定义必须在所有字段定义完毕后再指定,并且必须明确指定约束名

例7:创建一个表student_4,表中各字段均与student_2相同,并多一手机字段(stelephone),要求为

手机号(stelephone)和邮箱(semail)定义unique约束。

create table student_4(
sno char(10),
sname varchar2(30),
ssex char(3),
sbirthday DATE,
stelephone char(11),
semail varchar2(30),
sdept varchar2(30),
constraint table_unique UNIQUE(stelephone,semail)
);

例8:为student_4表sname字段添加unique约束。为sno添加unique约束。

alter table student_4
add constraint sname_unique UNIQUE(sname);
//
alter table student_4
add constraint uk_sno unique(sno);

例9:创建member表,在Email字段设置唯一约束。

drop table member purge;
create table member(
mid number,
name varchar2(20) NOT NULL,
email varchar2(50) UNIQUE
);

说明:如果为某个字段定义了unique约束,而该字段上没有定义NOT NULL约束,那么在该字段上允许出现多个NULL值,而oracle认为两个NULL值不相等。

如果unique约束为指定名称,删除时,可以使用alter table drop语句,如果unique约束指定了名称,删除时,使用alter table drop constraint语句。

例10:删掉member表中email的unique约束。

--查看表中字段的约束名称
select constraint_name,constraint_type,table_name from user_constraints;
--一般有约束名的,直接使用约束名,没有设置约束名的,系统将自动产生以SYS_Cxxxxxx格式的约束名
alter table member drop constraint SYS_c000009;
2.3 主键约束(PRIMARY KEY)PK

primary key约束是用来约束表的一个字段或几个字段的。

其取值唯一,且不为NULL。同一个表中只能定义一个primary key约束。

Oracle会自动为具有primary key约束的字段建立一个唯一索引和一个NOT NULL约束。

单个字段的主键约束定义,一般应在该字段定义完毕后指定。

例11:在表student_5中,定义单独字段primary key 约束。

create table student_5(
sno char(10) primary key,
sname varchar2(30),
ssex char(3),
sbirthday DATE,
stelephone char(11),
semail varchar2(30),
sdept varchar2(30)
);

多个字段的主键约束定义必须在所有字段定义完毕后再指定,并且必须明确指定约束名。

例12:创建学生表student_6,要求学号和姓名定义主键约束。

create table student_6(
sno char(10) ,
sname varchar2(30),
ssex char(3),
sbirthday DATE,
stelephone char(11),
semail varchar2(30),
sdept varchar2(30),
    constraint table_primarykey PRIMARY KEY(sno,sname)
);

例13:在已有表中添加主键约束。在member表中,添加mid为主键约束。

--member表
drop table member purge;
create table member(
mid number,
name varchar2(20) NOT NULL,
email varchar2(50) UNIQUE
);
--为mid字段添加主键约束
alter table member add PRIMARY KEY(mid);

删除primary key约束,可以使用alter table drop语句

如何查看表的字段具有哪些约束属性,以及这些约束的名称?

例14:给数据表student_4的sno字段添加NOT NULL约束,并查看该表具有哪些约束属性,如有主键约束,则删除其约束。

alter table student_4 modify sno constraint sno_notnull NOT NULL;
select constraint_name,constraint_type,table_name from user_constraints where table_name='STUDENT_4';
alter table student_6 drop constraint table_primarykey;

说明:如果要删除表中的主键约束,首先要考虑这个主键是否已经被另一个表中的外键关联,如果没有关联,那么这个主键约束可以直接被删除,否则不能被直接删除,此时必须将连同与之关联的外键约束一同删除。

2.4 外键约束(FOREIGN KEY)FK

外键用于与另外一个表之间建立关联关系。

两个表之间的关联关系是通过主键和外键来维持的。

外键规定本表中该字段的数据必须是另一个与之关联的表的主键中的数据或者NULL。

外键可以是一个字段,也可以是多个字段的组合。

在一个表中只能有唯一一个主键,但是可以有多个外键。

例15:创建两个表分别为class和student_7。在class表中设置classid为主键,在student_7表中设置classid为外键,且引用class表中的classid字段

--class表
create table class(
classid number primary key,
classname varchar2(40),
classcount number
);
--student_7表
create table student_7(
sno char(10),
sname varchar2(30),
ssex char(3),
classid number,
constraint student_7_class FOREIGN KEY(classid) references class(classid)
);

注意:主键classid所在的表class先于外键classid所在表student_7创建,否则,Oracle系统会给错误提示。

例16:向表class输入数据,应用脚本输入,脚本名为t1.sql。

--script:t1.sql
insert into class values(1,'16cloud1',65);
insert into class values(2,'17cloud1',55);
insert into class values(3,'18cloud1',45);

例17:创建脚本t2.sql向表student_7表中输入数据。

--script:t2.sql
insert into student_7 values(20204111,'Zhangsan','M',1);
insert into student_7 values(20204112,'Lisi','FM',2);
insert into student_7 values(20204113,'Wangwu','M',3);

以上两个表,在插入记录时,必须确保插入记录所对应的外键classid的数据值,要么在class表中的主键classid存在,要么为NULL,否则会出错。

例18:删除表class中的classid为1的记录,看看是否能成功。

delete from class where classid =1;

如何向已存在却无外键约束的表中添加外键约束?

例19:创建表student_8,字段于student_7一致,而无约束,然后向表student_8中添加外键约束。

--新建无约束表
create table student_8(
sno char(10),
sname varchar2(30),
ssex char(3),
classid number
);
--添加外键约束
alter table student_8 add constraint student_8_class FOREIGN KEY(classid) references class(classid) ;

说明:通常,将引用表称为“子表”,student_7和student_8均为子表,将被引用表称为“父表”,如class。

例20:创建表student_9,与student_7一致,并且指定在主键classid中的数据被删掉时,外键classid所对应的数据也级联删除。

create table student_9(
sno char(10),
sname varchar2(30),
ssex char(3),
classid number,
constraint student_9_class FOREIGN KEY(classid) references class(classid)
    on delete cascade
);
--on delete参数为设定当主键的数据被删除时,外键所对应的字段的数据值是否自动删除。
--如果后面跟cascade,则自动被删除,如果后面跟set null,则会将该外键值设为null,如果后面跟no action 子表中的外键如果包含该数据值,则禁止操作。默认选择为no action。

例21:删除表student_7和student_8,并向表student_9中插入3条记录。

drop table student_7;
drop table student_7;
--insert record into student_9
insert into student_9 values(20204111,'Zhangsan','M',1);
insert into student_9 values(20204112,'Lisi','FM',2);
insert into student_9 values(20204113,'Wangwu','M',1);

例22:级联删除的问题:在主键-外键相关联的表class和student_9中,删除表class中的classid为1的记录,看看是否能成功。并查看student_9的记录。

delete from class where classid =1;

例23:查看用户各表中存在各种约束的字段。

select * from user_cons_columns;
2.5 检查约束(CHECK)

check约束是一个关系表达式,它规定了一个字段的数据必须满足的条件。

当向表中插入一条记录或者修改某条记录的值的时候,都检查指定字段的数据值是否满足这个条件,如果满足,操作才能成功。

check约束可以被创建或者增加为在某个字段级别上的约束,也可以被创建或者增加为在一个表级别上的约束。

例24:创建表student_9,与student_2字段一样,设置性别ssex字段为check约束,要求只允许该字段的数据值为“M”或“FM”。

create table student_9(
sno char(10),
sname varchar2(30),
ssex char(3),
classid number,
constraint ssex_check CHECK(ssex in ('M','FM'))
);

例25:向student_9中插入记录,试试能否成功。

insert into student_9 values('20200411','zhangsan','xx',1);

检查约束,可在创建表的时候设置,也可在已创建好的表中再创建。可使用alter table ……add语句添加。

2.6 禁用和激活约束
约束的状态

表的完整性约束可处于两种状态:

激活状态(enable):激活状态下,约束将对表的插入或更新操作进行检查,与约束规则发生冲突的操作将被禁止。

禁用状态(disable):禁止状态下,约束不再起作用,与约束规则发生冲突的表的插入或者更新操作也能够成功执行。

一般情况下,为了保证数据库中的数据完整性,表中的约束应当处于激活状态。

当执行一些特殊的操作时,出于性能方面的考虑,有时候会将约束置于禁用状态。

禁用约束的操作包括:

(1)利用sql*loader从外部数据源提取大量数据到表中时。

(2)针对表执行一项包含大量操作的批处理工作时。

(3)导入导出表时。

定义方法

创建表的时定义约束的状态的语法格式:

create table [schema.]table_name(
……
……
[constraint constraint_name] constraint_type disable | enable);

也可以对已经创建的表使用修改表中的约束状态。

--1
alter table table_name enable | disable constraint constraint_name;
--2
alter table table_name modify constraint constraint_name enable |disable;

例26:将student_9中的ssex字段的检查约束设为禁用状态。

alter table student_9 modify constraint ssex_check disable;
2.7约束的验证状态

激活或者禁用状态是指在设置该状态之后,对表进行插入或更新操作时,是否对约束限制进行检查。与之对应,约束的另外两个状态决定是否对表中已有的数据进行约束限制检查。这两种状态为:

验证状态validate:如果约束处于验证状态,在定义或激活约束时,oracle将会检查表中所有已有的记录是否满足约束限制。

非验证状态novalidate:如果约束处于非验证状态,在定义或激活约束时,oracle不会检查表中所有的记录是否满足约束限制。

将验证、非验证、激活、禁用状态结合,可以合成4种约束状态。

enable validate
enable novalidate
disable validate
disable nocalidate

例27:将前例中已创建好的student_3表中为邮箱semail定义的unique约束设置为非验证激活状态。

alter table student_3 modify constraint semail_unique enbale novalidate;

你可能感兴趣的:(Oracle)