#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. Вам действительно нужен триггер на уровне строки.