While doing UPSERT in Postgres 9.5, is it possible to return null on INSERT success and return something ON CONFLICT?
I would like to something like this:
insert into "user" (timestamp, user_id, member_id)
values ($1, $2, $3)
ON CONFLICT (user_id, member_id)
DO select id from "user" where user_id = $2 returning user_id
The only purpose of selecting user_id is to return something (anything other than null) ON CONFLICT, and without writing to disk. I know that this can be done with ON CONFLICT DO UPDATE but it would involve writing to disk.
ON CONFLICT DO UPDATE updates the existing row that conflicts with the row proposed for insertion as its alternative action.
PostgreSQL lets you either add or modify a record within a table depending on whether the record already exists. This is commonly known as an "upsert" operation (a portmanteau of "insert" and "update").
In PostgreSQL, the UPSERT operation means either UPDATE or INSERT operation. The UPSERT operation allows us to either insert a row or skip the insert operation if a row already exists and update that row instead. Suppose you want to insert bulk data from one table to another table that already has some data.
The INSERT ON CONFLICT statement allows you to update an existing row that contains a primary key when you execute the INSERT statement to insert a new row that contains the same primary key. This feature is also known as UPSERT or INSERT OVERWRITE. It is similar to the REPLACE INTO statement of MySQL.
You could use CTE:
WITH cte AS (
INSERT INTO "user"(timestamp, user_id, member_id)
values ($1, $2, $3)
ON CONFLICT (user_id, member_id) DO NOTHING
RETURNING user_id
)
SELECT NULL AS result
WHERE EXISTS (SELECT 1 FROM cte) -- success
UNION ALL
SELECT id
FROM "user"
WHERE user_id = $2
AND NOT EXISTS (SELECT 1 FROM cte); -- conflict
DBFiddle Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With