2009-09-17 4 views
2

J'ai besoin de remplacer plus de 20 000 noms par de nouveaux noms que j'ai créés avec le CodeID. Par exemple: Je dois mettre à jour toutes les lignes qui contiennent "dog" (qui a un CodeID de 1) avec "cat", et mettre à jour toutes les lignes qui contiennent "horse" (qui a un CodeID de 2) avec "bird" », etc.Existe-t-il un moyen rapide de mettre à jour de nombreux enregistrements dans SQL?

1er instruction SQL: UPDATE animalTable SET cDescription = "chat", où CodeID = 1

2ème instruction SQL: UPDATE animalTable SET cDescription = "oiseau", où CodeID = 2

Ces déclarations travailler, mais j'ai besoin d'un moyen plus rapide de le faire parce que j'ai plus de 20 000 noms.

Merci d'avance.

+0

Sous quelle forme se trouve la liste de CodeId | OldName | NewName? – Benjol

+0

Créer une procédure stockée. – adatapost

+0

J'ai un peu de mal à comprendre la question. Pouvez-vous s'il vous plaît fournir le schéma de vos tables ou essayer de reformuler un peu? – Evernoob

Répondre

6

C'est le moyen le plus rapide de le faire. Ou voulez-vous mettre à jour tous les enregistrements en une seule commande?

vous pouvez faire une mise à jour avec une jointure (fixe Syntaxe ... Havent utilisé celui-ci dans un certain temps)

UPDATE animalTable 
INNER JOIN CodeTable ON animalTable.CodeID = CodeTable.ID 
SET animalTable.cDescription = CodeTable.Description_1; 

Une autre option est de diviser les mises à jour en lots plus petits, cela réduira le temps de la la table est verrouillée ... Mais le temps total des mises à jour prendra plus de temps (c'est juste une amélioration de la performance estimée). Vous pouvez le faire en mettant à jour seulement certaines plages d'ID dans chaque lot.

Vous pouvez également avoir ces données dans un tableau distinct. Puisque les données ne sont pas normalisées. Déplacez-le donc c'est plus normalisé.

+0

Merci beaucoup. Je devais juste éditer quelques choses: MISE À JOUR animalTable INNER JOIN CodeTable ON animalTable.CodeID = CodeTable.ID SET animalTable.cDescription = CodeTable.Description_1; Merci encore beaucoup – sami

+0

y at-il un moyen de désactiver les fonctions de verrouillage et d'annulation de table lors d'une mise à jour? peut-être désactiver toutes les fonctionnalités supplémentaires sur l'ensemble de la DB? car ce sera le plus rapide – batman

+0

Non, ces fonctionnalités appartiennent à une base de données SQL. Vous pouvez limiter le verrouillage de la table en vous assurant que la taille de votre lot est inférieure à 5 000 lignes à chaque mise à jour. Aucune escalade de verrouillage ne se produit donc. Aussi avec une version récente de SQL, vous pouvez regarder dans la fonctionnalité "Delayed durabilité" que je ne suggérerais pas pour la production (Mais il peut vous acheter des performances sous contraintes SEVERE ... vérifier TechNet) –

1

Vous pouvez utiliser une déclaration CASE mettre à jour

MISE À JOUR animaltable SET cDescription = CAS codeID QUAND 1 ALORS 'cat' QUAND 2 ALORS 'oiseau' .... FIN

3

Vous pouvez créer une table temporaire qui contient les valeurs de traduction et mise à jour en fonction de cela.

Par exemple:

create table #TRANSLATIONS 
(
    from varchar(32), 
    to  varchar(32) 
) 

Ensuite, insérez les valeurs de traduction:

insert into #TRANSLATIONS (from,to) values ('cat','dog') 

Enfin, la mise à jour sur cette base:

update MYTABLE 
set myvalue = t.to 
where myvalue = t.from 
from MYTABLE m, 
     #TRANSLATIONS t 

(non testé, du haut de mon tête).

+0

vous avez besoin d'une clause de jointure pour ceux deux tables je pense ... – codeulike

+0

Comme je l'ai dit - non testé, du haut de ma tête. :-) La clause 'where' n'implémente-t-elle pas la jointure? – Andrew

1

Supposind vous avez un fichier comme celui-ci:

1,cat 
2,bird 
... 

Je voudrais écrire un script qui lit ce fichier et exécute une mise à jour pour chaque ligne.

En PHP:

$f = fopen("file.csv","r") 
while($row = fgetcsv($f, 1024)) { 
    $sql = "update animalTable set cDescription = '".$row[1]."' where CodeID = ".$row[0]; 
    mysql_query($sql); 
} 
fclose($f); 
+0

quel est le 1024 entre parenthèses? – sami

+0

extraite de la documentation (http://us.php.net/fgetcsv): Doit être supérieure à la plus longue ligne (en caractères) du fichier CSV (en tenant compte des caractères de fin de ligne). Il est devenu facultatif dans PHP 5. En omettant ce paramètre (ou en le mettant à 0 en PHP 5.0.4 et plus tard), la longueur de ligne maximale n'est pas limitée, ce qui est légèrement plus lent. – Keeper

+0

comment j'exécuterais ce script? désolé je suis nouveau chez MySQL. – sami

0

Ce que vous pouvez faire pour accélérer la mise à jour est uniquement les enregistrements qui ne sont pas déjà la valeur que vous souhaitez attribuer. Cette approche permet à la commande de ne mettre à jour que les enregistrements qui ne sont pas déjà 'cat'.

Avertissement: Je déteste les chats.

Questions connexes