实例
建表
create table ug(uid int, gid int , uptime varchar(30));
建触发器函数
CREATE or Replace FUNCTION func_ug_updateTime() RETURNS trigger
AS
$func_ug_updateTime$
BEGIN
If (TG_OP = 'UPDATE') THEN
If NEW.uptime = OLD.uptime Then
return null;
END IF;
END IF;
update ug set uptime = NOW() where uid = NEW.uid and gid = NEW.gid;
return null;
END;
$func_ug_updateTime$ LANGUAGE plpgsql;
建触发器
CREATE TRIGGER t_ug_updateTime AFTER INSERT OR UPDATE ON ug
FOR EACH ROW EXECUTE PROCEDURE func_ug_updateTime();
插入数据
insert into ug values(1,0, '2019-1-21 18:32:28');
insert into ug values(2,0, '2019-1-22 18:32:28');
insert into ug values(3,1, '2019-1-23 18:32:28');
insert into ug values(4,1, '2019-1-24 18:32:28');
验证
可以看到uptime字段的值被更新为了当前时间now(),说明触发器确实生效了;
删除表
验证依赖于该表的触发器是否被删除
可以当表被删除后,看到依赖于该表的触发器被删除了
重新建表并建立触发器,然后删除触发器函数
create table ug(uid int, gid int , uptime varchar(30));
CREATE TRIGGER t_ug_updateTime AFTER INSERT OR UPDATE ON ug
FOR EACH ROW EXECUTE PROCEDURE func_ug_updateTime();
可以看到直接删除触发器函数时,如果该触发器函数被某个触发器依赖,那么就会报错,此时需要在删除触发器函数的时候,添加cascade参数,从而将该触发器函数与依赖与该触发器函数的触发器一并被删除;
反思
触发器函数被触发器依赖的时候,需要使用cascade来进行删除;
但是当表被触发器依赖的时候,我们在删除表的时候,并不需要使用cascade来删除;
但是当A表被B表依赖(比如B.id引用A.id),那么在删除A的时候,必须使用cascade参数,才能成功删除A表,但是B表并不会被删除,因为真正的引用关系是B.id而不是B表本身,而是此时B表中依赖与A中的记录是否会被删除呢?
测试
- 代码
create table ta(id int primary key , name varchar(20));
insert into ta values(1, 'a'),(2,'b'),(3,'c');
create table tb(id int primary key , tid int);
alter table tb add constraint fk_tb_tid foreign key(tid) references ta(id);
insert into tb values(1, 1),(2,1),(3,2),(4,2);
create table tc(id int primary key , tid int);
alter table tc add constraint fk_tc_tid foreign key(tid) references ta(id) match simple on delete cascade on update cascade;
insert into tc values(1, 1),(2,1),(3,2),(4,2),(5,3);
- 截图
重新建表并做测试
总结
- 可以看到,当ta表中的id=3的记录被删除的时候,tc表中对应记录被删除了;
- 默认情况下,外键约束存在会导致被依赖表无法直接删除,表中被依赖记录无法直接删除;
- 当使用cascade删除ta时,tb与tc中的外键约束都被清除了,但是数据还在,即使tc中的外键是on delete cascade的;
- 可以理解为默认情况下的外键是表级别的;
而添加了on delete cascade参数的是记录级别的