pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
PL/pgSQL 可用于定义触发器过程。触发器 过程用 CREATE FUNCTION 命令创建,声明为无参数、返回 类型为 trigger 的函数。注意,即使函数期望接收 CREATE TRIGGER 中指定的参数,也必须声明为无参数—— 触发器参数通过 TG_ARGV 传递,如下所述。
当 PL/pgSQL 函数作为触发器被调用时,顶层 块中会自动创建若干特殊变量。它们是:
NEW数据类型 RECORD;在行级触发器中保存 INSERT/UPDATE 操作的新数据库行的变量。此 变量在语句级触发器中为空。
OLD数据类型 RECORD;在行级触发器中保存 UPDATE/DELETE 操作的旧数据库行的变量。此 变量在语句级触发器中为空。
TG_NAME数据类型 name;包含实际触发的触发器名称的变量。
TG_WHEN数据类型 text;依据触发器定义为 BEFORE 或 AFTER 的字符串。
TG_LEVEL数据类型 text;依据触发器定义为 ROW 或 STATEMENT 的字符串。
TG_OP数据类型 text;取值为 INSERT、 UPDATE 或 DELETE 的字符串, 说明触发器是针对哪个操作触发的。
TG_RELID数据类型 oid;导致触发器调用的表的对象 ID。
TG_RELNAME数据类型 name;导致触发器调用的表的名称。
TG_NARGS数据类型 integer;CREATE TRIGGER 语句中给触发器过程的参数个数。
TG_ARGV[]数据类型为 text 的数组;来自 CREATE TRIGGER 语句的参数。索引从 0 计数。 无效索引(小于 0 或大于等于 tg_nargs)得到空值。
触发器函数必须返回空值,或返回与触发该触发器的表的结构完全相同的 记录/行值。
BEFORE 行级触发器可以返回空值,向触发器管理器示意跳过 这一行的其余操作(即不触发后续触发器,并且不对这一行执行 INSERT/UPDATE/DELETE)。如果返回 非空值,操作将以该行值继续进行。返回与 NEW 原值不同的 行值会改变将被插入或更新的行(但在 DELETE 情况下没有 直接效果)。要更改将被存储的行,可以直接替换 NEW 中的 单个值并返回修改后的 NEW,也可以构造一个完整的新记录/ 行来返回。
BEFORE 或 AFTER 语句级触发器以及 AFTER 行级触发器的返回值总是被忽略;不妨返回空值。但 这些类型的触发器中的任何一种都仍可以通过引发错误中止整个操作。
例 37.1 展示了一个用 PL/pgSQL 编写的触发器过程的例子。
例 37.1. 一个 PL/pgSQL 触发器过程
这个示例触发器确保每当表中有行被插入或更新时,当前用户名和时间都被 记入该行。它还检查给出了雇员姓名,并且薪金为正值。
CREATE TABLE emp (
empname text,
salary integer,
last_date timestamp,
last_user text
);
CREATE FUNCTION emp_stamp() RETURNS trigger AS '
BEGIN
-- Check that empname and salary are given
IF NEW.empname IS NULL THEN
RAISE EXCEPTION ''empname cannot be null'';
END IF;
IF NEW.salary IS NULL THEN
RAISE EXCEPTION ''% cannot have null salary'', NEW.empname;
END IF;
-- Who works for us when she must pay for it?
IF NEW.salary < 0 THEN
RAISE EXCEPTION ''% cannot have a negative salary'', NEW.empname;
END IF;
-- Remember who changed the payroll when
NEW.last_date := ''now'';
NEW.last_user := current_user;
RETURN NEW;
END;
' LANGUAGE plpgsql;
CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
FOR EACH ROW EXECUTE PROCEDURE emp_stamp();
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。