主外键关系CRUD
-
准备工作
create table t_customer( id number, name varchar2(20) constraint customer_name_nn not null, constraint customer_id_pk primary key(id) ); create table t_order( id number, price number, customer_id number, constraint order_id_pk primary key(id), constraint order_cid_fk foreign key(customer_id) references t_customer(id) );
3.1 insert
注意,在有主外键关系的情况下,一定要先插入没有外键的一方,再插入有外键的一方。
因为外键列的值必须要在另外一张表中的主键列出现过。否则插入不进去
-
插入 t_customer
insert into t_customer values(1,'tom'); insert into t_customer values(2,'jerry'); insert into t_customer values(3,'terry');
-
插入 t_order
insert into t_order values(1,3000,1); insert into t_order values(2,3000,2); insert into t_order values(3,3000,2); -- 上面能够插入成功是因为 外键 外键列中的值 在 t_customer表中的主键列出现过。同时外键列的值可以重复 -- 外键列也可以为空,如果是在建表的时候手动给外键列添加了非空约束,那么就不能为空 insert into t_order values(1,3000,null); -- 插入失败,因为外键列的值 6 并没有在主键列中存在过 insert into t_order(id,price,customer_id) values(4,5000,6);
3.2 update
可以修改外键列的值,但是修改后的值也必须在另外一张表中的主键列中存在。
-
修改t_order中id为1的数据的customer_id 为 3
update t_order set customer_id = 3 where id = 1;
-
修改t_order中id为1的数据的customer_id 为 null
update t_order set customer_id = null where id = 1;
-
修改t_order中id为1的数据的customer_id 为 1000
update t_order set customer_id = 1000 where id = 1; -- 修改失败,因为在t_customer中的主键列没有 1000的值
3.3 delete
当删除的最好是先删除有外键的一方在删除无外键的一方。
因为如果先删除无外键的一方,那么就会导致另外一张表里面的外键列的值不知道怎么处理从而导致报错。
delete from t_order;
删除删除成功。因为这个表里面的数据不对对t_customer的数据产生任何进行影响。
再次插入数据进行测试:
insert into t_order values(1,3000,1);
insert into t_order values(2,3000,2);
insert into t_order values(3,3000,2);
删除 t_customer 中id为3的数据。
delete from t_customer where id = 3;
删除成功,因为id为3并没有在 t_order里面充当了外键。所以删除后不会对t_order表里面的数据产生影响。
删除 t_customer 中id为1的数据。
delete from t_customer where id = 2;
删除失败,因为在 t_customer里面id为2的数据,在t_order里面充当外键。所以当 把id为2的数据删除以后。
t_order不知道怎么处理 外键列customer_id 中为2的数据。因此报错。
要想不报错,可以先删除有外键的一方,在删除没有外键的一方。
但是如果非要直接删除没有外键的一方,那么就需要在建表的时候告诉有外键的一方,当没有外键的一方删除数据时,有外键的一方该怎么处理。
处理方式有三种:
- on delete no action 默认就是这种
- on delete cascade 级联操作,当删除数据时,另外一张表中也删除相关数据
- on delete set null 级联操作,当删除数据时,将另外一张表中相关的外键数据设置为空
3.3.1 默认方式
on delete no action
已上面 t_order
,t_customer
为例
delete from t_customer where id = 2;
报错,错误信息显示为: 违反完整约束条件- 已找到子记录
3.3.2 on delete cascade
需要在建表的时候指定外键的操作
create table t_teacher(
id number primary key,
name varchar2(255)
);
create table t_student(
id number primary key,
name varchar2(255),
teacher_id number references t_teacher(id) on delete cascade
);
insert into t_teacher(1,'wangzh');
insert into t_teacher(2,'xiezl');
insert into t_student(1,'天使1号',1);
insert into t_student(2,'天使2号',1);
insert into t_student(3,'天使3号',2);
删除 t_teacher表中id为1的数据
delete from t_teacher where id = 1;
发现 t_student中外键为1的数据也直接被删除了
3.3.3 on delete set null
create table tbl_hunsband(
id number primary key,
name varchar2(255)
);
create table tbl_wife(
id number primary key,
name varchar2(255),
hunsband_id number reference tbl_hunsband(id) on delete set null
);
insert into tbl_hunsband(1,'pantf');
insert into tbl_hunsband(2,'liangwei');
insert into tbl_hunsband(1,'xiaotao',1);
insert into t_student(2,'niurui',2);
删除 t_hunsband 表中 id为1的数据
delete from tbl_student where id = 1;
发现 t_wife表中 相关外键数据置空了。