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

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

触发器函数返回类型是trigger, 若是须要给触发器函数传入参数, 须要定义到触发器函数外部参数列表, 须要经过其余方式传入。.sql

触发器语法示例以下:数据库

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

咱们但愿删除学生表时,可以同时删除该学生考试成绩,触发器能够实现实现相似功能。post

插入测试数据。测试

---测试数据
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');

执行查询操做。.net

---查询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建立触发器。多个触发器可使用一个触发器函数。postgresql

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

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

建立触发器。htm

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

相关文章
相关标签/搜索