【postgresql初级使用】触发器的enable与disable,可以自动化精准管理触发器,避免重写触发器复杂逻辑

触发器的enable与disable

专栏内容

文章目录

概述


最近几篇文章分享了触发器相关内容,有行级触发器,也有语句级触发器,postgresql还支持视图上的INSTEAD OF触发器。

这么多的触发器,如何进行维护呢?除了删除drop 触发器之外,还可以对暂时不用的触发器禁用disable,使用时再启用enable,这样方便快捷,不用重写。

禁用触发器


先来看下禁用触发器,禁用触发器,并不是将它删除,触发器的定义仍然保留在数据库中,只是在事件触发时不再响应了。

禁用语法

对于普通触发器,都是定义在表对象上,可以禁用某个表上的触发器,SQL语法如下:

sql 复制代码
ALTER TABLE table_name
DISABLE TRIGGER [ trigger_name | ALL | USER ]

说明

  • 通过alter table命令对表对象进行修改;
  • disable trigger后面指定触发器范围:
    指定单个触发器的名称;
    ALL, 该表上所有的触发器,包括系统生成的,如表的唯一约束或外键或排它约束生成的触发器;此时需要超级权限的用户才能执行;
    USER,该表上的所有触发器,除了系统生成的,也就是只包含用户自定义的;

案例演示

结合《条件触发器》一文中的案例,

查看orders表上的触发器如下。

shell 复制代码
postgres=> \d orders
                                  Table "senlleng.orders"
    Column    |         Type          | Collation | Nullable |           Default
--------------+-----------------------+-----------+----------+------------------------------
 order_id     | integer               |           | not null | generated always as identity
 customer_id  | integer               |           | not null |
 total_amount | numeric               |           | not null | 0
 status       | character varying(20) |           | not null |
Indexes:
    "orders_pkey" PRIMARY KEY, btree (order_id)
Triggers:
    insert_customer_stats_trigger AFTER INSERT ON orders FOR EACH ROW EXECUTE FUNCTION insert_customer_stats()
    update_customer_stats_trigger AFTER UPDATE ON orders FOR EACH ROW WHEN (old.status::text <> 'completed'::text AND new.status::text = 'completed'::text) EXECUTE FUNCTION update_customer_stats()

有两个触发器 insert_customer_stats_triggerupdate_customer_stats_trigger

现在将第二个触发器禁用,达到结帐失败的效果。

sql 复制代码
postgres=> alter table orders disable trigger update_customer_stats_trigger;
ALTER TABLE

下面演示一下客户结帐的流程。

  • 新增客户
shell 复制代码
postgres=> INSERT INTO orders (customer_id, total_amount, status)
VALUES (3, 100, 'pending');
INSERT 0 1
  • 结帐
shell 复制代码
postgres=> UPDATE orders
SET status = 'completed'
WHERE customer_id = 3;
UPDATE 1
  • 查看帐单
shell 复制代码
postgres=> select * from customer_stats where customer_id =3;
 customer_id | total_spent
-------------+-------------
           3 |           0
(1 row)

最后帐单没有进行统计,仍然为0元。

启用触发器


将原来数据库中已经存在,但是被禁用的触发器,让它再次响应事件,并执行相关逻辑。

启用语法

启用触发器的SQL语法如下:

sql 复制代码
ALTER TABLE table_name
ENABLE TRIGGER [ trigger_name | ALL | USER ]

说明

  • 通过alter table命令对表对象进行修改;
  • enable trigger后面指定触发器范围:
    指定单个触发器的名称;
    ALL, 该表上所有的触发器,包括系统生成的,如表的唯一约束或外键或排它约束生成的触发器;此时需要超级权限的用户才能执行;
    USER,该表上的所有触发器,除了系统生成的,也就是只包含用户自定义的;

案例演示

将上面禁用的结帐触发器,再次启用,预期效果时可以自动计算结账金额。

sql 复制代码
postgres=> \d orders
                                  Table "senlleng.orders"
    Column    |         Type          | Collation | Nullable |           Default
--------------+-----------------------+-----------+----------+------------------------------
 order_id     | integer               |           | not null | generated always as identity
 customer_id  | integer               |           | not null |
 total_amount | numeric               |           | not null | 0
 status       | character varying(20) |           | not null |
Indexes:
    "orders_pkey" PRIMARY KEY, btree (order_id)
Triggers:
    insert_customer_stats_trigger AFTER INSERT ON orders FOR EACH ROW EXECUTE FUNCTION insert_customer_stats()
Disabled user triggers:
    update_customer_stats_trigger AFTER UPDATE ON orders FOR EACH ROW WHEN (old.status::text <> 'completed'::text AND new.status::text = 'completed'::text) EXECUTE FUNCTION update_customer_stats()

现在将上面禁用的触发器再次启用,预期效果是结帐时可以查到帐单总金额。

sql 复制代码
postgres=> alter table orders enable trigger update_customer_stats_trigger;
ALTER TABLE
  • 新增客户
shell 复制代码
postgres=> INSERT INTO orders (customer_id, total_amount, status) VALUES (4, 100, 'pending'); 
INSERT 0 1
  • 中途又加了饮料
shell 复制代码
postgres=> update orders set total_amount =120 where customer_id =4;
UPDATE 1
  • 结帐
shell 复制代码
postgres=> UPDATE orders SET status = 'completed' WHERE customer_id = 4; 
UPDATE 1
  • 查看帐单
shell 复制代码
UPDATE 1
postgres=> select * from customer_stats where customer_id =4;
 customer_id | total_spent
-------------+-------------
           4 |         120
(1 row)

最后帐单查询,可以看到消费总计为120。

总结


通过对触发器的启用和禁用,来精确管理触发器的使用,让触发器的定义一直保持在系统当中。

结尾


非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!

作者邮箱:study@senllang.onaliyun.com

如有错误或者疏漏欢迎指出,互相学习。

注:未经同意,不得转载!

相关推荐
cyt涛1 小时前
MyBatis 学习总结
数据库·sql·学习·mysql·mybatis·jdbc·lombok
Rookie也要加油1 小时前
01_SQLite
数据库·sqlite
liuxin334455661 小时前
教育技术革新:SpringBoot在线教育系统开发
数据库·spring boot·后端
看山还是山,看水还是。2 小时前
MySQL 管理
数据库·笔记·mysql·adb
fishmemory7sec2 小时前
Koa2项目实战2(路由管理、项目结构优化)
数据库·mongodb·koa
momo小菜pa2 小时前
【MySQL 09】表的内外连接
数据库·mysql
Jasonakeke3 小时前
【重学 MySQL】四十九、阿里 MySQL 命名规范及 MySQL8 DDL 的原子化
数据库·mysql
程序猿小D3 小时前
第二百六十九节 JPA教程 - JPA查询OrderBy两个属性示例
java·开发语言·数据库·windows·jpa
小宇成长录3 小时前
Mysql:数据库和表增删查改基本语句
数据库·mysql·数据库备份
团儿.4 小时前
解锁MySQL高可用新境界:深入探索MHA架构的无限魅力与实战部署
数据库·mysql·架构·mysql之mha架构