Я настроил триггер для копирования некоторых полей новой записи в новую таблицу при вставке новой записи. В любом случае, это может успешно работать. но моя цель срабатывает при успешной или полной вставке, но теперь триггер будет срабатывать всякий раз, когда он будет успешным или неудачным.
Я пытался найти решение в поисковых системах, но все еще борюсь с этим. Итак, я занимаюсь решением здесь, спасибо, ребята.
добавка:
например: Я дважды вставляю одну и ту же запись, но устанавливаю «элемент» в качестве первичного ключа, поэтому второй раз вставка не удастся. но t2 все еще вставлен с помощью триггера.
триггерная функция:
Begin
INSERT INTO t2 (item,attr_1)
VALUES (New.item,New.attr_1);
RETURN New;
END;
Это воспроизведение проблемы:
postgres=# insert into t1 (item,attr_1,attr_2,attr_3) values ('a',1,2,3) on conflict(item)do nothing;
INSERT 0 1
postgres=# select * from t1;
item | attr_1 | attr_2 | attr_3
------+--------+--------+--------
a | 1 | 2 | 3
(1 行记录)
postgres=# select * from t2;
item | attr_1
------+--------
a | 1
(1 行记录)
postgres=# insert into t1 (item,attr_1,attr_2,attr_3) values ('a',1,2,3) on conflict(item)do nothing;
INSERT 0 0
postgres=# select * from t2;
item | attr_1
------+--------
a | 1
a | 1
(2 行记录)
@Belayer, спасибо за ваше предложение, я добавляю дополнительную информацию о проблеме.
Этого не должно произойти, но, не видя полного определения триггерной функции и оператора CREATE TRIGGER, а также определения обеих таблиц и любых других триггеров в них, мы могли только догадываться.





Что происходит:
create table trg_test(id integer primary key, fld1 varchar);
create table trg_test2(id integer , fld1 varchar);
CREATE FUNCTION cp_record( )
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
RAISE NOTICE 'Action is %', TG_OP;
INSERT INTO trg_test2 VALUES(NEW.id, NEW.fld1);
RETURN NEW;
END;
$function$
;
create trigger trg_test_cp_record before insert on trg_test for each row execute function cp_record();
insert into trg_test values (1, 'test') on conflict(id) do nothing;
NOTICE: Action is INSERT
INSERT 0 1
insert into trg_test values (1, 'test2') on conflict(id) do nothing;
NOTICE: Action is INSERT
INSERT 0 0
insert into trg_test values (1, 'test3') on conflict(id) do nothing;
NOTICE: Action is INSERT
INSERT 0 0
select * from trg_test;
id | fld1
----+------
1 | test
select * from trg_test2;
id | fld1
----+-------
1 | test
1 | test2
1 | test3
INSERT ... ON CONFLICT сначала пробует INSERT и активирует триггер BEFORE INSERT, который запускает оператор INSERT INTO trg_test2 VALUES(NEW.id, NEW.fld1);. Если конфликта нет, то INSERT переходит к исходной таблице и вы получаете INSERT 0 1. Когда происходит CONFLICT, исходного INSERT не происходит, следовательно, INSERT 0 0. Однако INSERT внутри триггера все же происходит и отображается в другой таблице.
Если вы измените триггер на AFTER INSERT:
create trigger trg_test_cp_record after insert on trg_test for each row execute function cp_record();
Затем:
insert into trg_test values (1, 'test') on conflict(id) do nothing;
NOTICE: Action is INSERT
INSERT 0 1
insert into trg_test values (1, 'test2') on conflict(id) do nothing;
INSERT 0 0
insert into trg_test values (1, 'test3') on conflict(id) do nothing;
INSERT 0 0
select * from trg_test;
id | fld1
----+------
1 | test
(1 row)
select * from trg_test;
id | fld1
----+------
1 | test
(1 row)
test=# select * from trg_test2;
id | fld1
----+------
1 | test
Исходное непротиворечивое утверждение проходит как INSERT. Утверждения о конфликте не действуют, поскольку срабатывает пункт о конфликте и INSERT не достигает триггера AFTER.
Черт возьми, это проблема, с которой я столкнулся! Огромное спасибо за ясность объяснений и терпение, хотя я изложил их недостаточно.
Сообщество SO поможет вам с проблемами, но от вас ждут определённых ожиданий. Пожалуйста, потратьте несколько минут, чтобы Совершить экскурсию и просмотреть Как спросить . Затем обновите свой вопрос, включив в него определения таблиц (DDL), примеры данных и ожидаемые результаты. Всё как форматированный текст или ещё лучше рабочий пример, но - без изображений. Кроме того, четко определите, что вы подразумеваете под успехом или полностью, что вы подразумеваете под неудачей (обычно, когда вставка завершается неудачей, выдается исключение, и триггер не выполняется.)