我设置了一个触发器,用于在插入新记录时将新记录的某些字段复制到新表。无论如何,这样就可以成功运行了。但是我的目标是插入成功或完全插入时触发,但现在无论成功还是失败都会触发。
我试图在搜索引擎中找到解决方案,但我仍在努力解决这个问题。所以我在这里寻求解决方案,谢谢大家。
补充:
例如: 我重新插入同一条记录两次,但我将“item”设置为主键,所以第二次不会成功插入。但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 行记录)
发生了什么:
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
确实发生了,并且它显示在另一个表中。为了完成这项工作,您需要测试 NEW
约束的 CONFLICT
值是否与 OLD
值相同,并使用该测试来让另一个表的 INSERT
继续或不继续。