# 创建规则

CREATE RULE — 定义一个新的重写规则

# 概要

CREATE [ OR REPLACE ] RULE name AS ON event
    TO table_name [ WHERE condition ]
    DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) }

where event can be one of:

    SELECT | INSERT | UPDATE | DELETE

# 描述

创建规则定义应用于指定表或视图的新规则。创建或替换规则将创建一个新规则,或替换同一个表的同名现有规则。

PostgreSQL 规则系统允许定义对数据库表中的插入、更新或删除执行的替代操作。粗略地说,当执行给定表上的给定命令时,规则会导致执行其他命令。或者,一个反而rule 可以用另一个命令替换给定的命令,或者导致命令根本不被执行。规则也用于实现 SQL 视图。重要的是要认识到规则实际上是一种命令转换机制或命令宏。转换发生在命令开始执行之前。如果您确实想要为每个物理行独立触发的操作,您可能想要使用触发器,而不是规则。有关规则系统的更多信息,请参见第 41 章.

目前,选择规则必须是无条件的反而规则并且必须具有由单个选择命令。因此,一个选择rule 有效地将表转换为视图,其可见内容是规则返回的行选择命令而不是存储在表中的任何内容(如果有的话)。写一个更好的风格创建视图命令而不是创建一个真实的表并定义一个选择规则。

您可以通过定义创建可更新视图的错觉插入,在更新, 和删除时规则(或足以满足您的目的的任何子集)将视图上的更新操作替换为其他表上的适当更新。如果你想支持插入返回等等,那么一定要放一个合适的返回条款中的每一个规则。

如果您尝试对复杂的视图更新使用条件规则,则会遇到一个问题:必须做一个无条件的反而您希望在视图上允许的每个操作的规则。如果规则是有条件的,或者不是反而,那么系统仍然会拒绝执行更新操作的尝试,因为它认为在某些情况下它可能最终会尝试对视图的虚拟表执行操作。如果要处理条件规则中的所有有用情况,请添加无条件什么都不做规则以确保系统理解它永远不会被调用来更新虚拟表。然后使条件规则非反而;在应用它们的情况下,它们会添加到默认值取而代之行动。(此方法目前不支持返回但是查询。)

# 笔记

一个简单到可以自动更新的视图(参见创建视图) 不需要用户创建的规则即可更新。虽然您无论如何都可以创建显式规则,但自动更新转换通常会优于显式规则。

另一个值得考虑的替代方法是使用代替触发器(见创建触发器) 代替规则。

# 参数

姓名

要创建的规则的名称。这必须与同一表的任何其他规则的名称不同。同一表和同一事件类型上的多个规则按字母名称顺序应用。

事件

该活动是其中之一选择,插入,更新, 要么删除.请注意,一个插入包含一个关于冲突子句不能用于具有插入要么更新规则。考虑改用可更新的视图。

表名

规则适用的表或视图的名称(可选模式限定)。

健康)状况

任何 SQL 条件表达式(返回布尔值)。条件表达式不能引用任何表,除了新的老的, 并且不能包含聚合函数。

反而

反而表示应该执行的命令代替原来的命令。

表示应该执行的命令此外原来的命令。

如果两者都没有也不反而被指定,是默认值。

命令

构成规则操作的一个或多个命令。有效的命令是选择,插入, 更新, 删除, 或者通知.

之内*(健康)状况命令*, 特殊表名新的老的可用于引用引用表中的值。新的有效于插入在更新规则来引用正在插入或更新的新行。老的有效于在更新删除时引用正在更新或删除的现有行的规则。

# 笔记

您必须是表的所有者才能为其创建或更改规则。

在一项规则中插入,更新, 或者删除在视图上,您​​可以添加一个返回发出视图列的子句。如果规则被触发,则该子句将用于计算输出插入返回,更新返回, 或者删除退货分别命令。当规则由不带的命令触发时返回, 规则返回子句将被忽略。当前的实现只允许无条件反而包含规则返回;此外,最多可以有一个返回子句在同一事件的所有规则中。(这确保只有一个候选人返回用于计算结果的子句。)返回如果没有,对视图的查询将被拒绝返回任何可用规则中的子句。

注意避免循环规则非常重要。例如,尽管 PostgreSQL 接受以下两个规则定义中的每一个,但选择由于规则的递归扩展,命令会导致 PostgreSQL 报告错误:

CREATE RULE "_RETURN" AS
    ON SELECT TO t1
    DO INSTEAD
        SELECT * FROM t2;

CREATE RULE "_RETURN" AS
    ON SELECT TO t2
    DO INSTEAD
        SELECT * FROM t1;

SELECT * FROM t1;

目前,如果一个规则动作包含一个通知指挥部通知命令将无条件执行,即通知即使没有任何应适用该规则的行,也会发出。例如,在:

CREATE RULE notify_me AS ON UPDATE TO mytable DO ALSO NOTIFY mytable;

UPDATE mytable SET name = 'foo' WHERE id = 42;

通知事件将在期间发送更新, 是否有符合条件的行编号 = 42.这是一个实现限制,可能会在未来的版本中修复。

# 兼容性

创建规则是 PostgreSQL 语言扩展,整个查询重写系统也是如此。

# 也可以看看

改变规则,删除规则