postgresql中update语句后未激发规则
遵循 我创建了以下语句:postgresql中update语句后未激发规则,postgresql,rules,Postgresql,Rules,遵循 我创建了以下语句: CREATE TABLE shoelace_log ( sl_name text, -- shoelace changed sl_avail integer, -- new available value log_who text, -- who did it log_when timestamp -- when); CREATE RULE log_shoelace AS ON UPDATE
CREATE TABLE shoelace_log (
sl_name text, -- shoelace changed
sl_avail integer, -- new available value
log_who text, -- who did it
log_when timestamp -- 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,
current_user,
current_timestamp
);
只执行更新查询,不触发规则。我尝试使用命令解释原因
EXPLAIN UPDATE shoelace_log SET sl_avail = 6 WHERE sl_name = 'sl7';
日志上写着:
"Seq Scan on shoelace_log (cost=0.00..19.66 rows=4 width=32)"
" Filter: (sl_name = 'sl7'::text)"
"Seq Scan on shoelace_log (cost=0.00..19.62 rows=4 width=78)"
" Filter: (sl_name = 'sl7'::text)"
我也尝试在EXPLAIN中使用VERBOSE选项,但我不明白为什么没有触发我的事件。您选择了错误的功能。完全忘记规则吧——它们很难做到,几乎不可能做到正确 您需要的是一个触发器:
create or replace function shoelace_log_who_when()
returns trigger language plpgsql as
$$
begin
if OLD.sl_avail is distinct from NEW.sl_avail then
NEW.log_who = current_user;
NEW.log_when = current_timestamp;
end if;
return NEW;
end;
$$;
create trigger shoelace_log_who_when before update on shoelace_log
for each row execute procedure shoelace_log_who_when();
试试看:
insert into shoelace_log values ( 'foo', 1, NULL, NULL );
select * from shoelace_log;
您可能还想考虑使用预构建的ADON为您这样做:
我试过这个例子,它奏效了。但我必须先创建鞋带数据表。该表不在示例中
create table shoelace_data (
sl_name text,
sl_avail integer
);
insert into shoelace_data values ('Catcall', 3);
update shoelace_data set sl_avail = 5;
现在,如果您从日志表中选择
select * from shoelace_log;
"Catcall";5;"postgres";"2011-03-31 20:40:10.906"
请注意,规则规定,当鞋带数据中的sl_avail列有更新时,应插入鞋带日志。它不是tablelog。这只是为了在表中填写自动上次修改的时间戳和用户。我尝试在pg9上运行您链接到的示例,但遇到了相同的问题。您说您的pgAdmin3查询是UPDATE shoelace_data,但您解释了UPDATE shoelace_log日志表。。。你确定你正在键入你认为正在键入的查询吗?+1是一个很好的答案,但仍然不能解释为什么这样一个简单的示例不起作用。这就是为什么你不应该使用规则。它们非常复杂,即使是经验丰富的博士后用户也不会试图解释他们的行为。我认为他们被认为是被开除了博士后;在9.1版本中,视图上的INSTEAD OF触发器不再需要它们了。可惜pg文档没有声明不应该使用它们。我已经阅读了一些原因,说明它们是痛苦的,应该避免,但并不是因为它们没有文档所描述的功能。OP混淆了数据表和日志表——他想在以某种方式更新前者时插入后者。你需要一个不同的触发程序。重新阅读问题,在解释混淆之前停下来。。。 update shoelace_log set sl_avail=2; select * from shoelace_log; sl_name | sl_avail | log_who | log_when ---------+----------+----------+--------------------------- foo | 2 | tometzky | 2011-03-30 17:06:21.07137
create table shoelace_data (
sl_name text,
sl_avail integer
);
insert into shoelace_data values ('Catcall', 3);
update shoelace_data set sl_avail = 5;
select * from shoelace_log;
"Catcall";5;"postgres";"2011-03-31 20:40:10.906"