Skip to content
Database

Postgres 触发器

Automatically execute SQL on table events.

在 Postgres 中,触发器会在表的事件上(比如 INSERT、UPDATE、DELETE 或 TRUNCATE 操作)自动执行一系列动作。

🌐 In Postgres, a trigger executes a set of actions automatically on table events such as INSERTs, UPDATEs, DELETEs, or TRUNCATE operations.

创建触发器 #

🌐 Creating a trigger

创建触发器涉及两部分:

🌐 Creating triggers involve 2 parts:

  1. 一个 函数,会被执行(称为触发函数)
  2. 实际的 Trigger 对象,包含触发器应何时运行的相关参数。

一个触发器的例子是:

🌐 An example of a trigger is:

1
create trigger "trigger_name"
2
after insert on "table_name"
3
for each row
4
execute function trigger_function();

触发器函数 #

🌐 Trigger functions

触发器函数是一个用户定义的 函数,当触发器被触发时,Postgres 会执行它。

🌐 A trigger function is a user-defined Function that Postgres executes when the trigger is fired.

示例触发函数 #

🌐 Example trigger function

这是一个例子,每当员工的薪水更新时,它都会更新 salary_log

🌐 Here is an example that updates salary_log whenever an employee's salary is updated:

1
-- Example: Update salary_log when salary is updated
2
create function update_salary_log()
3
returns trigger
4
language plpgsql
5
as $$
6
begin
7
insert into salary_log(employee_id, old_salary, new_salary)
8
values (new.id, old.salary, new.salary);
9
return new;
10
end;
11
$$;
12
13
create trigger salary_update_trigger
14
after update on employees
15
for each row
16
execute function update_salary_log();

触发变量 #

🌐 Trigger variables

触发器函数可以访问几个特殊变量,这些变量提供触发事件的上下文信息以及正在修改的数据。在上面的例子中,你可以看到插入到工资记录中的值是 old.salarynew.salary —— 在这种情况下,old 表示之前的值,new 表示更新后的值。

🌐 Trigger functions have access to several special variables that provide information about the context of the trigger event and the data being modified. In the example above you can see the values inserted into the salary log are old.salary and new.salary - in this case old specifies the previous values and new specifies the updated values.

这里是触发函数中可用的一些关键变量和选项:

🌐 Here are some of the key variables and options available within trigger functions:

  • TG_NAME:被触发的触发器名称。
  • TG_WHEN:触发事件(BEFOREAFTER)的时间。
  • TG_OP:触发事件的操作(INSERTUPDATEDELETETRUNCATE)。
  • OLD:一个记录变量保存了 UPDATEDELETE 触发器中旧行的数据。
  • NEW:一个记录变量保存了新行在 UPDATEINSERT 的数据,并触发了。
  • TG_LEVEL:触发器级别(ROWSTATEMENT),表示触发器是行级还是语句级。
  • TG_RELID:触发器被触发时表的对象ID。
  • TG_TABLE_NAME:触发器被触发的表的名称。
  • TG_TABLE_SCHEMA:触发器被触发的表的模式。
  • TG_ARGV:创建触发器时提供的一组字符串参数。
  • TG_NARGSTG_ARGV 数组中的参数数量。

触发类型 #

🌐 Types of triggers

有两种触发器,BEFOREAFTER

🌐 There are two types of trigger, BEFORE and AFTER:

在进行更改之前触发 #

🌐 Trigger before changes are made

在触发事件之前执行。

🌐 Executes before the triggering event.

1
create trigger before_insert_trigger
2
before insert on orders
3
for each row
4
execute function before_insert_function();

在更改后触发 #

🌐 Trigger after changes are made

在触发事件后执行。

🌐 Executes after the triggering event.

1
create trigger after_delete_trigger
2
after delete on customers
3
for each row
4
execute function after_delete_function();

执行频率 #

🌐 Execution frequency

执行触发器有两个可选方式:

🌐 There are two options available for executing triggers:

  • for each row:指定触发函数应该对每一行受影响的记录执行一次。
  • for each statement:这个触发器在整个操作中只执行一次(例如,插入时只执行一次)。在处理单条 SQL 语句影响的多行数据时,这可能比 for each row 更高效,因为它允许你一次对一组行进行计算或更新。

扣动扳机 #

🌐 Dropping a trigger

你可以使用 drop trigger 命令删除触发器:

🌐 You can delete a trigger using the drop trigger command:

1
drop trigger "trigger_name" on "table_name";

如果你的触发器在受限制的模式内,你将无法删除它,因为权限受限。在这种情况下,你可以改为删除它依赖的函数,使用 CASCADE 子句自动移除所有调用该函数的触发器:

🌐 If your trigger is inside a restricted schema, you won't be able to drop it due to permission restrictions. In those cases, you can drop the function it depends on instead using the CASCADE clause to automatically remove all triggers that call it:

1
drop function if exists restricted_schema.function_name() cascade;

在删除函数之前,确保先备份一下,以防你以后打算重新创建它。

🌐 Make sure you take a backup of the function before removing it in case you're planning to recreate it later.

资源 #

🌐 Resources