即使在ON CONFLICT情况下,postgres INSERT触发器也会触发

时间:2019-02-28 23:35:02

标签: postgresql triggers

在几个SO答案(12)中,建议如果存在冲突并且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(),但下次不会见。

我怎么了?

1 个答案:

答案 0 :(得分:6)

在冲突检查之前运行BEFORE INSERT触发器。触发器有机会更改插入的值,并且在发生这种情况之前检查冲突是没有意义的。每个the documentation:

  

请注意,INSERT触发器之前所有按行的影响都反映在排除的值中,因为这些影响可能导致该行被排除在插入之外。

AFTER INSERT触发器将按您预期的方式运行。