pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
CREATE RULE — 定义一条新规则
CREATE RULEnameAS ONeventTOobject[ WHEREcondition] DO [ INSTEAD ]actionwhereactioncan be: NOTHING |query| (query;query... ) | [query;query... ]
name要创建的规则的名称。
event事件是 SELECT、UPDATE、DELETE 或 INSERT 之一。
objectObject 是 table 或 table.column。(目前,实际上只实现了 table 形式。)
condition任意的 SQL 布尔条件表达式。条件表达式不能引用 new 和 old 之外的任何表。
query组成 action 的一个或多个查询可以是任何 SQL 的 SELECT、INSERT、UPDATE、DELETE 或 NOTIFY 语句。
在 condition 和 action 中,可以使用特殊表名 new 和 old 来引用被引用表(即 object)中的值。new 在 ON INSERT 和 ON UPDATE 规则中有效,用于引用正在被插入或更新的新行。old 在 ON SELECT、ON UPDATE 和 ON DELETE 规则中有效,用于引用正在被选择、更新或删除的现有行。
CREATE规则成功创建时返回的消息。
Postgres 的规则系统允许定义在对数据库表进行插入、更新或删除时所执行的替代动作。规则也用于实现表视图。
一条规则的语义是:当单个实例(行)被访问、插入、更新或删除时,会有一个旧实例(对于选择、更新和删除)和一个新实例(对于插入和更新)。给定事件类型和给定目标对象(表)的所有规则会被检查,顺序不确定。如果 WHERE 子句中指定的 condition(如果有)为真,该规则的 action 部分就会被执行。如果指定了 INSTEAD,action 会替代原始查询执行;否则,它在原始查询执行之前完成。在 condition 和 action 两部分中,旧实例和/或新实例中字段的值会替换到 old.attribute-name 和 new.attribute-name 上。
规则的 action 部分可以由一个或多个查询组成。要编写多个查询,需用圆括号或方括号包围它们。这些查询会按指定的顺序执行(而对于一个对象上多条规则的执行顺序则没有任何保证)。action 也可以是 NOTHING,表示没有任何动作。因此,一条 DO INSTEAD NOTHING 规则会阻止原始查询的执行(当其条件为真时);而一条 DO NOTHING 规则没有任何用处。
规则的 action 部分与触发激活它的用户命令使用相同的命令标识符和事务标识符执行。
目前,ON SELECT 规则必须是无条件的 INSTEAD 规则,并且其动作必须由单个 SELECT 查询组成。因此,一条 ON SELECT 规则实际上会把对象表变为视图,其可见内容是该规则的 SELECT 查询返回的行,而不是表中原来存储的内容(如果有)。直接编写 CREATE VIEW 命令被认为比创建表并为其定义 ON SELECT 规则的风格更好。
要在一个表上定义规则,你必须拥有该表的规则定义权限。使用 GRANT 和 REVOKE 来更改权限。
避免循环规则非常重要。例如,尽管下面两条规则定义中的每一条都被 Postgres 接受,但 select 命令会导致 Postgres 报告错误,因为查询循环了太多次:
例 1. 循环重写规则组合的例子:
CREATE RULE bad_rule_combination_1 AS
ON SELECT TO emp
DO INSTEAD
SELECT * FROM toyemp;
CREATE RULE bad_rule_combination_2 AS
ON SELECT TO toyemp
DO INSTEAD
SELECT * FROM emp;
这个从 EMP 中选择的尝试会导致 Postgres 报错,因为这些查询循环了太多次:
SELECT * FROM emp;
CREATE RULE 语句是 Postgres 的语言扩展。SQL92 中没有 CREATE RULE 语句。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。