↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1 / 7.0 / 6.5 / 6.4
历史版本PostgreSQL 7.0 已于 2005 年 5 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

CREATE RULE

CREATE RULE — 定义一条新规则

大纲

CREATE RULE name AS ON event
    TO object [ WHERE condition ]
    DO [ INSTEAD ] [ action | NOTHING ]
  

输入

name

要创建的规则的名称。

event

事件是 select、 update、delete 或 insert 之一。

object

Object 是 table 或 table.column。

condition

任意的 SQL WHERE 子句,只要 SQL 中允许出现实例 变量,new 或 old 就可以出现在实例变量的位置上。

action

任意的 SQL 语句,只要 SQL 中允许出现实例 变量,new 或 old 就可以出现在实例变量的位置上。

输出

CREATE

规则成功创建时返回的消息。

描述

Postgres 的 规则系统允许定义在对数据库表或类进行插入、更新或 删除时所执行的替代动作。目前,规则 用于实现表视图。

一条规则的语义是:当单个实例被 访问、插入、更新或删除时,会有一个旧实例(对于 选择、更新和删除)和一个新实例(对于插入和 更新)。 如果 ON 子句中指定的 event 和 WHERE 子句中指定的 condition 对旧实例为真,该规则的 action 部分就会被 执行。不过首先,旧实例和/或新实例中字段的值会替换到 old.attribute-name 和 new.attribute-name 上。

规则的 action 部分 与触发激活它的用户命令使用相同的命令标识符和事务标识符 执行。

注解

关于 SQL 规则有一点需要提醒。如果同一个类名 或实例变量出现在规则的 event、 condition 和 action 部分中, 它们都会被视为不同的元组变量。更准确地说, new 和 old 是这些子句之间 仅有的共享元组变量。例如,下面的 两条规则具有相同的语义:

ON UPDATE TO emp.salary WHERE emp.name = "Joe"
    DO 
        UPDATE emp SET ... WHERE ...
    
ON UPDATE TO emp-1.salary WHERE emp-2.name = "Joe"
    DO 
        UPDATE emp-3 SET ...  WHERE ...
    

每条规则都可以带可选的 INSTEAD 标记。 如果没有 该标记,当规则 condition 部分中的 event 发生时,action 会随用户命令 一起执行。或者, action 部分也可以 替代用户命令执行。在后一种情况下, action 可以是关键字 NOTHING。

避免循环规则时务必特别注意。 例如,尽管 下面两条规则定义中的每一条都被 Postgres 接受, 但 select 命令会导致 Postgres 报告错误,因为查询循环了太多次:

例 19.1. 循环重写规则组合的例子。

CREATE RULE bad_rule_combination_1 AS
    ON SELECT TO emp
    DO INSTEAD 
        SELECT TO toyemp;
     
CREATE RULE bad_rule_combination_2 AS
    ON SELECT TO toyemp
    DO INSTEAD 
        SELECT TO emp;
     

这个从 EMP 中选择的尝试会导致 Postgres 报错, 因为这些查询循环了太多次。

SELECT * FROM emp;
      


要在一个类上定义规则,你必须拥有该类的规则定义权限。 使用 GRANT 和 REVOKE 来更改权限。

SQL 规则中的对象不能是数组引用,也 不能带参数。

除 "oid" 字段外,系统属性不能在 规则中的任何地方被引用。这尤其 意味着实例的函数(例如 foo(emp),其中 emp 是一个类)不能在规则中的任何地方被调用。

规则系统将规则文本和查询计划存储为 文本属性。这意味着如果规则加上其各种内部表示 超过大约一页(8KB)的某个值, 规则的创建可能会失败。

用法

让 Sam 获得与 Joe 相同的薪水调整:

CREATE RULE example_1 AS
    ON UPDATE emp.salary WHERE old.name = "Joe"
    DO 
        UPDATE emp 
        SET salary = new.salary
        WHERE emp.name = "Sam";
   

在 Joe 接受薪水调整时,该事件 将变为真,并且 Joe 的旧实例和提议的 新实例对执行例程可用。 因此,他的新薪水会被代入该规则的 action 部分,随后被执行。这样就把 Joe 的薪水传播给了 Sam。

让 Bill 在访问时获得 Joe 的薪水:

CREATE RULE example_2 AS
    ON SELECT TO EMP.salary
    WHERE old.name = "Bill"
    DO INSTEAD
        SELECT emp.salary
        FROM emp
        WHERE emp.name = "Joe";
   

拒绝 Joe 访问鞋部门员工的薪水 (current_user 返回当前 用户的名称):

  
CREATE RULE example_3 AS
    ON 
        SELECT TO emp.salary
        WHERE old.dept = "shoe" AND current_user = "Joe"
    DO INSTEAD NOTHING;
   

创建一个在玩具部门工作的员工的视图。

CREATE toyemp(name = char16, salary = int4);

CREATE RULE example_4 AS
    ON SELECT TO toyemp
    DO INSTEAD
        SELECT emp.name, emp.salary
        FROM emp
        WHERE emp.dept = "toy";
   

所有新员工的薪水必须不超过 5,000

CREATE RULE example_5 AS
    ON INERT TO emp WHERE new.salary > 5000
    DO 
        UPDATE emp SET salary = 5000
        WHERE emp.oid = new.oid;
   

兼容性

SQL92

CREATE RULE 语句是 Postgres 的语言扩展。 SQL92 中没有 CREATE RULE 语句。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。