MySQL "bonne" façon d'insérer une ligne si elle n'est pas trouvée, ou le mettre à jour si elle est trouvée
Très souvent, j'ai envie d'exécuter une requête sur un de mes utilisateurs où je veux une ligne stockée et associées à cet utilisateur, dans un 1-de-1 de la relation. Donc, disons (c'est juste un exemple au hasard), que j'ai une table qui garde la trace d'un utilisateur de la voiture, avec quelques infos sur la voiture. Chaque utilisateur peut avoir 0 ou 1 voitures. Si l'utilisateur n'a pas de voiture, il n'y a aucune entrée dans la table pour cet utilisateur.
table de voitures (de nouveau, juste un exemple):
id, user_id, car_make, car_model
Donc, quand j'ai mise à jour de ce tableau, je finis toujours par faire quelque chose comme ceci (pseudo-code):
result = SELECT * FROM cars WHERE user_id=5
if (num_rows(result)>0){
UPDATE cars SET car_make='toyota', car_model='prius' WHERE user_id=5
}else{
INSERT INTO cars (user_id, car_make, car_model) VALUES (5, 'toyota', 'prius')
}
Comment puis-je faire cela dans un élégant déclaration de travaux "automatiquement"? Qu'advient-il si, dans un autre processus, la ligne est SUPPRIMÉE entre le SELECT et UPDATE? Mon instruction de mise à JOUR échoue où l'instruction INSERT devriez avoir exécuté. Et je sens que j'ai besoin de faire deux semblables (mais différentes) instructions pour accomplir la même chose! Ce que j'ai besoin est une déclaration qui va m'assurer que les données que je veux existe dans la table, surtout lorsque je veux seulement 1 ligne qui répond à mes besoins. Par exemple, il pourrait être quelque chose comme (ce qui est totalement composée de cours):
MAKE SURE A ROW IN cars WHERE user_id=5 IS SET WITH car_make='toyota', car_model='prius'
De cette façon, si user_id de 5 existe déjà, il sera mis à jour, sinon, il sera inséré. Aussi, si j'ai changé les exigences, par exemple-à-dire que chaque utilisateur peut avoir zéro, un ou une des voitures de car_make, alors je pourrais préciser que:
MAKE SURE A ROW IN cars WHERE user_id=5 AND car_make='toyota' IS SET WITH car_model='prius'
J'espère que ma question a du sens! Comment puis-je améliorer cette base insérez-si-pas-de trouver ou de mettre à jour-si-trouvé opération qui vient si souvent? Merci pour toute aide!
source d'informationauteur DivideByHero
Vous devez vous connecter pour publier un commentaire.
Vous pouvez utiliser "REMPLACER DANS" ou "INSÉRER... SUR UN DOUBLE DE LA CLÉ DE MISE À JOUR". Je crois que le deuxième est ce que vous voulez, mais il existe des situations où le REMPLACER DANS la pratique.
De mon autre Débordement de Pile répondre:
Si vous voulez faire cela en une seule instruction, je vous conseille d'utiliser le
INSERT ... ON DUPLICATE KEY UPDATE
syntaxe, comme suit:La première
INSERT
instruction est exécutée si il n'existe pas d'enregistrement avec la spécifié de la valeur de clé (clé primaire ou unique). Si un enregistrement existe déjà, à la suite deUPDATE
déclaration (someothervalue = 3
) est exécutée.C'est pris en charge dans toutes les versions de MySQL. Pour plus d'info, voir le Manuel de Référence de MySQL page pour
INSÉRER ... SUR un DOUBLE de la CLÉ de mise à JOUR
Cela s'appelle un UPSERT (JUSQU'date ou dansSERT). Il y a un certain nombre de questions à ce sujet, vous pouvez le rechercher. Voir Wikipedia
EDIT: MySQL 4.1+ prend en charge INSATE (INSert ou updMANGÉ), ce qui devrait vous obtenez la même chose, aussi longtemps que vous avez une clé primaire. Manuel MySQL
Je pense que c'est plus facile de passer partout. Essayez d'insérer, puis sur mise à jour.
MySQL spécifiquement a une clause SUR le DOUBLE de la CLÉ'
INSÉRER DANS les voitures (les champs) VALUES (valeurs) SUR le DOUBLE de la CLÉ de mise à JOUR ...
Bien sûr, cela vous oblige à avoir une bonne unique installation de clés.
Dans Oracle vous avez Fusion.
Aucune idée sur MySql, mais le terme peut vous donner quelque chose d'autre à la recherche.
un exemple de la façon dont je l'ai utilisé SUR un DOUBLE de la CLÉ de mise à JOUR:
INSÉREZ DANS la base de registre (nom, valeur) VALUES ('" . $key . "', '" . $val . "') SUR un DOUBLE de la CLÉ de mise à JOUR de la valeur= '" . $val . "'"