Перед вставкой (триггер уровня инструкции) не работает

#database #postgresql #function #triggers

#База данных #postgresql #функция #триггеры

Вопрос:

Приведенные ниже инструкции, которые я выполнил:

 create table tab1(id int , name varchar(10) , city varchar(10) , latest bool default true);
CREATE OR REPLACE FUNCTION public.updateoldrow()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
begin
update tab1 set latest ='0' where name = new.name and city = new.city and latest = '1';
RETURN NEW;
END;
$function$
;

create trigger trig_updateoldrow before
insert
on
public.tab1 for each statement execute procedure updateoldrow();

insert into tab1 values(1,'Shiwangini','xyz','true');
insert into tab1 values(2,'Shiwangini','xyz','true');
  

Я создал таблицу функцию (для обновления старой записи до ‘false’ с теми же критериями соответствия значению) затем создал триггер уровня инструкции (перед вставкой) -> затем вставил в нее 2 тестовые записи.
Теперь, когда я запускаю ‘select * from tab1;’, согласно ожиданиям, первое значение с id = 1 должно быть установлено в ‘false’. Однако этого не происходит. Я также проверил план выполнения инструкции insert, поэтому она вызывает триггер:

     explain (analyze true, verbose, costs, buffers)insert into tab1 
    values(2,'Shiwangini','xyz','true');

    Insert on public.tab1  (cost=0.00..0.01 rows=1 width=81) (actual time=0.113..0.113 rows=0 
    loops=1)
    Buffers: shared read=1 dirtied=1
  ->  Result  (cost=0.00..0.01 rows=1 width=81) (actual time=0.001..0.001 rows=1 loops=1)
    Output: 2, 'Shiwangini'::character varying(10), 'xyz'::character varying(10), true
    Planning Time: 0.020 ms
    Trigger trig_updateoldrow: time=0.060 calls=1
    Execution Time: 0.128 ms
  

Однако, если то же самое, чего я пытаюсь достичь с помощью триггера уровня строки — он работает должным образом и обновляет старое значение.

Здесь я не могу понять, почему триггер на уровне оператора работает не так, как ожидалось. Любая причина для этого будет оценена.

Ответ №1:

В документе говорится

НОВОЕ

Запись типа данных; переменная, содержащая новую строку базы данных для операций ВСТАВКИ / ОБНОВЛЕНИЯ в триггерах уровня строк. Эта переменная равна null в триггерах уровня инструкции и для операций УДАЛЕНИЯ.

таким образом, обновление не может работать должным образом, поскольку NEW значение равно null. Вам действительно нужен триггер на уровне строки.