UPDATE (20.08.2015):
Es gibt jetzt eine offizielle Implementierung für die Behandlung von Upserts durch die Verwendung von ON CONFLICT DO UPDATE
(offizielle Dokumentation). Zum Zeitpunkt des Schreibens befindet sich diese Funktion derzeit in PostgreSQL 9.5 Alpha 2, das hier heruntergeladen werden kann: Postgres-Quellverzeichnisse .
Hier ist ein Beispiel, vorausgesetzt, es item_id
ist Ihr Primärschlüssel:
INSERT INTO my_table
(item_id, price)
VALUES
(123456, 10.99)
ON
CONFLICT (item_id)
DO UPDATE SET
price = EXCLUDED.price
Ursprünglicher Beitrag ...
Hier ist eine Implementierung, auf die ich gestoßen bin, um einen Überblick darüber zu erhalten, ob eine Einfügung oder Aktualisierung stattgefunden hat.
Die Definition von upsert_data
ist, die Werte in einer einzelnen Ressource zu konsolidieren, anstatt den Preis und die item_id zweimal angeben zu müssen: Einmal für die Aktualisierung, noch einmal für die Einfügung.
WITH upsert_data AS (
SELECT
'19.99'::numeric(10,2) AS price,
'abcdefg'::character varying AS item_id
),
update_outcome AS (
UPDATE pricing_tbl
SET price = upsert_data.price
FROM upsert_data
WHERE pricing_tbl.item_id = upsert_data.item_id
RETURNING 'update'::text AS action, item_id
),
insert_outcome AS (
INSERT INTO
pricing_tbl
(price, item_id)
SELECT
upsert_data.price AS price,
upsert_data.item_id AS item_id
FROM upsert_data
WHERE NOT EXISTS (SELECT item_id FROM update_outcome LIMIT 1)
RETURNING 'insert'::text AS action, item_id
)
SELECT * FROM update_outcome UNION ALL SELECT * FROM insert_outcome
Wenn Sie die Verwendung von nicht mögen upsert_data
, finden Sie hier eine alternative Implementierung:
WITH update_outcome AS (
UPDATE pricing_tbl
SET price = '19.99'
WHERE pricing_tbl.item_id = 'abcdefg'
RETURNING 'update'::text AS action, item_id
),
insert_outcome AS (
INSERT INTO
pricing_tbl
(price, item_id)
SELECT
'19.99' AS price,
'abcdefg' AS item_id
WHERE NOT EXISTS (SELECT item_id FROM update_outcome LIMIT 1)
RETURNING 'insert'::text AS action, item_id
)
SELECT * FROM update_outcome UNION ALL SELECT * FROM insert_outcome