Query:
INSERT INTO
derived (a, b, c)
VALUES (?, ?, ?)
ON CONFLICT (a, b, c) DO UPDATE SET
a = EXCLUDED.a,
b = EXCLUDED.b,
c = EXCLUDED.c
WHERE EXISTS (select a from primary where a = ?)
Please note,
- fourth parameter is same as first parameter.
- derived.a has foreign-key-constraint on primary.a
- Update has to happen if there is a conflict on all 3 columns.
Unfortunately, this query is not working and I am still getting a foreign key violation when inserting with a value a which is not in primary table. Any help is appreciated.
2
Answers
Following did what I wanted:
Your solution while giving the results you want is overly complicated as it is essentially:
Lets analyze your solution to see why. First off your tables must look something like:
Now the actual data types and constraint types do not matter, just that
a
must be the same type in each table and must be unique in the table. Then the 3 column combination must form a unique combination inderived
.Now in order to get the conflict all 3 values, in the proper order must already exist in
derived
so your update operation merely sets each column to the same value it already has (yes setting a column to it’s current value does actually update the column). Finally, how about thewhere
clause. Well if a matching value forderived.a
did not exist inprimary.a
the row could not exist due to the it’s definition as a foreign key. Thus since the data values are the same and the where must return true the row content is exactly the same. And that is what thedo nothing
clause results in. So:The situation changes if there were another non-key column is involved (call it
d
. In this case you need to set only the value ford
update phase, you do not need to update columnsa
,b
,c
– they already exit.See demo here.