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 INSERT
,NEW
表中的值也可以被修改 - 对于那些会自动生成值的插入(比如插入一个订单,自动增序为其分配一个序号),在
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不太区分存储过程和函数
$$
这儿有一篇更详细的触发器文章点我