postgresql触发器

PG触发器

  • 实例
    • 建表
    • 建触发器函数
    • 建触发器
    • 插入数据
    • 验证
    • 删除表
    • 验证依赖于该表的触发器是否被删除
    • 重新建表并建立触发器,然后删除触发器函数
    • 反思
    • 测试
    • 重新建表并做测试
    • 总结

实例

建表

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');

验证

postgresql触发器_第1张图片
postgresql触发器_第2张图片
可以看到uptime字段的值被更新为了当前时间now(),说明触发器确实生效了;

删除表

postgresql触发器_第3张图片

验证依赖于该表的触发器是否被删除


可以当表被删除后,看到依赖于该表的触发器被删除了

重新建表并建立触发器,然后删除触发器函数

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();

postgresql触发器_第4张图片
在这里插入图片描述
可以看到直接删除触发器函数时,如果该触发器函数被某个触发器依赖,那么就会报错,此时需要在删除触发器函数的时候,添加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);
  • 截图
    postgresql触发器_第5张图片
    postgresql触发器_第6张图片
    postgresql触发器_第7张图片
    postgresql触发器_第8张图片
    postgresql触发器_第9张图片

重新建表并做测试

postgresql触发器_第10张图片
postgresql触发器_第11张图片
postgresql触发器_第12张图片
postgresql触发器_第13张图片
postgresql触发器_第14张图片

总结

  • 可以看到,当ta表中的id=3的记录被删除的时候,tc表中对应记录被删除了;
  • 默认情况下,外键约束存在会导致被依赖表无法直接删除,表中被依赖记录无法直接删除;
  • 当使用cascade删除ta时,tb与tc中的外键约束都被清除了,但是数据还在,即使tc中的外键是on delete cascade的;
  • 可以理解为默认情况下的外键是表级别的;
    而添加了on delete cascade参数的是记录级别的

你可能感兴趣的:(PostgreSQL)