在几个SO答案(1,2)中,建议如果存在冲突并且INSERT
在触发中,ON CONFLICT DO NOTHING
触发器不应触发声明。也许我误会了,但是在我的实验中似乎并非如此。
这是我的SQL,可以在Postgres 9.6上运行。
CREATE TABLE t (
n text PRIMARY KEY
);
CREATE FUNCTION def() RETURNS trigger AS $$
BEGIN
RAISE NOTICE 'Called def()';
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER deftrig BEFORE INSERT ON t FOR EACH ROW EXECUTE PROCEDURE def();
如果我随后运行两次插入:
testdb=> insert into t (n) values ('dummy') on conflict do nothing;
NOTICE: Called def()
INSERT 0 1
testdb=> insert into t (n) values ('dummy') on conflict do nothing;
NOTICE: Called def()
INSERT 0 0
我本来希望第一次见Called def()
,但下次不会见。
我怎么了?
答案 0 :(得分:6)
在冲突检查之前运行BEFORE INSERT
触发器。触发器有机会更改插入的值,并且在发生这种情况之前检查冲突是没有意义的。每个the documentation:
请注意,INSERT触发器之前所有按行的影响都反映在排除的值中,因为这些影响可能导致该行被排除在插入之外。
AFTER INSERT
触发器将按您预期的方式运行。