PostgreSQL7.0手册-程序员手册 -42. Postgres 规则系统
getpgusername(), datetime('now'::text)
FROM shoelace_data shoelace_data, shoelace_data *NEW*,
shoelace_data *OLD*, shoelace_log shoelace_log
WHERE int4ne(6, shoelace_data.sl_avail)
AND bpchareq(shoelace_data.sl_name, 'sl7');
这就成了.所以最大限度的把规则系统的返回缩减后的结果是两个分析树的列表,与下面语句相同:
INSERT INTO shoelace_log SELECT
shoelace_data.sl_name, 6,
getpgusername(), 'now'
FROM shoelace_data
WHERE 6 != shoelace_data.sl_avail
AND shoelace_data.sl_name = 'sl7';
UPDATE shoelace_data SET sl_avail = 6
WHERE sl_name = 'sl7';
这就是执行的顺序以及规则定义的东西.做的替换和追加的资格(条件)用以确保如果原始的查询是下面这样
UPDATE shoelace_data SET sl_color = 'green'
WHERE sl_name = 'sl7';
就不会有日期记录写到表里,因为这回原始分析树不包含有关 sl_avail 的目标列表,NEW.sl_avail 将被 shoelace_data.sl_avail 代替,结果是下面的查询
INSERT INTO shoelace_log SELECT
shoelace_data.sl_name, shoelace_data.sl_avail,
getpgusername(), 'now'
FROM shoelace_data
WHERE shoelace_data.sl_avail != shoelace_data.sl_avail
AND shoelace_data.sl_name = 'sl7';
并且资格(条件)将永远不可能是真值.因为在分析树级别上 INSERT ... SELECT 和 INSERT ... VALUES 之间没有区别,所以如果原始查询更改多行的话,(规则)仍将生效.所以如果 Al 写出下面命令
UPDATE shoelace_data SET sl_avail = 0
WHERE sl_color = 'black';
实际上有四行被更新(sl1,sl2,sl3 和 sl4).但 sl3 已经是 sl_avail = 0.这回,原始的分析树资格(条件)已经不一样了,结果是生成下面的分析树
INSERT INTO shoelace_log SELECT
shoelace_data.sl_name, 0,
getpgusername(), 'now'
FROM shoelace_data
WHERE 0 != shoelace_data.sl_avail
AND shoelace_data.sl_color = 'black';
这个分析树将肯定插入三个新的日志记录.这也是完全正确的.
重要的是原始分析树最后执行.Postgres 的"交警" 在两个分析树的执行间做一次命令计数器增一的动作,所以第二个(分析树)可以看到第一个(分析树)所做的改变.如果 UPDATE 将先被执行,所有的行都已经设为零,所以记日志的 INSERT 将不能找到任何行是符合 0 != shoelace_data.sl_avail 条件的.
与视图共存
一个简单的保护视图关系,使其避免我们曾提到的有人可以在其中 INSERT,UPDATE 和 DELETE 不可见的数据的方法是让那些分析树被丢弃.我们创建下面规则
CREATE RULE shoe_ins_protect AS ON INSERT TO shoe
DO INSTEAD NOTHING;
CREATE RULE shoe_upd_protect AS ON UPDATE TO shoe
DO INSTEAD NOTHING;
CREATE RULE shoe_del_protect AS ON DELETE TO shoe
DO INSTEAD NOTHING;
如果 Al 现在试图对视图关系 shoe 做上面的任何操作,规则系统将应用这些规则.因为这些规则没有动作而且是 INSTEAD,结果是生成的分析树将是空的并且整个查询将变得空空如也,因为经过规则系统处理后没有什么东西剩下来用于优化或执行了.
注意:这个方法可能会令前端困惑,因为在数据库里完全没有任何事情发生,因而后端对查询将不返回任何信息.在 libqp 里甚至是一个 PGRES_EMPTY_QUERY 或其他的信息也不返回.在 psql 里,什么也没发生.这些将在以后修改.
一个更复杂的使用规则系统的方法是用规则系统创建一个重写分析树的规则,使分析树对真实的表进行正确的操作.要在视图 shoelace 上做这个工作,我们创建下面规则:
CREATE RULE shoelace_ins AS ON INSERT TO shoelace
DO INSTEAD
INSERT INTO shoelace_data VALUES (
NEW.sl_name,
NEW.sl_avail,
NEW.sl_color,
NEW.sl_len,
NEW.sl_unit);
CREATE RULE shoelace_upd AS ON UPDATE TO shoelace
DO INSTEAD
UPDATE shoelace_data SET
sl_name = NEW.sl_name,
sl_avail = NEW.sl_avail,
sl_color = NEW.sl_color,
sl_len = NEW.sl_len,
sl_unit = NEW.sl_unit
WHERE sl_name = OLD.sl_name;
CREATE RULE shoelace_del AS ON DELETE TO shoelace
DO INSTEAD
DELETE FROM shoelace_data
WHERE sl_name = OLD.sl_name;
现在有一包鞋带到达 Al 的商店,而且这是一大笔到货.Al 并不长于计算,所以我们不想让他手工更新鞋带视图.取而代之的是我们创建了两个小表,一个是我们可以从到货清单中插入东西,另一个是一个特殊的技巧.创建这些的命令如下:
CREATE TABLE shoelace_arrive (
arr_name char(10),
arr_quant integer
);
CREATE TABLE shoelace_ok (
ok_name char(10),
ok_quan
上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] 下一页

