Skip to content

定义

触发器是由事件自动触发执行的一种特殊的存储过程,触发事件可以是对一个表进行insert、update、delete等操作;触发器常用于加强数据的完整性约束和业务规则上的约束

创建触发器

步骤:

  1. 先为触发器建一个执行函数,此函数返回类型为触发器类型
  2. 然后建一个触发器
sql

# 学生表
create table student (
  student_no int primary key,
  student_name varchar(40),
  age int
);
# 成绩表
create table score (
  student_no int,
  chinense_score int,
  math_score int,
  test_date date
);

# 触发器:在删除学生表中学生的同时,删除其在成绩表中的成绩
create or replace function student_delete_trigger()  -- 创建 - 如果有同名的覆盖
returns trigger                                      -- 返回trigger类型
as $$                                                -- 开始函数体界定符
begin                                                -- 实际函数逻辑 开始
  delete from score where student_no = OLD.student_no; -- OLD是一个特殊变量,用于引用触发操作前的数据行
  return OLD;                                        -- 函数内部必须返回OLD/NEW记录或NULL
end;                                                 -- 实际函数逻辑 结束
$$                                                   -- 结束函数体界定符
language plpgsql;                                    -- 实现预言

# 创建触发器
create trigger delete_student_trigger
  after delete on student
  for each row execute procedure student_delete_trigger ();

语句级触发器和行级触发器

  • 语句级触发器:执行每个SQL语句时只执行一次
    ⚠️:总是返回null
  • 行级触发器:执行每行SQL语句都会执行一次
    ⚠️:before:返回null表示忽略对当前行的操作,如果返回非null行,对于insert和update操作来说,返回的行将成为被插入的行或者是将要更新的行
    ⚠️:after:忽略返回值

下面代码是语句级触发器,举个例子:insert into student values (1, '张三', 14), (2, '李四', 14);
一个语句,虽然插入2行,但只在log中记录一次

sql

# 对student表更新情况记录log  
create table log_student (
  update_time timestamp,   -- 操作时间
  db_user varchar(40),     -- 操作的数据库用户名
  opr_type varchar(6)      -- 操作类型:insert、delete、update
);

# 记录log的触发器函数
create function log_student_trigger ()
returns trigger as
$$
begin 
  insert into log_student values(now(), user, TG_OP);
  return null;
end;
$$
language "plpgsql";

# 在student表上创建语句级触发器
create trigger log_student_trigger
  after insert or delete or update on student
  for statement execute procedure log_student_trigger();

# 创建行级触发器
create trigger log_sstudent_trigger2
  after insert or delete or update on student
  for row execute procedure log_student_trigger();

before触发器和after触发器

sql

# 触发器函数
create function student_use_new_name_trigger()
returns trigger as
$$
begin
  NEW.student_name = NEW.student_name || NEW.student_no;   -- NEW表示‌即将被插入或更新‌的新数据行,||是字符串连接符号
  return NEW;
end;
$$
language 'plpgsql';

删除触发器

删除触发器,触发器的函数不会被删除。
删除表,表上的触发器也会被删除

sql

drop trigger user_new_name_student_trigger on student;

特殊变量

  • NEW
  • OLD
  • TG_NAME
  • TG_WHEN
  • TG_LEVEL .........

事件触发器

就是DDL(数据库定义)触发器(只有超级用户才能创建和修改事件触发器)
返回event_trigger

sql

# 触发器的函数
create or replace function abort_any_command()
  returns event_trigger as
  $$
  begin
    raise exception 'command % is disabled', tg_tag;
  end;
  $$
  language 'plpgsql';

# 事件触发器
create event trigger abort_ddl on ddl_command_start
  execute procedure abort_any_command();