Migrating an Oracle MERGE statement to a PostgreSQL UPSERT statement

社会主义新天地 提交于 2021-02-18 15:22:42

问题


Can you please help me converting the following Oracle MERGE statement into a valid UPSERT statement for use in a PostgreSQL 9.3 database?

MERGE INTO my_table a
     USING (SELECT v_c1 key,
                   v_c2 AS pkey,
                   v_c3 AS wcount,
                   v_c4 AS dcount
              FROM DUAL) b
        ON (    a.key = b.key
            AND a.pkey = b.pkey
WHEN MATCHED
THEN
   UPDATE SET wcount = b.wcount,
              dcount = b.dcount
WHEN NOT MATCHED
THEN
   INSERT     (key,
               pkey,
               wcount,
               dcount)
    VALUES(b.key,b.pkey,b.wcount,b.dcount);

回答1:


I don't think there's UPSERT statement in PostgreSQL 9.3, but you can do this:

with cte_dual as (
    select
        v_c1 as key,
        v_c2 as pkey,
        v_c3 as wcount,
        v_c4 as dcount
), cte_update as (
    update my_table as a set
        wcount = b.wcount,
        dcount = b.dcount
    from cte_dual as b
    where b.key = a.key and b.pkey = a.pkey
    returning *
)
insert into my_table (key, pkey, wcount, dcount)
select d.key, d.pkey, d.wcount, d.dcount
from cte_dual as d
where not exists (select * from cte_update as u WHERE u.key = d.key and u.pkey = d.pkey)

You can read couple of similar questions:

  • How to UPSERT (MERGE, INSERT ... ON DUPLICATE UPDATE) in PostgreSQL?
  • Insert, on duplicate update in PostgreSQL?



回答2:


I ran on this today, read these, the docs, eventually used something very similar to what to my understanding the docs are advising now for UPSERT:

INSERT INTO table (
    $INSERT_COLUMN_NAMES
)
VALUES (
    $INSERT_COLUMN_VALUES
)
ON CONFLICT (
    $LIST_OF_PRIMARY_KEY_COLUMN_NAMES
)
DO UPDATE SET
    $UPDATE_SET_SUBCLAUSE
WHERE 
    $WHERE_CONDITION_ON_PRIMARY_KEYS
;

I was actually working it at DAO level so I can not provide a meaningful example at the moment, will review this later.

If I'm not mistaken is working perfectly fine. I felt forced into create a primary key that wasn't there, but actually belonged there.




回答3:


upsert works in Postgres 9.3 ,

Example-

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 mytable2 b);


来源:https://stackoverflow.com/questions/19395690/migrating-an-oracle-merge-statement-to-a-postgresql-upsert-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!