postgresql,如何只在插入成功时触发触发函数?

问题描述 投票:0回答:1

我设置了一个触发器,用于在插入新记录时将新记录的某些字段复制到新表。无论如何,这样就可以成功运行了。但是我的目标是插入成功或完全插入时触发,但现在无论成功还是失败都会触发。

我试图在搜索引擎中找到解决方案,但我仍在努力解决这个问题。所以我在这里寻求解决方案,谢谢大家。

补充:

例如: 我重新插入同一条记录两次,但我将“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 行记录)

Results Picture

postgresql psql pgadmin
1个回答
0
投票

发生了什么:

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
继续或不继续。

© www.soinside.com 2019 - 2024. All rights reserved.