19 外键约束

--外键

--作用:当在字表中插入的数据在父表中不存在,则会自动报错
--概念:当一张表的某个字段需要依赖另一个表的某个字段的值,则使用外键。其中主动依赖的表称为字表,被依赖的表称为父表。外键加在字表中。

--使用:

--在创建表时字段后:cno number(10) references 父表名(父表字段名)
--在创建表的最后:constraints fk_表名_字段名 foreign key (字段名) references 父表名(父表字段名)
--在已经创建表完毕后添加:alter table 表名 add constraints fk_表名_字段名 foreign key (字段名) references 父表名(父表字段名)

--缺点:

--当子表没有清除完毕,无法删除父表中的记录,除非使用级联删除

delete from clazz where cno=1;--报错:已找到字表记录

--解决方法:

--使用级联删除:当删除父表数据时,自动删除此字段和子表相关的所有记录 或 设置子表中的依赖字段为空

  • --在字表创建时:cno number(10) references clazz(cno) on delete cascade 删除父表记录时会删除字表相关记录
  • --在创建子表时:cno number(10) references clazz(cno)  on delete set null 这样删除父表记录时,字表相关记录的相关字段会被设置为空,字表记录本身不会被删除
    •   --注意:字表的依赖字段不能设置为非空,否则on delete set null无效 

例子:

create table student(
sno number(10) primary key,
sname varchar2(10) not null,
sage number(3) check(sage>0 and sage <150),
ssex char(4)check(ssex='男' or ssex='女'),
sfav varchar2(500),
sqq varchar2(30) unique,
cno number(10)
)
--查询
select * from student;
select * from clazz;
--添加学生测试数据
insert into student values(1,'张三001',18,'男','唱歌','112414545',1);
insert into student values(2,'张三002',18,'男','唱歌','112414546',1);
insert into student values(3,'李四001',18,'男','唱歌','112414547',2);
insert into student values(4,'李四002',18,'男','唱歌','112414548',2);
--创建班级表
create table clazz(
cno number(10) primary key,
cname varchar2(100) not null,
cdesc varchar2(300)
)
--添加班级测试数据
insert into clazz values(1,'java高薪就业班','好厉害');
insert into clazz values(2,'python就业班','真的凶');
--联合查询:学生及其班级信息
select * from student
join clazz
on student.cno=clazz.cno;
--发现问题:可以插入一个学生但这个学生的班级是一个不存在的班级
insert into student values(5,'王二',19,'男','打篮球',213123,3);
--解决方法:在创建学生表时,cno(班级number)设置为另一个表的主键,这个行为称为设置外键
  --先删掉原有的student表
drop table student;
  --在创建新的设置了外键的student表,执行后再执行上面的添加学生的语句
create table student(
sno number(10) primary key,
sname varchar2(10) not null,
sage number(3) check(sage>0 and sage <150),
ssex char(4)check(ssex='男' or ssex='女'),
sfav varchar2(500),
sqq varchar2(30) unique,
cno number(10) references clazz(cno)--或在最后 foreign key(字段) references 另一个表名(字段名)
)
--外键概念
  --作用:当在字表中插入的数据在父表中不存在,则会自动报错
  --概念:当一张表的某个字段需要依赖另一个表的某个字段的值,则使用外键。
    --其中主动依赖的表称为字表,被依赖的表称为父表。外键加在字表中
  --使用:
    --在创建表时字段后:cno number(10) references 父表名(父表字段名)
    --在创建表的最后:constraints fk_表名_字段名 foreign key (字段名) references 父表名(父表字段名)
    --在已经创建表完毕后添加:alter table 表名 add constraints fk_表名_字段名 foreign key (字段名) references 父表名(父表字段名)
  --缺点:
    --当子表没有清除完毕,无法删除父表中的记录,除非使用级联删除
    delete from clazz where cno=1;
    --级联删除:当删除父表数据时,自动删除此字段和子表相关的所有记录
      --使用方式,创建字表时设置外键后面添加 on delete cascade:在字表创建时:cno number(10) references clazz(cno) on delete cascade 
                           --先删掉原来的约束再添加
                            select  * from user_cons_columns order by table_name; 
                            alter table student drop constraints SYS_C007041;
    alter table student add constraints fk_student_cno foreign key(cno) references clazz(cno) on delete cascade;
                            --成功删除,我们来删父表记录试试
    delete from clazz where cno=1;
    --查询:相关自己录被一并删除
    select * from student;
    select * from clazz;
     --缺点:使用上面的方式删除父表记录时会删除字表相关记录
      --解决方法,在创建子表时在设置外键后面添加 on delete set null,这样删除父表记录时,字表相关记录的相关字段会被设置为空,记录本身不会被删除
       --注意:字表的依赖字段不能设置为非空,否则on delete set null无效
          --先删掉原来的约束
          alter table student drop constraints fk_student_cno;
          --再添加带delete set null关键字的约束
                       --删除学生:delete from student;
          delete from student;
                       --添加约束
    alter table student add constraints fk_student_cno foreign key(cno) references clazz(cno) on delete set null;
                       --添加班级
                       --添加学生
insert into student values(1,'张三001',18,'男','唱歌','112414545',1);
insert into student values(2,'张三002',18,'男','唱歌','112414546',1);
insert into student values(3,'李四001',18,'男','唱歌','112414547',2);
insert into student values(4,'李四002',18,'男','唱歌','112414548',2);
            --删除clazz记录
            delete from clazz;
            --查询学生
            select * from student;
   

  

猜你喜欢

转载自www.cnblogs.com/Scorpicat/p/12306745.html