Loading

pgsql之触发器与触发器函数

迫于学业压力,不得不使用pgsql。其复杂度远超mysql,不仅让我回味其中,久久不能自拔/wx

首先,咱找到pgsql 12.2的中文官方说明文档,打之看了一下,额,还是算了。

太复杂了,由于触发器后必须执行函数或者存储过程,所以触发器条目和函数条目关系比较密切,经常会相互跳转和引用,跳着跳着就不知道自己都看了些啥,抬起头叹口气,就只看的到顶层密密麻麻的tabs了。

再快一点!

终于,在同学的帮助下,我得知了创建触发器的一般格式:

create trigger trigger_name [before/after/instead of] [update | insert | delete] on table_name
for each [row | statement]
execute [function | procedure] function_name;

与之配套的是触发器函数

在pgsql中,可以定义一种叫做触发器函数的函数,故名思意,专门用在触发器响应后执行,其一般定义如下:

create or replace function function_name() returns trigger  -- 返回一个触发器
language 'plpgsql'
AS $$
BEGIN
    ...
END;
$$

更方便的是,可以直接根据触发器的相应操作(delete、insert、update)等来直接引用NEW和OLD这两张表,这两张表(也或者是表项)的意义以后有时间来补上

另外,我从mysql必知必会中看到了一些关于操作与可引用表之间的关系,如下:

INSERT触发器

  • 可以引用一个名为NEW的虚拟表,访问那些被插入的行
  • 即使使用BEFORE INSERTNEW表中的值也可以被修改
  • 对于那些会自动生成值的插入(比如插入一个订单,自动增序为其分配一个序号),在BEFORE时NEW.num将会永远是0,因此这种情况要使用AFTER来获取正确的序号

DELETE触发器

  • 可以引用一个名为OLD的虚拟表,访问那些被删除的行
  • OLD中的值是只读的,无法写

UPDATE触发器

  • 可以引用一个名为OLD的虚拟表,访问那些被更新之前的行
  • 可以引用一个名为NEW的虚拟表,访问那些被更新之后的行
  • BEFORE UPDATE允许更新NEW中的值
  • OLD只读

那么,开始!

CREATE or replace function addLog() returns trigger
language 'plpgsql'
AS $$
BEGIN
    insert into departments_copy_log(login_name, update_date, dept_no, dept_name_old, dept_name_new)  -- session_user是登录pgsql账户的用户名
    values (session_user, now(), new.dept_no, old.dept_name, new.dept_name);  -- 直接引用new和old,这里代表的应该是有变更的表项
    return new;  -- 这里得返回点什么,否则会报函数没有返回的错误。。。具体原因以后补上
END;

create trigger log_department_change after update on departments_copy
for each row
execute procedure addLog();  -- 这里试过function,也行,好像pgsql不太区分存储过程和函数
$$

这儿有一篇更详细的触发器文章点我

posted @ 2021-06-01 22:32  槐下  阅读(1737)  评论(0编辑  收藏  举报