Oracle数据库学习笔记——数据完整性(下)

参照完整性

表的一列或几列的组合的值在表中唯一地指定一行记录,选择这样的一列或多列的组合作为主键可实现表的实体完整性,通过定义PRIMARY KEY约束来创建主键。

外键约束定义了表与表之间的关系,通过将一个表中一列或多列添加到另一个表中,创建两个表之间的连接,这个列就成为第二个表的外键,通过定义FOREIGN KEY约束来创建外键。

使用PRIMARY KEY约束或UNIQUE约束来定义主表主键或唯一键,FOREIGN KEY约束来定义从表外键,可实现主表与从表之间的参照完整性。

定义表间参照关系的步骤是先定义主表主键(或唯一键),再定义从表外键。

使用SQL Developer 实现参照完整性

【例】使用SQL Developer,在stsys数据库中建立student表和score表的参照关系,再删除表间参照关系。

(1)按照前面介绍的方法定义主表主键,此处已定义student表的sno列为主键。

(2)启动”SQL Developer”,在”连接”节点下打开数据库连接”sys_stsys”,展开“表”节点,选中表score,单击鼠标右键,在弹出的快捷菜单中选择”编辑”命令,出现“编辑表”窗口,单击“外键”选项。

(3)单击“添加”按钮,在右边的“名称”栏中输入外键的名称,这里是score_student_FK1,在“引用表”栏中输入引用表的名称,这里是student,在“关联”栏的“本地列”中显示可用于创建外键的列,可以在下拉列表框中选择,这里选择sno,则在”student上的引用列”显示sno,如图所示。
在这里插入图片描述
4)单击 “确定”按钮,完成表间参照关系的创建。

(5)在上图所示的界面中,选择需要删除的外键,这里是score_student_FK1,单击“删除”按钮,单击“确定”按钮,即可删除选择的外键。

使用PL/SQL语句创建表间参照关系

创建主键(PRMARY KEY约束)及唯一键(UNIQUE约束)的方法在前面已作介绍,这里介绍通过PL/SQL语句创建外键的方法。

1)创建表的同时定义外键

语法格式:

CREATE TABLE <从表名>
(   <列定义> [ CONSTRAINT <约束名> ] REFERENCES <主表名>[ ( <列名> [ ,...n ] ) ]
 	  [,…n]
 [ [ CONSTRAINT <约束名> ] [ FOREIGN KEY ( <列名> [,...n ] ) [<参照表达式>]]
)

其中

<参照表达式>::=
 REFERENCES <主表名>[ ( <列名> [ ,...n ] ) ] 
 [ ON DELETE { CASCADE | SET NULL } ]

说明:
可以定义列的外键约束和表的外键约束。
定义列的外键约束在列定义的后面使用REFERENCES关键字定义外键,其对应的主表名的主键或唯一键的列名,在主表名后面的括号中指定。
定义表的外键约束在列定义的后面使用FOREIGN KEY关键字定义外键,并在后面包含要定义的列。
定义外键定义有以下参照动作:
ON DELETE CASCADE:定义级联删除,从主表删除数据时自动删除从表中匹配的行。
ON DELETE SET NULL:从主表删除数据时设置从表中对应外键键列为NULL。 如果未指定动作,当删除主表数据时,如果违反外键约束,操作会被禁止。

【例1】创建stu表,字段名与student表相同,其中sno列作为外键,与已建立的以sno列作为主键student表创建表间参照关系,并插入2条记录:121001,刘鹏翔,1992-08-25和121002,李佳慧,1993-02-18。

CREATE TABLE stu
(
  sno char(6) NOT NULL REFERENCES student(sno),  /*用这种方式定义了sno是外键*/
  sname char(8) NOT NULL,
  sbirthday date NULL
);

INSERT INTO stu VALUES('121001','刘鹏',TO_DATE('19920825','YYYYMMDD'));
INSERT INTO stu VALUES('121002','李佳',TO_DATE('19930218','YYYYMMDD'));

【例2】在stu表中,插入1条student表中不存在学号的记录:121005,王晓燕,1993-10-28;在student表中,删除1条stu表中已存在学号的记录:121001,刘鹏翔,1992-08-25。

INSERT INTO stu VALUES('121005','王晓燕',TO_DATE('19931028','YYYYMMDD'));

在stu表中插入的1条记录,其学号在student表中不存在,违反FOREIGN KEY约束,系统报错,拒绝插入。

DELETE FROM student
  WHERE sno='121001';

在student表中删除1条记录,其学号在stu表中已存在,违反FOREIGN KEY约束,系统报错,拒绝删除。(要先删了从表的才能删主表的)

【例3】创建sco表,字段名与score表相同,以学号、课程号组合作为外键,与已建立的以学号、课程号组合作为主键的score表创建表间参照关系,并且当删除score表中的记录时同时删除sco表中与主键对应的记录。

创建sco表,定义了外键和级联删除,其语句如下。

CREATE TABLE sco
(
  sno char(6)NOT NULL,
  cno char(4)NOT NULL, 
 grade int NULL,
  CONSTRAINT FK_sco FOREIGN KEY(sno,cno) REFERENCES score (sno,cno)  /*前一个(sno,cno)引用了score的(sno,cno),score是主表*/
     ON DELETE CASCADE
);

在从表sco表插入与主表score同样的18条记录。
由于在建立score表和sco表的表间参照关系时定义了级联删除,当删除score表cno为1004的记录时自动删除stu表中匹配行。

DELETE FROM score 
  WHERE cno='1004';

对主表执行结果进行查询,可以看出,主表已删除cno为1004的3条记录,剩下15条记录。

SELECT * 
  FROM score;

在这里插入图片描述
对从表执行结果进行查询,此时从表已自动删除cno为1004的3条记录,剩下15条记录,实现了级联删除。

SELECT * 
  FROM sco;

在这里插入图片描述

2)通过修改表定义外键

