Postgresql 在触发一次或两次INSERT或UPDATE之前触发on?

Postgresql 在触发一次或两次INSERT或UPDATE之前触发on?,postgresql,triggers,sql-update,sql-insert,Postgresql,Triggers,Sql Update,Sql Insert,我创建了以下触发器 创建触发器材质\u触发器 在插入或更新材料之前 每行 执行程序my_proc(); 我很难理解何时会在upsert查询上运行my_proc,如下所示: ——向上插入 插入到材料中(id、col) 值(1,1) 在冲突(id)上执行更新集 col='x' 如果我在运行upsert,我认为: 如果是插入,它将运行一次 在更新的情况下将运行两次 然后,从逻辑上讲,如果我在上传后运行这个,我会确保我的程序只被触发一次吗 如果我在运行upsert,我认为: 对于插入,它将运行

我创建了以下触发器

创建触发器材质\u触发器
在插入或更新材料之前
每行
执行程序my_proc();
我很难理解何时会在upsert查询上运行
my_proc
,如下所示:

——向上插入
插入到材料中(id、col)
值(1,1)
在冲突(id)上执行更新集
col='x'
如果我在运行upsert,我认为:

  • 如果是
    插入
    ,它将运行一次
  • 更新的情况下
    将运行两次
然后,从逻辑上讲,如果我在上传后运行这个
,我会确保
我的程序
只被触发一次吗

如果我在运行upsert,我认为:

  • 对于插入,它将运行一次

  • 在更新的情况下,它将运行两次

这可能是对冲突的误解

对于给定的行,upsert查询始终执行一个操作,而不是两个操作。它要么插入,要么在找到现有记录时更新。If甚至可以不执行任何操作,If
不执行任何操作
作为目标操作


在这两种情况下,每行的
触发器只触发一次。

在执行
更新的情况下,触发器实际上触发了两次。这可以通过以下方式进行演示:

——创建表
如果不存在,则创建表示例(uuid int unique);
--创建函数
创建或替换函数print_函数()
返回触发器
作为$body$
开始
提出“启动”通知;
提出“方法:%”通知,TG_OP;
归还新的;
结束;
$body$
语言plpgsql;
--创建触发函数
创建触发器示例\u触发器
在插入或更新示例之前
每行
执行程序print_函数();
--上游
在示例(uuid)中插入冲突(uuid)上的值(1)DO UPDATE SET uuid=5;
在示例(uuid)中插入冲突(uuid)上的值(1)DO UPDATE SET uuid=5;
其输出:

NOTICE:  Starting
NOTICE:  METHOD: INSERT             -- Populated with inital value
NOTICE:  Starting
NOTICE:  METHOD: INSERT             -- Fired a first time for insert (can't insert as exists)
NOTICE:  Starting
NOTICE:  METHOD: UPDATE             -- Fired a second time for update
INSERT 0 1

我想这完全回答了我的问题,谢谢!嘿,我很感激你花时间来回答这个问题,但在这种情况下它是不正确的,也许你可以删除它,这样它就不会误导未来的人们?