How to Retrieve id of inserted row when using upsert with WITH cluase in Posgres 9.5?

删除回忆录丶 提交于 2019-11-30 19:53:14

问题


I'm trying to do upset query in Postgres 9.5 using "WITH"

with s as (
            select id
            from products
            where product_key = 'test123'
        ), i as (
            insert into products (product_key, count_parts)
            select 'test123', 33
            where not exists (select 1 from s)
            returning id                       
        )
        update products
        set product_key='test123', count_parts=33
        where id = (select id from s) 
        returning id

Apparently I'm retrieving the id only on the updates and get nothing on insertions even though I know insertions succeeded.

I need to modify this query in a way I'll be able the get the id both on insertions and updates.

Thanks!


回答1:


It wasn't clear to me why you do at WITH first SELECT, but the reason you get only returning UPDATE id is because you're not selecting INSERT return.

As mentioned (and linked) in comments, Postgres 9.5 supports INSERT ON CONFLICT Clause which is a much cleaner way to use.

And some examples of before and after 9.5:

Before 9.5: common way using WITH

WITH    u AS (
            UPDATE      products
            SET         product_key='test123', count_parts=33
            WHERE       product_key = 'test123'
            RETURNING   id
        ),i AS (
            INSERT
            INTO        products ( product_key, count_parts )
            SELECT      'test123', 33
            WHERE       NOT EXISTS( SELECT 1 FROM u )
            RETURNING   id
        )
SELECT  *
FROM    (       SELECT id FROM u
        UNION   SELECT id FROM i
        ) r;

After 9.5: using INSERT .. ON CONFLICT

INSERT INTO products ( product_key, count_parts )
VALUES      ( 'test123', 33 )
ON CONFLICT ( product_key ) DO
UPDATE
SET         product_key='test123', count_parts=33
RETURNING   id;

UPDATE:

As hinted in a comment there might be slight cons using INSERT .. ON CONFLICT way.
In case table using auto-increment and this query happens a lot, then WITH might be a better option.
See more: https://stackoverflow.com/a/39000072/1161463



来源:https://stackoverflow.com/questions/39014190/how-to-retrieve-id-of-inserted-row-when-using-upsert-with-with-cluase-in-posgres

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