语法格式:

ALTER TABLE <表名>
     ADD CONSTRAINT <约束名>
           FOREIGN KEY( <列名>[,…n])
           REFERENCES <主表名>(<列名>[,…n]) <参照表达式>

【例】修改stsys数据库中score表的定义,将它的“课程号”列定义为外键,假设course表的“课程号”列已定义为主键。

ALTER TABLE score
  ADD CONSTRAINT FK_score_course FOREIGN KEY(cno) 
  REFERENCES course(cno);  /*score的cno引用了course的cno*/

2.使用PL/SQL语句删除表间参照关系

语法格式:

ALTER TABLE <表名>
  DROP CONSTRAINT <约束名>[,…n];

【例】删除以上对score课程号列定义的FK_score_course外键约束。

ALTER TABLE score
  DROP CONSTRAINT FK_score_course;

综合训练

(1)在stsys数据库中建立3个表:st,co,sc

CREATE TABLE st         /* 学生表 */
(  sno char(5),                    /* 学号 */
   sname char(10),             /* 姓名 */
   age int,                           /* 年龄 */
   sex char(2)                     /* 性别 */
);
CREATE TABLE co       /* 课程表 */
(  cno char(5),                   /* 课程号 */
   cname char(10),            /* 课程名 */
   teacher char(10)            /* 任课教师 */
);
CREATE TABLE sc        /* 成绩表 */
(  sno char(5),                    /* 学号 */
   cno char(5),                    /* 课程号 */
   grade int                         /* 分数 */
);

(2)将st表中sno修改为主键。

ALTER TABLE st
  MODIFY sno NOT NULL;
ALTER TABLE st
  ADD (CONSTRAINT PK_sno PRIMARY KEY(sno));

(3)将st表中的age列的值设为应在16~25之间。

ALTER TABLE st
  ADD (CONSTRAINT CK_age CHECK(age>=16 AND age<=25));

(4)将sc表中sno设置为引用sc表中sno列的外键。

ALTER TABLE sc
  ADD CONSTRAINT FK_sno 
    FOREIGN KEY (sno) REFERENCES st (sno);

(5)将sc表中cno设置为引用co表中cno列的外键。

ALTER TABLE co
  MODIFY cno NOT NULL;
ALTER TABLE co
  ADD (CONSTRAINT PK_cno PRIMARY KEY(cno));
ALTER TABLE sc
  ADD CONSTRAINT FK_cno 
     FOREIGN KEY (cno) REFERENCES co (cno);

(6)删除前面所有的限定。

ALTER TABLE sc
  DROP CONSTRAINT FK_sno;
ALTER TABLE sc
  DROP CONSTRAINT FK_cno;
ALTER TABLE st
  DROP CONSTRAINT PK_sno;
ALTER TABLE st
  DROP CONSTRAINT CK_age;
ALTER TABLE co
  DROP CONSTRAINT PK_cno

猜你喜欢

转载自blog.csdn.net/weixin_45550460/article/details/105192075