用于on conflict
实现upsert
行为是一个很棒的功能。我想知道是否要找到该功能的 RFC,是否可以找到一种使用on conflict
事件来调用函数的方法,或者使用类似以下内容的方法:
on conflict
do $$
insert into another table
$$
Run Code Online (Sandbox Code Playgroud)
否则,考虑到我自己对 postgresql 还很陌生,有没有办法“捕获”冲突以进行进一步干预。
您不能使用该on conflict
关键字影响其他表。正如官方文档所述,conflict_action 可能仅为以下之一:
conflict_action is one of:
DO NOTHING
DO UPDATE SET { column_name = { expression | DEFAULT } |
( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |
( column_name [, ...] ) = ( sub-SELECT )
} [, ...]
[ WHERE condition ]
Run Code Online (Sandbox Code Playgroud)
但是,这并不意味着没有解决方法(至少对于该do nothing
命令而言)。您可以使用一个函数与 PostgreSQL 中非常有用的关键字组合found
来模拟类似的东西。
create or replace function generic_insert(
p_user_name text
)
returns boolean
language plpgsql
as
$$
begin
insert into users (user_name) values (p_user_name) on conflict do nothing;
if not found then <your code> end if;
return found;
end;
$$;
Run Code Online (Sandbox Code Playgroud)
这里的技巧是found
关键字返回“受影响的行数”(最后执行的查询的行数)。由于do nothing
没有影响任何行,found
因此返回 false,因此您可以通过此知道您的插入导致命令do nothing
的部分on conflict
触发。当然,您可以在 if 语句中放入您想要的任何代码或插入命令。