【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

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

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

相关推荐
混乱意志2 小时前
dgraph example数据导入
数据库·后端
Web极客码2 小时前
WordPress 站点漏洞利用:数据库恶意注入与多重感染的案例分析
数据库·wordpress·网站安全·数据库注入·wordpress漏洞·wordpress安全插件
刺客xs2 小时前
MySQL数据库----DML语句
数据库·mysql
嘉讯科技HIS系统2 小时前
嘉讯科技:医疗信息化、数字化、智能化三者之间的关系和区别
大数据·数据库·人工智能·科技·智慧医疗
爱上语文3 小时前
Redis基础(4):Set类型和SortedSet类型
java·数据库·redis·后端
lifallen3 小时前
Paimon vs. HBase:全链路开销对比
java·大数据·数据结构·数据库·算法·flink·hbase
Brookty4 小时前
【MySQL】JDBC编程
java·数据库·后端·学习·mysql·jdbc
先做个垃圾出来………5 小时前
SQL的底层逻辑解析
数据库·sql
码不停蹄的玄黓5 小时前
深入拆解MySQL InnoDB可重复读(RR)隔离级别:MVCC+临键锁如何「锁」住一致性?
数据库·mysql·可重复读
paopaokaka_luck5 小时前
基于SpringBoot+Vue的酒类仓储管理系统
数据库·vue.js·spring boot·后端·小程序