2010-02-16 5 views
1

J'utilise MySQL 4.1. Certaines tables ont des entrées en double qui vont à l'encontre des contraintes.Corriger les entrées DB en double (bug MySQL)

Lorsque j'essaie de grouper des lignes, MySQL ne reconnaît pas les lignes comme étant similaires.

Exemple:

Le tableau A a une colonne "Nom" avec le proprety unique.
La table contient une ligne avec le nom 'Hach?' et une rangée avec le même nom mais un carré à la fin au lieu du '?' (Que je ne peux pas reproduire dans ce champ de texte)
« Groupe par » A sur ces 2 lignes de retour 2 rangées séparées

Cette cause plusieurs des problèmes, y compris le fait que je ne peux pas exporter et réimporter la base de données. Lors de la réimportation d'une erreur, mentionne qu'une insertion a échoué car elle enfreint une contrainte.

En théorie, je pourrais essayer d'importer, attendre la première erreur, corriger le script d'importation et la base de données d'origine, et répéter. En pratique, cela prendrait une éternité.

Existe-t-il un moyen de lister toutes les anomalies ou de forcer la base de données à revérifier les contraintes (et de lister toutes les valeurs/lignes qui vont à leur encontre)?

Je peux fournir le fichier .MYD si cela peut vous être utile.

+0

Si les deux noms ne sont pas égaux, ils ne violent pas la contrainte de duplication. Je ne suis pas ton ici. Si ce sont les données qui sont corrompues, vous devriez le corriger. – crunchdog

+0

Ils sont égaux lorsque j'exporte et réimprime les données. "Si ce sont les données qui sont corrompues, vous devriez le corriger." Comment puis-je trouver les données corrompues? Je ne peux pas rechercher un carré. –

+0

Je suis désolé si ma description est imprécise, mais le problème est vraiment bizarre. –

Répondre

0

Je suppose que c'est un MySQL 4.1 bug aléatoire. Les valeurs de Somes changent juste d'elles-mêmes sans raison particulière même si elles violent certaines contraintes de MySQL. MySQL ignore simplement ces violations.

Pour résoudre mon problème, j'écrirai un prog qui essayera de réinsérer chaque ligne de données dans le même tableau (pour être précis: un autre tableau avec les mêmes caractéristiques) et enregistrera toutes les instances de défaillances.Je vais laisser l'incident ouvert pendant un certain temps au cas où quelqu'un aurait le même problème et quelqu'un d'autre trouverait une solution plus pratique.

2

Pour afficher la liste de toutes les anomalies:

SELECT name, count(*) FROM TableA GROUP BY name HAVING count(*) > 1; 

Il y a quelques façons d'aborder la suppression des dups et votre chemin dépendra fortement du nombre de dups que vous avez.

Voir this Une question sur la façon de retirer ceux de votre table.

Voici la solution que je condition que:

-- Setup for example 
create table people (fname varchar(10), lname varchar(10)); 

insert into people values ('Bob', 'Newhart'); 
insert into people values ('Bob', 'Newhart'); 
insert into people values ('Bill', 'Cosby'); 
insert into people values ('Jim', 'Gaffigan'); 
insert into people values ('Jim', 'Gaffigan'); 
insert into people values ('Adam', 'Sandler'); 

-- Show table with duplicates 
select * from people; 

-- Create table with one version of each duplicate record 
create table dups as 
    select distinct fname, lname, count(*) 
    from people group by fname, lname 
    having count(*) > 1; 

-- Delete all matching duplicate records 
delete people from people inner join dups 
on people.fname = dups.fname AND 
    people.lname = dups.lname; 

-- Insert single record of each dup back into table 
insert into people select fname, lname from dups; 

-- Show Fixed table 
select * from people; 
+0

La première requête ne renvoie rien. 2 tables ont ce problème. Ne fonctionne pas sur eux ou eux. Dans l'un le duplicata je peux y identifier un caractère différent. Pourtant, quand il essaie d'insérer, MYSQL trouve que c'est le même caractère. Je vais mettre à jour ma description. –

+0

Avez-vous vérifié pour vous assurer que vous n'avez pas d'espace blanc dans les valeurs de vos colonnes? Je suppose que vous avez une valeur comme 'Bob' et une autre comme 'Bob'. –

+0

Ce ne sont pas des espaces. –

0

Créer une nouvelle table, sélectionnez toutes les lignes et le groupe par la clé unique (au nom de la colonne par exemple) et l'insérer dans la nouvelle table.

+0

Hmm, comment obtenir les valeurs non groupées ... – crunchdog

+0

"Grouper" ne fonctionne pas. J'ai édité ma question. –

0

Pour ce qui est ce personnage, faire la requête suivante:

SELECT HEX(Name) FROM TableName WHERE Name LIKE 'Hach%' 

Vous allez se le code ascii de ce « carré ».

Si ce personnage est 'x', vous pouvez mettre à jour comme celui-ci: (mais si cette colonne est unique, vous aurez des erreurs)

UPDATE TableName SET Name=TRIM(TRAILING 'x' FROM Name); 
+0

Oui merci. Malheureusement, j'ai des centaines de cas comme celui-là et un seul d'entre eux commence par "Hach". Comment puis-je les trouver tous? –

+0

Mais le dernier caractère (le 'carré') est-il le même? –

+0

Le carré n'est pas toujours le dernier caractère et il peut y en avoir plus de 1. Ils semblent remplacer les accents par des mots: la langue est le français et beaucoup de mots ont des accents. D'un autre côté, certains accents ne sont pas remplacés par des "carrés". –

Questions connexes