On this page
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 INSERT,ON UPDATE和ON DELETE规则(或足以满足您目的的子集)来创建可更新视图的错觉,以用其他表上的适当更新替换视图上的更新操作。如果要支持INSERT RETURNING等等,请确保在每个规则中放入合适的RETURNING子句。
如果您尝试使用条件规则进行复杂的视图更新,则有一个陷阱:*您必须允许在视图上执行的每个操作都必须有一个无条件的INSTEAD规则。如果规则是有条件的,或者不是INSTEAD,则系统仍将拒绝执行更新操作的尝试,因为它认为在某些情况下可能最终尝试对视图的虚拟表执行操作。如果要处理条件规则中的所有有用情况,请添加无条件DO INSTEAD NOTHING规则,以确保系统理解永远不会调用它来更新虚拟表。然后使条件规则为非INSTEAD;在应用它们的情况下,它们会添加到默认的INSTEAD NOTHING操作中。 (但是,该方法当前不适用于支持RETURNING查询.)
Note
足够简单以可自动更新的视图(请参见CREATE VIEW)不需要用户创建的规则即可更新。尽管您仍然可以创建显式规则,但是自动更新转换通常会胜过显式规则。
另一个值得考虑的替代方法是使用INSTEAD OF触发器(请参见CREATE TRIGGER)代替规则。
Parameters
name- 要创建的规则的名称。此名称必须与同一表的任何其他规则的名称不同。同一表和同一事件类型上的多个规则以字母名称 Sequences 应用。
event- 该事件是
SELECT,INSERT,UPDATE或DELETE之一。请注意,包含ON CONFLICT子句的INSERT不能用于具有INSERT或UPDATE规则的表。考虑改用可更新的视图。
- 该事件是
table_name- 规则所适用的表或视图的名称(可选为模式限定)。
condition- 任何 SQL 条件表达式(返回
boolean)。条件表达式不能引用NEW和OLD以外的任何表,并且不能包含聚合函数。
- 任何 SQL 条件表达式(返回
INSTEADINSTEAD指示应而不是原始命令被执行。
ALSOALSO表示除原始命令外还应执行命令。
如果既未指定ALSO也未指定INSTEAD,则默认值为ALSO。
command- 组成规则操作的一个或多个命令。有效的命令是
SELECT,INSERT,UPDATE,DELETE或NOTIFY。
- 组成规则操作的一个或多个命令。有效的命令是
在* condition 和 command *中,特殊表名NEW和OLD可用于引用引用表中的值。 NEW在ON INSERT和ON UPDATE规则中有效,以引用要插入或更新的新行。 OLD在ON UPDATE和ON DELETE规则中有效,以引用要更新或删除的现有行。
Notes
您必须是表的所有者才能为其创建或更改规则。
在视图上的INSERT,UPDATE或DELETE的规则中,您可以添加RETURNING子句以发出视图的列。如果规则分别由INSERT RETURNING,UPDATE RETURNING或DELETE 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 语言扩展,整个查询重写系统也是如此。