2

We have a DB for which we need a "selsert" (not upsert) function. The function should take a text value and return a id column of existing row (SELECT) or insert the value and return id of new row (INSERT). There are multiple processes that will need to perform this functionality (selsert)

I have been experimenting with pg_advisory_lock and ON CONFLICT clause for INSERT but am still not sure what approach would work best (even when looking at some of the other answers).

So far I have come up with following

WITH 
selected AS (
  SELECT id FROM test.body_parts WHERE (lower(trim(part))) = lower(trim('finger')) LIMIT 1
),
inserted AS (
  INSERT INTO test.body_parts (part)
  SELECT trim('finger')
  WHERE NOT EXISTS ( SELECT * FROM selected )
  -- ON CONFLICT (lower(trim(part))) DO NOTHING -- not sure if this is needed
  RETURNING id
)
SELECT id, 'inserted' FROM inserted
UNION
SELECT id, 'selected' FROM selected
  • Will above query (within function) insure consistency in high concurrency write workloads?
  • Are there any other issues I must consider (locking?, etc, etc)

BTW, I can insure that there are no duplicate values of (part) by creating unique index. That is not an issue. What I am after is that SELECT returns existing value if another process does INSERT (I hope I am explaining this right)

Unique index would have following definition

CREATE UNIQUE INDEX body_parts_part_ux
  ON test.body_parts
  USING btree
  (lower(trim(part)));
zam6ak
  • 7,229
  • 11
  • 46
  • 84
  • Possible migration to [DBA StackExchange](https://dba.stackexchange.com/). – Parfait Mar 27 '18 at 21:37
  • Nah, this is about "programming" in SQL. – Laurenz Albe Mar 28 '18 at 08:02
  • @Parfait IMHO, this is very much about programming, as it relates to how to write SQL that concurrent apps will use and SQL that is safe for high concurrent write workloads. – zam6ak Mar 28 '18 at 12:56
  • @zam6ak ... DBA SE does indeed allow programming but in a specialized vein. I recommend the migration because such concepts, *consistency*, *high concurrency*, *locking* are DBA concepts, a bit more nuanced than general SQL scripting. – Parfait Mar 28 '18 at 13:34
  • Does this answer your question? https://stackoverflow.com/a/42217872/14731 – Gili Jun 03 '22 at 06:00

0 Answers0