Comment faire correctement upsert en postgres 9.5
syntaxe correcte de upsert avec postgresql 9.5, au-dessous de la requête montre column reference "gallery_id" is ambiguous
erreur, pourquoi?
var dbQuery = `INSERT INTO category_gallery (
category_id, gallery_id, create_date, create_by_user_id
) VALUES (, , , )
ON CONFLICT (category_id)
DO UPDATE SET
category_id = ,
last_modified_date = ,
last_modified_by_user_id =
WHERE gallery_id = `;
j'ai essayé de changer WHERE gallery_id = ;
en WHERE category_gallery.gallery_id = ;
puis affiche l'erreur there is no unique or exclusion constraint matching the ON CONFLICT specification
, mais Je ne veux pas définir gallery_id ou category_id comme unique parce que je veux être sûr que les deux colonnes sont les mêmes puis faites la mise à jour....
comment faire correctement upsert en postgres 9.5?
si ON CONFLICT
besoin colonne unique, dois-je utiliser une autre méthode, comment?
je veux être sûr de plusieurs colonnes les deux conflits puis faire la mise à jour, ce qui est l'usage correct
var dbQuery = `INSERT INTO category_gallery (
category_id, gallery_id, create_date, create_by_user_id
) VALUES (, , , )
ON CONFLICT (category_id, gallery_id)
DO UPDATE SET
category_id = ,
last_modified_date = ,
last_modified_by_user_id =
WHERE gallery_id = `;
var dbQuery = `INSERT INTO category_gallery (
category_id, gallery_id, create_date, create_by_user_id
) VALUES (, , , )
ON CONFLICT (category_id AND gallery_id)
DO UPDATE SET
category_id = ,
last_modified_date = ,
last_modified_by_user_id =
WHERE gallery_id = `;
(category_id , gallery_id pas unique colonne)
category_id | gallery_id | create_date | create_by_user_id | last_modified_date | last_modified_by_user_id
1 | 1 | ...
1 | 2 | ...
2 | 2 | ...
1 | 3 | ...
2 réponses
la construction ON CONFLICT
nécessite une contrainte de travail UNIQUE
. De la documentation sur INSERT .. ON CONFLICT
clause :
la clause facultative
ON CONFLICT
spécifie une action alternative à la levée d'une violation unique ou contrainte d'exclusion erreur de violation. Pour chaque ligne individuelle proposée Pour insertion, l'insertion se poursuit ou, si une la contrainte d'arbitrage ou l'index spécifié par conflict_target est violé, l'alternative conflict_action est prise.ON CONFLICT DO NOTHING
évite simplement d'insérer une rangée comme son action alternative.ON CONFLICT DO UPDATE
met à jour la rangée existante qui est en conflit avec la rangée qu'il est proposé d'insérer à titre de solution de rechange.
maintenant, la question n'est pas très claire, mais vous avez probablement besoin d'une contrainte UNIQUE
sur les 2 colonnes combinées: (category_id, gallery_id)
.
ALTER TABLE category_gallery
ADD CONSTRAINT category_gallery_uq
UNIQUE (category_id, gallery_id) ;
si la ligne à insérer correspond à les deux valeurs avec une ligne déjà sur la table, alors au lieu de INSERT
, faites un UPDATE
:
INSERT INTO category_gallery (
category_id, gallery_id, create_date, create_by_user_id
) VALUES (, , , )
ON CONFLICT (category_id, gallery_id)
DO UPDATE SET
last_modified_date = EXCLUDED.create_date,
last_modified_by_user_id = EXCLUDED.create_by_user_id ;
vous pouvez utiliser l'une ou l'autre des colonnes de la contrainte UNIQUE:
ON CONFLICT (category_id, gallery_id)
ou le nom de la contrainte:
ON CONFLICT ON CONSTRAINT category_gallery_uq
comme alternative simplifiée à la réponse actuellement acceptée , la contrainte UNIQUE
peut être ajoutée anonymement lors de la création de la table:
CREATE TABLE table_name (
id TEXT PRIMARY KEY,
col TEXT,
UNIQUE (id, col)
);
ensuite, la requête upsert devient (semblable à ce qui a déjà été répondu):
INSERT INTO table_name (id, col) VALUES (, )
ON CONFLICT (id, col)
DO UPDATE SET col = ;