# 创建规则
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 语言扩展,整个查询重写系统也是如此。