Quantcast
Viewing all articles
Browse latest Browse all 207

ON CONFLICT DO UPDATE command cannot affect row a second time when trying to pass additional columns from a CTE in postgresql

Based on the SO: https://dba.stackexchange.com/a/46477 answer provided, I have been extending the Function with UPSERT in Postgres 9.5 or later for my own purposes to insert data into multiple referenced tables.

I have the following type that I am passing to the function:

CREATE TYPE symbol_record AS(    name                       character varying(32),    exchange                   character varying(64),    base_name                  character varying(16),    base_precision             smallint,    base_commission_precision  smallint,    quote_name                 character varying(16),    quote_precision            smallint,    quote_commission_precision smallint);

the following relevant CTE's:

-- select all the distinct base_name and quote_nametyp_asset AS (SELECT v.name, a.id    FROM (        SELECT DISTINCT (base_name) name FROM val        UNION        SELECT DISTINCT (quote_name) name FROM val    ) v    LEFT JOIN asset a USING (name)),

and

ins_asset AS (INSERT INTO asset AS a (name, created_at)    SELECT name, now()    FROM typ_asset    WHERE id IS NULL    ON CONFLICT (name) DO UPDATE        SET name = EXCLUDED.name            WHERE a.name <> EXCLUDED.name    RETURNING a.name, a.id),

are working correctly.

However, I am unsure how to return the matching 'precision' and 'commission_precision' columns for each of the base/quote for consumption by the calling insert/select in ins_asset.

I tried:

typ_asset AS (SELECT v.name, v."precision", v.commission_precision, a.id    FROM (        SELECT DISTINCT (base_name) name, (base_precision) "precision", (base_commission_precision) commission_precision FROM val        UNION        SELECT DISTINCT (quote_name) name, (quote_precision) "precision", (quote_commission_precision) commission_precision FROM val    ) v    LEFT JOIN asset a USING (name)),

and adding the columns accordingly to the ins_asset CTE, but am getting the error:

ERROR: ON CONFLICT DO UPDATE command cannot affect row a second time

I am currently using Postgres 14, and the tables and full function can be seen at:https://dbfiddle.uk/?rdbms=postgres_14&fiddle=bfcb7f7a9a9fcbd8a1b65ec033af8ac2

I am sure it has something to do with the inserting additional data into the asset table (typ_asset / ins_asset) ctes, as it works fine without passing the additional columns (or I am passing them back incorrectly)

And further, yes I am fully aware that I am using a reserved keyword (precision). As this is the business language/terminology I have kept it for now (quoting as necessary), but it will also be fixed.

What is the correct way to return the 'precision' and 'commission_precision' columns, and upsert them into the asset table? The 'name' column in the asset table is unique, and I have tried to set commission_precision instead of name in case the unique column was the cause of the error. that also failed with the same error.

edit(1) per requested by ypercubeᵀᴹ, the full working fiddle without the precision and commission_precision values in the asset table:https://dbfiddle.uk/?rdbms=postgres_14&fiddle=9f7ad113c6c812c1348bbc85eef24661

(2) I'm sorry, yes you are correct, I have been trying many different things to fix the problem and DISTINCT ON was one thing I tried (because I don't fully understand the language), apparently, among several other changes. I have corrected the non working dbfiddle, and that actually fixed the problem.


Viewing all articles
Browse latest Browse all 207

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>