ToB企服应用市场:ToB评测及商务社交产业平台

标题: 【postgresql初级使用】触发器的创建删除,你不知道的触发器函数中的系统变 [打印本页]

作者: 王海鱼    时间: 2024-6-15 01:22
标题: 【postgresql初级使用】触发器的创建删除,你不知道的触发器函数中的系统变
使用触发器

   ​专栏内容
  
    个人主页:我的主页
管理社区:开源数据库
座右铭:天行健,君子以自强不息;阵势坤,君子以厚德载物.
  
  
概述


前一节介绍了触发器的原理,以及在postgresql中支持的触发器的类型,有基于行的触发器,也有基于SQL语句的触发器,同时触发的位置可以是实行前,也可以是实行后。
从本节开始介绍触发器的创建,使用,通过案例看看它们的什么样的区别。
创建触发器


触发器的创建语法如下:
  1. CREATE TRIGGER trigger_name
  2.    {BEFORE | AFTER}
  3.    ON table_name
  4.    [FOR [EACH] { ROW | STATEMENT }]
  5.        EXECUTE { FUNCTION | PROCEDURE } trigger_function;
复制代码
语法阐明

触发器函数

触发器的内容包罗一个自定义的函数,所以首先得有一个实行动作的函数。
先来定义一个函数,假如触发就打印一条信息。
  1. CREATE FUNCTION tri_fun()
  2.    RETURNS TRIGGER
  3.    LANGUAGE PLPGSQL
  4. AS $$
  5. BEGIN
  6.    -- trigger logic
  7.    raise notice 'trigger excute';
  8. END;
  9. $$
复制代码

在系统调用触发器函数时,会传入默认的参数,参数类型为TriggerData, 它的定义如下:
  1. typedef struct TriggerData
  2. {
  3. NodeTag type;
  4. TriggerEvent tg_event;
  5. Relation tg_relation;
  6. HeapTuple tg_trigtuple;
  7. HeapTuple tg_newtuple;
  8. Trigger *tg_trigger;
  9. TupleTableSlot *tg_trigslot;
  10. TupleTableSlot *tg_newslot;
  11. Tuplestorestate *tg_oldtable;
  12. Tuplestorestate *tg_newtable;
  13. const Bitmapset *tg_updatedcols;
  14. } TriggerData;
复制代码
假如使用C语言或其它编程语言时,就可以直接访问此布局,假如使用plpgsql时,默认也定义了一组系统变量。
这些是您在 PostgreSQL 的行级触发器(row-level triggers)中可以访问的特殊变量。它们提供了关于触发器的元信息和触发触发器的事件的上下文。以下是这些变量的详细解释:
这些特殊变量在编写 PostgreSQL 触发器时非常有效,由于它们提供了关于触发器和触发触发器的事件的上下文信息。
删除触发器


触发器删除就比力简朴了,语法如下:
  1. DROP TRIGGER trigger_name
  2. ON table_name
  3. [ CASCADE | RESTRICT ];
复制代码
语法阐明

案例分析


下面来通过一个案例,看看触发器的效果。
数据准备

先来建一张表emp, 然后通过触发器查抄数据的同等性,并且将插入数据的日期和用户名进行记录。
  1. CREATE TABLE emp (
  2.   empname text,
  3.   salary integer,
  4.   last_date timestamp,
  5.   last_user text
  6. );
复制代码
动作函数

使用plpgsql语言编写实行函数。
  1. CREATE FUNCTION emp_stamp()
  2. RETURNS trigger AS $emp_stamp$
  3. BEGIN
  4.         -- Check that empname and salary are given
  5.         IF NEW.empname IS NULL THEN
  6.                 RAISE EXCEPTION 'empname cannot be null';
  7.         END IF;
  8.        
  9.         IF NEW.salary IS NULL THEN
  10.                 RAISE EXCEPTION '% cannot have null salary',
  11.                 NEW.empname;
  12.         END IF;
  13.        
  14.         -- Who works for us when they must pay for it?
  15.         IF NEW.salary < 0 THEN
  16.                 RAISE EXCEPTION '% cannot have a negative salary',
  17.                 NEW.empname;
  18.         END IF;
  19.        
  20.         -- Remember who changed the payroll when
  21.         NEW.last_date := current_timestamp;
  22.         NEW.last_user := current_user;
  23.         RETURN NEW;
  24. END;
  25. $emp_stamp$ LANGUAGE plpgsql;
复制代码
这里使用了new系统参数值,它们分别代表插入前的新值,这里可以改变它的内容。
增加触发器

创建一个before触发器,在数据真正修改前做校验,并修改其中的内容,在insert和update动作进行触发。
  1. CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
  2. FOR EACH ROW EXECUTE FUNCTION emp_stamp();
复制代码
这是一个行级触发器,每一行数据的插入和更新都会触发。
触发结果

自动赋值
这里只须要插入前两个字段就可以,后两个字段会被自动赋值。
  1. postgres=> insert into emp(empname,salary) values('alex',4000);
  2. INSERT 0 1
  3. postgres=> select * from emp;
  4. empname | salary |         last_date          | last_user
  5. ---------+--------+----------------------------+-----------
  6. alex    |   4000 | 2024-06-04 08:43:54.428469 | senllang
  7. (1 row)
复制代码
可以看到后两个字段被自动赋值,用户采用当前登陆的用户名。
同等性校验
假如插入的数据不符合计划要求,在触发器中进行查抄时会抛出异常;
  1. postgres=> insert into emp(empname,salary) values('white',-1);
  2. ERROR:  white cannot have a negative salary
  3. CONTEXT:  PL/pgSQL function emp_stamp() line 15 at RAISE
复制代码
触发器中抛出异常后,事件也就会被abort掉。
总结


本文重要分享了触发器的创建,删除,以及触发器函数定义和系统变量,触发器中的系统变量可以帮助我们获取触发器当前的环境信息。
适当的使用触发器可以将应用变得简朴,如今也盛行淘汰函数和存储过程,为了更好的移植性和维护性。
结尾


   非常感谢各人的支持,在浏览的同时别忘了留下您宝贵的批评,假如以为值得鼓励,请点赞,收藏,我会更加努力!
  作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。
注:未经同意,不得转载!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4