当前位置:早雪网网络学院编程文档数据库技术Postgresql → PostgreSQL7.0手册-程序员手册 -42. Postgres 规则系统

PostgreSQL7.0手册-程序员手册 -42. Postgres 规则系统

减小字体 增大字体 作者:不详  来源:supcode.com收集整理  发布时间:2005-7-23 12:21:48
- new available value
        log_who    name,          -- who did it
        log_when   datetime       -- when
    );

    CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data
        WHERE NEW.sl_avail != OLD.sl_avail
        DO INSERT INTO shoelace_log VALUES (
                                        NEW.sl_name,
                                        NEW.sl_avail,
                                        getpgusername(),
                                        'now'::text
                                    );
一个有趣的细节是在规则 INSERT 动作(action)里把 'now' 转换成类型 text.如果不这样做,分析器将在 CREATE RULE 时,将看到 shoelace_log 里的目标类型是日期并且将试图从中成功地获取一个常量.所以一个常量日期值将被存储,结果是所有日志的记录都将是 CREATE RULE 语句的执行时间.这可不是我们想要的.类型转换将导致分析器从中构建一个日期('now'::text)并且在规则执行时将被计算. 
现在 Al 键入 

    al_bundy=> UPDATE shoelace_data SET sl_avail = 6                       
    al_bundy->     WHERE sl_name = 'sl7';
然后我们看看日志表. 
    al_bundy=> SELECT * FROM shoelace_log;
    sl_name   |sl_avail|log_who|log_when                        
    ----------+--------+-------+--------------------------------
    sl7       |       6|Al     |Tue Oct 20 16:14:45 1998 MET DST
    (1 row)
这是我们想要的.后端发生的事情如下.分析器创建分析树(这回最初的分析树的部分写成高亮显示,因为操作的基础是用于更新规则的规则动作). 
    UPDATE shoelace_data SET sl_avail = 6
      FROM shoelace_data shoelace_data
     WHERE bpchareq(shoelace_data.sl_name, 'sl7');
这里是一个规则 'log_shoelace' 用于 ON UPDATE 带着规则资格表达式 
    int4ne(NEW.sl_avail, OLD.sl_avail)
和一个动作 
    INSERT INTO shoelace_log SELECT 
           *NEW*.sl_name, *NEW*.sl_avail,
           getpgusername(), datetime('now'::text)
      FROM shoelace_data *NEW*, shoelace_data *OLD*,
           shoelace_log shoelace_log;
不要相信 pg_rules 系统视图的输出.它是用于下面的特殊场合的:在 INSERT 中只引用了 NEW 和 OLD 并且输出 INSERT 的 VALUES 格式.实际上在分析树级别上,INSERT ... VALUES 和 INSERT ... SELECT 语句没有区别.它们都有可排列元素,目标列表以及还可能有资格(条件)等.优化器稍后将决定是否为该分析树创建一个有关类型结果,序列号扫描,索引扫面,联合或其他关系的的执行规划.如果在分析树里没有可排列元素的引用,它就变成了一个结果执行规划(INSERT ... VALUES 的情况).上面的规则动作(action)可以真实地在两种变种里生成. 
该规则是一个有资格(条件)的非 INSTEAD 规则,所以规则系统必须返回两个分析树.更改过的规则动作(action)和原始分析树.在第一步里,原始查询的可排列元素集成到规则动作(action)分析树里.生成 

    INSERT INTO shoelace_log SELECT 
           *NEW*.sl_name, *NEW*.sl_avai,
           getpgusername(), datetime('now'::text)
      FROM shoelace_data shoelace_data, shoelace_data *NEW*,
           shoelace_data *OLD*, shoelace_log shoelace_log;
第二步把规则资格(条件)增加进去,所以结果集限制为 sl_avail 改变了的行. 
    INSERT INTO shoelace_log SELECT 
           *NEW*.sl_name, *NEW*.sl_avai,
           getpgusername(), datetime('now'::text)
      FROM shoelace_data shoelace_data, shoelace_data *NEW*,
           shoelace_data *OLD*, shoelace_log shoelace_log
     WHERE int4ne(*NEW*.sl_avail, *OLD*.sl_avail);
第三步把原始分析树的资格(条件)加进去,把结果集进一步限制成只有被初始分析树改变的行. 
    INSERT INTO shoelace_log SELECT 
           *NEW*.sl_name, *NEW*.sl_avai,
           getpgusername(), datetime('now'::text)
      FROM shoelace_data shoelace_data, shoelace_data *NEW*,
           shoelace_data *OLD*, shoelace_log shoelace_log
     WHERE int4ne(*NEW*.sl_avail, *OLD*.sl_avail)
       AND bpchareq(shoelace_data.sl_name, 'sl7');
第四步把 NEW 引用替换为从原始分析树的目标列来的或从结果关系来的匹配的变量引用. 
    INSERT INTO shoelace_log SELECT 
           shoelace_data.sl_name, 6,
           getpgusername(), datetime('now'::text)
      FROM shoelace_data shoelace_data, shoelace_data *NEW*,
           shoelace_data *OLD*, shoelace_log shoelace_log
     WHERE int4ne(6, *OLD*.sl_avail)
       AND bpchareq(shoelace_data.sl_name, 'sl7');
第五步用 OLD 引用把结果关系的引用替换掉. 
    INSERT INTO shoelace_log SELECT 
           shoelace_data.sl_name, 6,

上一页  [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13]  下一页

[数据载入中...] [返回上一页] [打 印]