2012-03-02 1 views
55

Je sais que vous pouvez utiliser ON DUPLICATE KEY UPDATE mettre à jour une certaine valeur s'il y a un record pour cette clé déjà,Y at-il un moyen d'utiliser ON DUPLICATE KEY pour mettre à jour tout ce que je voulais insérer?

Je peux le faire:

INSERT INTO `tableName` (`a`,`b`,`c`) VALUES (1, 2, 3) 
ON DUPLICATE KEY UPDATE `a`=1, `b`=2, `c`=3 

Mais comment puis-je faire cela sans avoir à écrire sortir les colonnes et les valeurs deux fois?

+0

http://stackoverflow.com/questions/294661/what-is-the-best-way-to-insert-and-update-a-single-row-table-in-mysql –

Répondre

70

Unfortunately not.

Vous pouvez obtenir à mi-chemin par ne pas avoir à répéter la valeur:

INSERT INTO `tableName` (`a`,`b`,`c`) VALUES (1,2,3) 
    ON DUPLICATE KEY UPDATE `a`=VALUES(`a`), `b`=VALUES(`b`), `c`=VALUES(`c`); 

Mais vous avez toujours à la liste des colonnes.

+0

@Neal: Vos valeurs à insérer sont complexes, je suppose? –

+0

:-(http://chat.stackoverflow.com/transcript/message/2819869#2819869 – Neal

+0

Il ne semble pas fonctionner ^^^ – Neal

28

utilisation REPLACE INTO

Le sens de REPLACE INTO est que si le nouveau disque présente de nouvelles valeurs clés, il sera inséré comme nouveau disque.

Si le nouvel enregistrement a des valeurs de clé qui correspondent à un enregistrement préexistant, la violation de clé sera ignorée et le nouvel enregistrement remplacera l'enregistrement préexistant.

+5

Ah, cela pourrait être bien meilleur, il est à noter que tous les champs non donnés explicitement dans la requête seront par défaut, cependant, ce qui diffère évidemment du comportement «ON DUPLICATE KEY UPDATE». –

+40

Note: avec 'REPLACE', si la clé de l'enregistrement correspond à quelque chose qui existe déjà, ** l'ancienne ligne (s!) Sera supprimée, et la nouvelle sera insérée **.Cela peut être un gros problème si vous vous trompez avec des déclencheurs ou des contraintes de clés étrangères. – cHao

+2

Bon point. Vous risquez des réactions en chaîne importantes, je suppose. –

6

S'il est utile, je fait une requête pour éviter d'écrire à la main la dernière partie de la « Duplicate » requête, pour les versions> = 5.0:

SELECT GROUP_CONCAT(CONCAT(COLUMN_NAME,"=values(", COLUMN_NAME,")") SEPARATOR ", ") FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'database_name' AND TABLE_NAME = 'table_name'; 

et sa sortie est la suivante:

a=values(a), b=values(b), c=values(c), d=values(d) 

sur une table qui comporte des colonnes a, b, c et d, de sorte que vous pouvez ajouter à la première partie de la requête:

INSERT INTO `tableName` (`a`,`b`,`c`, `d`) VALUES (1,2,3,4) ON DUPLICATE KEY UPDATE a=values(a), b=values(b), c=values(c), d=values(d) 

MISE À JOUR: Pour une très longue liste de colonnes, vous pouvez voir une sortie tronquée, vous pouvez utiliser cette déclaration avant que la requête ci-dessus (merci Uncle iroh):

SET SESSION group_concat_max_len = 1000000; 
+1

Aime ça. Parfois, j'ai besoin de cela avant votre requête très utile. SET SESSION group_concat_max_len = 1000000; –

Questions connexes