J'ai un tableau où un utilisateur répond à une question. Les règles sont que l'utilisateur peut répondre à de nombreuses questions ou que de nombreux utilisateurs peuvent répondre à une question MAIS un utilisateur ne peut répondre à une question particulière qu'une seule fois. Si l'utilisateur répond à nouveau à la question, celle-ci doit simplement remplacer l'ancienne. Généralement, le conflit sur met à jour les travaux lorsque nous avons affaire à des colonnes uniques. Dans ce scénario, les colonnes person_id
et question_id
ne peut pas être unique. Cependant, la combinaison des deux est toujours unique. Comment implémenter l'instruction d'insertion qui se met à jour en cas de conflit?
CREATE TABLE "answer" (
"person_id" integer NOT NULL REFERENCES person(id),
"question_id" integer NOT NULL REFERENCES question(id) ON DELETE CASCADE, /* INDEXED */
"answer" character varying (1200) NULL,
PRIMARY KEY (person_id, question_id)
);
Placez simplement les deux clés dans le ON CONFLICT
clause:
INSERT INTO answer VALUES (1,1,'q1')
ON CONFLICT (person_id,question_id)
DO UPDATE SET answer = EXCLUDED.answer;
Exemple:
INSERT INTO answer VALUES (1,1,'q1')
ON CONFLICT (person_id,question_id)
DO UPDATE SET answer = EXCLUDED.answer;
SELECT * FROM answer;
person_id | question_id | answer
-----------+-------------+--------
1 | 1 | q1
(1 Zeile)
INSERT INTO answer VALUES (1,1,'q1-UPDATED')
ON CONFLICT (person_id,question_id)
DO UPDATE SET answer = EXCLUDED.answer;
SELECT * FROM answer;
person_id | question_id | answer
-----------+-------------+------------
1 | 1 | q1-UPDATED
(1 Zeile)
Vous pouvez également définir le primaire à l'extérieur de la table et vous n'avez pas besoin de réécrire toutes les colonnes qui y sont incluses.
CREATE TABLE "answer" (
"person_id" integer NOT NULL REFERENCES person(id),
"question_id" integer NOT NULL REFERENCES question(id) ON DELETE CASCADE, /* INDEXED */
"answer" character varying (1200) NULL);
ALTER TABLE "answer" ADD CONSTRAINT answer_pk PRIMARY KEY (person_id, question_id);
Puis:
INSERT INTO answer VALUES (1,1,'q1') ON CONFLICT ON CONSTRAINT answer_pk DO UPDATE SET answer = EXCLUDED.answer;
Lorsque la contrainte change à l'avenir, vous n'avez pas besoin d'ajuster manuellement les instructions d'insertion pour refléter cela.