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 条件表达式(返回
INSTEAD
INSTEAD
指示应而不是原始命令被执行。
ALSO
ALSO
表示除原始命令外还应执行命令。
如果既未指定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 语言扩展,整个查询重写系统也是如此。