Note

CREATE RULE

创建规则-定义新的重写规则

Synopsis

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

Description

CREATE RULE定义了应用于指定表或视图的新规则。 CREATE OR REPLACE RULE要么创建新规则,要么为同一表替换具有相同名称的现有规则。

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

当前,ON SELECT规则必须是无条件的INSTEAD规则,并且必须具有由单个SELECT命令组成的动作。因此,ON SELECT规则有效地将表转换为视图,其可见内容是规则的SELECT命令返回的行,而不是表中存储的内容(如果有的话)。与创建实际表并为其定义ON SELECT规则相比,写CREATE VIEW命令被认为是更好的样式。

您可以通过定义ON INSERTON UPDATEON DELETE规则(或足以满足您目的的子集)来创建可更新视图的错觉,以用其他表上的适当更新替换视图上的更新操作。如果要支持INSERT RETURNING等等,请确保在每个规则中放入合适的RETURNING子句。

如果您尝试使用条件规则进行复杂的视图更新,则有一个陷阱:*您必须允许在视图上执行的每个操作都必须有一个无条件的INSTEAD规则。如果规则是有条件的,或者不是INSTEAD,则系统仍将拒绝执行更新操作的尝试,因为它认为在某些情况下可能最终尝试对视图的虚拟表执行操作。如果要处理条件规则中的所有有用情况,请添加无条件DO INSTEAD NOTHING规则,以确保系统理解永远不会调用它来更新虚拟表。然后使条件规则为非INSTEAD;在应用它们的情况下,它们会添加到默认的INSTEAD NOTHING操作中。 (但是,该方法当前不适用于支持RETURNING查询.)

Note

足够简单以可自动更新的视图(请参见CREATE VIEW)不需要用户创建的规则即可更新。尽管您仍然可以创建显式规则,但是自动更新转换通常会胜过显式规则。

另一个值得考虑的替代方法是使用INSTEAD OF触发器(请参见CREATE TRIGGER)代替规则。

Parameters

  • name

    • 要创建的规则的名称。此名称必须与同一表的任何其他规则的名称不同。同一表和同一事件类型上的多个规则以字母名称 Sequences 应用。
  • event

    • 该事件是SELECTINSERTUPDATEDELETE之一。请注意,包含ON CONFLICT子句的INSERT不能用于具有INSERTUPDATE规则的表。考虑改用可更新的视图。
  • table_name

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

    • 任何 SQL 条件表达式(返回boolean)。条件表达式不能引用NEWOLD以外的任何表,并且不能包含聚合函数。
  • INSTEAD

    • INSTEAD指示应而不是原始命令被执行。
  • ALSO

    • ALSO表示除原始命令外还应执行命令。

如果既未指定ALSO也未指定INSTEAD,则默认值为ALSO

  • command

    • 组成规则操作的一个或多个命令。有效的命令是SELECTINSERTUPDATEDELETENOTIFY

在* condition command *中,特殊表名NEWOLD可用于引用引用表中的值。 NEWON INSERTON UPDATE规则中有效,以引用要插入或更新的新行。 OLDON UPDATEON DELETE规则中有效,以引用要更新或删除的现有行。

Notes

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

在视图上的INSERTUPDATEDELETE的规则中,您可以添加RETURNING子句以发出视图的列。如果规则分别由INSERT RETURNINGUPDATE RETURNINGDELETE RETURNING命令触发,则此子句将用于计算输出。当该规则由不带RETURNING的命令触发时,该规则的RETURNING子句将被忽略。当前的实现只允许无条件的INSTEAD规则包含RETURNING;此外,同一事件的所有规则中最多可以有一个RETURNING子句。 (这确保了只有一个候选RETURNING子句可用于计算结果.)如果任何可用规则中都没有RETURNING子句,则视图上的RETURNING查询将被拒绝。

注意避免循环规则非常重要。例如,尽管 PostgreSQL 接受以下两个规则定义中的每一个,但是SELECT命令将由于递归扩展规则而导致 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;

当前,如果规则动作包含NOTIFY命令,则将无条件执行NOTIFY命令,即即使没有规则应适用的任何行也将发出NOTIFY。例如,在:

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

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

无论是否有任何与条件id = 42匹配的行,都会在UPDATE期间发送一个NOTIFY事件。这是一个实施限制,可能会在将来的版本中修复。

Compatibility

CREATE RULE是 PostgreSQL 语言扩展,整个查询重写系统也是如此。

See Also

ALTER RULE, DROP RULE