0

我有一个分区表和一个更新函数/触发器。更新行时,它首先删除该行,然后将其插入到正确的分区中。我的问题是我正在尝试做一个类似于 Oracle 中的 MERGE 的语句。我在 Postgres 中找到了使用 UPSERT 的类似实现的参考,如下所示:

WITH upsert as
(
   update mytable2 m 
      set sales=m.sales+d.sales, 
          status=d.status 
   from mytable d 
   where m.pid=d.pid
   RETURNING m.*
)
insert into mytable2 
select a.pid, a.sales, 'NEW' 
from mytable a 
where a.pid not in (select b.pid from upsert b);

但是,问题是更新首先触发 - 在特定行上导致删除和插入,然后插入再次插入。这是因为我在分区上的更新功能/触发器。有没有办法让它像在 Oracle 中那样通过合并(即如果找到行,更新它,否则插入它)而不会导致欺骗或因违反约束而失败?

非常感谢您的帮助!

4

1 回答 1

0

您的问题在于返回 null 的触发器和期望返回结果的 upsert 的交集。本质上,您正在做的是:

  1. 删除行
  2. 插入行
  3. 中止更新(这与您的 upsert 混淆)
  4. 检查更新是否完成,如果没有插入。

在这种情况下,您会遇到一些问题,因为您的触发器会破坏软件的流程。

那么如何使这项工作......

我看不出有一种简单的方法可以在一个非常大的集合上完成这项工作。我确实认为您将不得不将更新部分移动到您可以调用的函数中。该函数的细节将取决于您一次实际更新的行数。然后你可以做一个INSERT ... SELECT类似于你正在做的事情,但使用函数调用而不是 CTE。

于 2013-04-19T04:27:08.307 回答