Правило не сработало после обновления в postgresql - PullRequest
2 голосов
/ 30 марта 2011

Следуя инструкциям в www.postgresql.org

Я создал это утверждение:

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
                            );

Когда я пытаюсь выполнить запрос в консоли запросов pgAdmin3:

UPDATE shoelace_data SET sl_avail = 6 WHERE sl_name = 'sl7';

Выполняется только запрос на обновление, и правило не запускается. Я пытаюсь использовать команду EXPLAIN, чтобы понять, почему.

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)"

Я также пытаюсь использовать опцию VERBOSE с EXPLAIN, но не могу понять, почему мое событие не сработало.

Ответы [ 3 ]

3 голосов
/ 30 марта 2011

Вы выбрали неправильную функцию. Забудьте о правилах & mdash; они очень тяжелые, почти невозможно сделать правильно.

Здесь вам нужен триггер:

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;
<i>sl_name | sl_avail | log_who | log_when 
---------+----------+---------+----------
foo     |        1 |         | 
</i>
update shoelace_log set sl_avail=2;
select * from shoelace_log;
<i> sl_name | sl_avail | log_who  |         log_when          
---------+----------+----------+---------------------------
 foo     |        2 | tometzky | 2011-03-30 17:06:21.07137
</i>
1 голос
/ 30 марта 2011

Возможно, вы захотите использовать готовый аддон, который сделает это за вас:

http://pgfoundry.org/projects/tablelog/

0 голосов
/ 01 апреля 2011

Я попробовал пример, и это сработало. Но я должен был сначала создать таблицу shoelace_data. Этой таблицы нет в примере.

create table shoelace_data (
    sl_name text,
    sl_avail integer
);
insert into shoelace_data values ('Catcall', 3);
update shoelace_data set sl_avail = 5;

Теперь, если вы выбираете из таблицы log . , .

select * from shoelace_log;
"Catcall";5;"postgres";"2011-03-31 20:40:10.906"

Обратите внимание, что правило гласит: вставить в shoelace_log при обновлении столбца sl_avail в shoelace_data .

...