PostgreSQL数据库日常学习笔记16-触发器函数


声明:本文转载自https://my.oschina.net/u/1011130/blog/1559851,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

PostgreSQL触发器是一组动作或数据库回调函数,用于表或视图等执行指定数据库事件,即INSERT,UPDATE,DELETE或TRUNCAT等语句时自动运行。 触发器用于验证输入数据,执行业务规则,保持审计跟踪等。

触发器函数返回类型是trigger, 如果需要给触发器函数传入参数, 需要定义到触发器函数外部参数列表, 需要通过其他方式传入。.

触发器语法示例如下:

CREATE [ CONSTRAINT ] TRIGGER name { BEFORE | AFTER | INSTEAD OF } { event [ OR ... ] }     ON table_name     [ FROM referenced_table_name ]     [ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ]     [ REFERENCING { { OLD | NEW } TABLE [ AS ] transition_relation_name } [ ... ] ]     [ FOR [ EACH ] { ROW | STATEMENT } ]     [ WHEN ( condition ) ]     EXECUTE PROCEDURE function_name ( arguments )  where event can be one of:      INSERT     UPDATE [ OF column_name [, ... ] ]     DELETE     TRUNCATE 

创建测试学生表student 和分数表score 。

CREATE TABLE student (  		studentno INT PRIMARY KEY , 		studentname TEXT , 		studentbirthday DATE DEFAULT CURRENT_DATE ); CREATE TABLE score (  		studentno INT , 		chinaesescore INT , 		mathscore INT , 		testdate DATE  ); 

我们希望删除学生表时,能够同时删除该学生考试成绩,触发器可以实现实现类似功能。

插入测试数据。

---测试数据 INSERT INTO student VALUES(1,'王小虎'),(2,'李逍遥'),(3,'景天'),(4,'云天河'); INSERT INTO score VALUES (1,92,87,'2017-1-18'),(1,90,83,'2017-7-14'),(2,69,74,'2017-1-18'),(2,75,83,'2017-7-14'),(3,92,87,'2017-1-18'),(3,92,87,'2017-7-14'); 

执行查询操作。

---查询student表 test=# select studentno,studentname,studentbirthday from student;  studentno | studentname | studentbirthday -----------+-------------+-----------------          1 | 王小虎      | 2017-11-02          2 | 李逍遥      | 2017-11-02          3 | 景天        | 2017-11-02          4 | 云天河      | 2017-11-02 (4 行记录)  ---查询score表 test=#  test=# select studentno,chinaesescore,mathscore,testdate from score;  studentno | chinaesescore | mathscore |  testdate -----------+---------------+-----------+------------          1 |            92 |        87 | 2017-01-18          1 |            90 |        83 | 2017-07-14          2 |            69 |        74 | 2017-01-18          2 |            75 |        83 | 2017-07-14          3 |            92 |        87 | 2017-01-18          3 |            92 |        87 | 2017-07-14 (6 行记录)   test=# 

创建触发器前,需要定义触发器函数,函数带任何参数,返回值的类型必须是trigger。触发器函数定义完成后,可以用命令CREATE TRIGGER创建触发器。多个触发器可以使用一个触发器函数。

下面演示创建触发器执行函数。

CREATE OR REPLACE FUNCTION deletestudentafterscore() RETURNS TRIGGER AS $$ BEGIN  DELETE FROM score WHERE studentno =OLD.studentno; RETURN OLD; END; $$ LANGUAGE plpgsql; 

创建触发器。

CREATE TRIGGER deletestudent AFTER DELETE ON student FOR EACH ROW EXECUTE PROCEDURE deletestudentandscore();  

删除学号为3学生。

---删除景天 test=# delete from student where studentno=3; #DELETE 1 

再次执行查询语句。

test=# select studentno,studentname,studentbirthday from student;  studentno | studentname | studentbirthday -----------+-------------+-----------------          1 | 王小虎      | 2017-11-02          2 | 李逍遥      | 2017-11-02          4 | 云天河      | 2017-11-02 (3 行记录)   test=# select studentno,chinaesescore,mathscore,testdate from score;  studentno | chinaesescore | mathscore |  testdate -----------+---------------+-----------+------------          1 |            92 |        87 | 2017-01-18          1 |            90 |        83 | 2017-07-14          2 |            69 |        74 | 2017-01-18          2 |            75 |        83 | 2017-07-14 (4 行记录)   test=#  ---删除李逍遥 test=# delete from student where studentno=2; #DELETE 1 test=# select studentno,studentname,studentbirthday from student;  studentno | studentname | studentbirthday -----------+-------------+-----------------          1 | 王小虎      | 2017-11-02          4 | 云天河      | 2017-11-02 (2 行记录)   test=# select studentno,chinaesescore,mathscore,testdate from score;  studentno | chinaesescore | mathscore |  testdate -----------+---------------+-----------+------------          1 |            92 |        87 | 2017-01-18          1 |            90 |        83 | 2017-07-14 (2 行记录)   test=# 

PostgreSQL支持两种触发器,一种是数据行级触发器,另外一种是语句级触发器,修改0行数据也会导致触发匹配触发器,一次性更新多条数据触发器也只会被触发一次。对于数据行级触发器,触发触发器语句在每操作一个数据行,就会被执行一次。语句级触发器只会被执行一次,即具有一次性。

补全已删除数据。

test=# INSERT INTO student VALUES(2,'王小虎'),(3,'景天'); INSERT 0 2 test=# INSERT INTO score VALUES (2,69,74,'2017-1-18'),(2,75,83,'2017-7-14'),(3,92,87,'2017-1-18'),(3,92,87,'2017-7-14'); INSERT 0 4  ---根据学生编号排序 test=# select studentno,studentname,studentbirthday from student order by studen tno;  studentno | studentname | studentbirthday -----------+-------------+-----------------          1 | 王小虎      | 2017-11-02          2 | 王小虎      | 2017-11-02          3 | 景天        | 2017-11-02          4 | 云天河      | 2017-11-02 (4 行记录)   test=# select studentno,chinaesescore,mathscore,testdate from score;  studentno | chinaesescore | mathscore |  testdate -----------+---------------+-----------+------------          1 |            92 |        87 | 2017-01-18          1 |            90 |        83 | 2017-07-14          2 |            69 |        74 | 2017-01-18          2 |            75 |        83 | 2017-07-14          3 |            92 |        87 | 2017-01-18          3 |            92 |        87 | 2017-07-14 (6 行记录)   test=#  

当PL / pgSQL函数被调用为触发器时,会在顶级块中自动创建若干特殊变量。分别是NEW、OLD、TG_NAME、TG_WHEN、TG_LEVEL、TG_OP、TG_RELID、TG_RELNAME、TG_TABLE_NAME、TG_TABLE_SCHEMA、TG_NARGS、TG_ARGV[]等。上文中触发器函数deletestudentafterscore已经练习使用过OLD变量。

一个表或视图上可以创建多个触发器, 调用顺序和触发器类型有关.如果存在多个同类触发器, 调用顺序则和触发器名称有关, 按照名字英文排序调用(a-z)。

一个触发器函数可以多次被触发器调用。

参考链接

http://blog.csdn.net/neo_liu0000/article/details/6255623

https://www.postgresql.org/docs/10/static/sql-createtrigger.html

https://www.postgresql.org/docs/current/static/plpgsql-trigger.html#plpgsql-trigger-example

参考书籍

postgresql修炼之道 从小工到专家 P173-P186

本文发表于2017年11月03日 06:34
(c)注:本文转载自https://my.oschina.net/u/1011130/blog/1559851,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2437 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1