109 votes

MySQL Insertion conditionnelle

J'ai de la difficulté à former un INSERT conditionnel

J'ai x_table avec des colonnes (instance, utilisateur, élément) où ID instance est unique. Je souhaite insérer une nouvelle ligne uniquement si l'utilisateur ne dispose pas déjà d'un élément donné.

Par exemple, essayer d’insérer instance = 919191 user = 123 item = 456

 Insert into x_table (instance, user, item) values (919191, 123, 456) 
    ONLY IF there are no rows where user=123 and item=456
 

Toute aide ou orientation dans la bonne direction serait grandement appréciée.

134voto

Jonathan Leffler Points 299946

Si votre SGBD n'impose pas de restrictions sur la table que vous avez sélectionnée lors de l'exécution d'une insertion, essayez:

 INSERT INTO x_table(instance, user, item) 
    SELECT 919191, 123, 456
        FROM dual
        WHERE NOT EXISTS (SELECT * FROM x_table
                             WHERE user = 123 
                               AND item = 456)
 

En cela, dual est une table avec une seule ligne (trouvée à l'origine dans Oracle, maintenant ailleurs également). La logique est que l'instruction SELECT génère une seule ligne de données avec les valeurs requises, mais uniquement lorsque les valeurs ne sont pas déjà trouvées.

Vous pouvez également consulter l'instruction MERGE.

56voto

dougk Points 851

Vous pouvez également utiliser INSERT IGNORE qui ignore silencieusement l'insertion au lieu de mettre à jour ou d'insérer une ligne lorsque vous avez un index unique (utilisateur, élément).

La requête ressemblera à ceci:

 INSERT IGNORE INTO x_table(instance, user, item) VALUES (919191, 123, 456)
 

Vous pouvez ajouter l'index unique avec CREATE UNIQUE INDEX user_item ON x_table (user, item) .

43voto

temple Points 51

Avez-vous déjà essayé quelque chose comme ça?

 INSERT INTO x_table
SELECT 919191 as instance, 123 as user, 456 as item
FROM x_table
WHERE (user=123 and item=456)
HAVING COUNT(*) = 0;
 

10voto

Alex Martelli Points 330805

Avec un UNIQUE(user, item) , faites:

 Insert into x_table (instance, user, item) values (919191, 123, 456) 
  ON DUPLICATE KEY UPDATE user=123
 

le bit user=123 est un "no-op" pour correspondre à la syntaxe de la clause ON DUPLICATE sans rien faire lorsqu'il y a des doublons.

1voto

NickZoic Points 2406

Si vous ajoutez une contrainte qui (x_table.user, x_table.item) est unique, l'insertion d'une autre ligne avec le même utilisateur et le même élément échouera.

par exemple:

 mysql> create table x_table ( instance integer primary key auto_increment, user integer, item integer, unique (user, item));
Query OK, 0 rows affected (0.00 sec)

mysql> insert into x_table (user, item) values (1,2),(3,4);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> insert into x_table (user, item) values (1,6);
Query OK, 1 row affected (0.00 sec)

mysql> insert into x_table (user, item) values (1,2);
ERROR 1062 (23000): Duplicate entry '1-2' for key 2
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X