PostgreSQL 8.2.3 中文文档
后退快退快进前进

CREATE RULE

名称

CREATE RULE -- 定义一个新重写规则

语法

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

描述

CREATE RULE 定义一个适用于特定表或者视图的新规则。CREATE OR REPLACE RULE 要么是创建一个新规则,要么是替换一个表上的同名规则。

PostgreSQL 规则系统允许在更新、插入、删除时执行一个其它的预定义动作。简单的说,规则就是在指定表上执行指定动作的时候,将导致一些额外的动作被执行。另外,一个 INSTEAD 规则可以用另外一个命令取代特定的命令,或者令完全不执行该命令。规则还可以用于实现表视图。规则实际上只是一个命令转换机制,或者说命令宏。这种转换发生在命令开始执行之前。如果你想要针对每个物理行独立发生的操作,那么可能应该使用触发器而不是规则。有关规则的更多信息可以在章35找到。

目前,ON SELECT 规则必须是无条件的 INSTEAD 规则并且必须有一个由单独一条 SELECT 查询组成的动作。因此,一条 ON SELECT 规则有效地把表转成视图,它的可见内容是规则的 SELECT 查询返回的记录而不是存储在表中的内容。写一条 CREATE VIEW 命令比创建一个表然后在上面定义一条 ON SELECT 规则的风格要好。

你可以创建一个允许更新的视图的幻觉,方法是在视图上定义 ON INSERT, ON UPDATE, ON DELETE 规则(或者满足你需要的任何上述规则的子集),用合适的对其它表的更新替换在视图上更新的动作。如果打算支持 INSERT RETURNING 之类,就必须确保在规则的结尾放置恰当的 RETURNING 子句。

如果你想在视图更新上使用条件规则,那么这里就有一个补充:对你希望在视图上允许的每个动作,你都必须有一个无条件的 INSTEAD 规则。如果规则是有条件的或者它不是 INSTEAD ,那么系统仍将拒绝执行更新动作,因为它认为最终会在视图的虚拟表上执行这个动作。如果你想处理条件规则上的所有有用的情况,那只需要增加一个无条件的 DO INSTEAD NOTHING 规则确保系统明白它决不会被调用来更新虚拟表就可以了。然后把条件规则做成非 INSTEAD ;在这种情况下,如果它们被触发,那么它们就增加到缺省的 INSTEAD NOTHING 动作中。不过这种方法目前不支持 RETURNING 查询。

参数

name

创建的规则名。它必须在同一个表上的所有规则名字中唯一。同一个表上的同一个事件类型的规则是按照字母顺序运行的。

event

SELECT, INSERT, UPDATE, DELETE 事件之一

table

规则作用的表或者视图的名字(可以有模式修饰)

condition

任意返回 boolean 的 SQL 条件表达式。条件表达式除了引用 NEWOLD 之外不能引用任何表,并且不能有聚集函数。

INSTEAD

指示使用该命令代替最初的命令。

ALSO

该命令应该在最初的命令执行之后一起执行。

如果既没有声明 ALSO 也没有声明 INSTEAD ,那么 ALSO 是缺省。

command

组成规则动作的命令。有效的命令是 SELECT, INSERT, UPDATE, DELETE, NOTIFY 语句之一。

conditioncommand 里,特殊的表名字 NEWOLD 可以用于指向被引用表里的数值。NEWON INSERTON UPDATE 规则里可以指向被插入或更新的新行。OLDON UPDATEON DELETE 规则里可以指向现存的被更新或删除的行。

注意

为了在表上定义或修改规则,你必须是该表的拥有者。

在视图上用于 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;

里,一个 NOTIFY 事件将在 UPDATE 的时候发出,不管是否有满足 id = 42 条件的行。这是一个实现的限制,将来的版本应该修补这个毛病。

兼容性

CREATE RULE 是 PostgreSQL 语言的扩展,整个规则重写系统都是如此。


后退首页前进
CREATE ROLE上一级CREATE SCHEMA