syntaxe correcte de upsert avec postgresql 9.5, la requête ci-dessous 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 ($1, $2, $3, $4)
ON CONFLICT (category_id)
DO UPDATE SET
category_id = $1,
last_modified_date = $3,
last_modified_by_user_id = $4
WHERE gallery_id = $2`;
J'ai essayé de changer WHERE gallery_id = $2;
à WHERE category_gallery.gallery_id = $2;
affiche alors 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 m'assurer que les deux colonnes sont identiques, puis mettre à jour ....
Comment faire correctement upsert dans Postgres 9.5?
si ON CONFLICT
besoin d'une colonne unique, dois-je utiliser une autre méthode, comment?
Je veux m'assurer que plusieurs colonnes sont en conflit, puis mettre à jour, quelle est l'utilisation correcte
var dbQuery = `INSERT INTO category_gallery (
category_id, gallery_id, create_date, create_by_user_id
) VALUES ($1, $2, $3, $4)
ON CONFLICT (category_id, gallery_id)
DO UPDATE SET
category_id = $1,
last_modified_date = $3,
last_modified_by_user_id = $4
WHERE gallery_id = $2`;
var dbQuery = `INSERT INTO category_gallery (
category_id, gallery_id, create_date, create_by_user_id
) VALUES ($1, $2, $3, $4)
ON CONFLICT (category_id AND gallery_id)
DO UPDATE SET
category_id = $1,
last_modified_date = $3,
last_modified_by_user_id = $4
WHERE gallery_id = $2`;
table (category_id, gallery_id pas une colonne unique)
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 | ...
La construction ON CONFLICT
Nécessite une contrainte UNIQUE
pour fonctionner. De la documentation sur clause INSERT .. ON CONFLICT
:
La clause facultative
ON CONFLICT
Spécifie une action alternative à la levée d'une contrainte d'exclusion unique ou erreur de violation. Pour chaque ligne individuelle proposée pour l'insertion, l'insertion se poursuit ou, si une contrainte ou un index arbitre spécifié par conflict_target est violé, l'autre conflict_action est prise.ON CONFLICT DO NOTHING
Évite simplement d'insérer une ligne comme action alternative.ON CONFLICT DO UPDATE
Met à jour la ligne existante qui entre en conflit avec la ligne proposée pour l'insertion en tant qu'action alternative.
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 aux deux valeurs avec une ligne déjà sur la table, alors au lieu de INSERT
, faites une UPDATE
:
INSERT INTO category_gallery (
category_id, gallery_id, create_date, create_by_user_id
) VALUES ($1, $2, $3, $4)
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 soit les 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 (similaire à ce qui a déjà été répondu):
INSERT INTO table_name (id, col) VALUES ($1, $2)
ON CONFLICT (id, col)
DO UPDATE SET col = $2;