2014-05-14 5 views
1

J'essaie une conversion simple - une colonne mysql varchar qui contient des valeurs de longitude (par exemple "-1.234" à -1.234) pour améliorer l'optimisation.MySQL varchar au numéro

J'ai lu et lu à ce sujet et rien ne fonctionne, la dernière tentative était:

UPDATE latlng_data SET lng_copy = CAST(lng AS DECIMAL(6,4)); 

rencontré:

Error Code: 1366. Incorrect decimal value: '' for column '' at row -1 

colonne cible, créée pour récupérer les erreurs est:

FLOAT(6,4) 

and null allowed. 

Pourquoi les messages d'erreur mysql sont-ils si inutiles?

Après 'Dognose' avis (ci-dessous) J'ai utilisé:

UPDATE latlng_data SET lng='999.9999' where lng='';-- to give invalid lng in this case 

augmentent alors le champ de données de copie (dans le but de le renommer Orig) puis:

UPDATE latlng_data SET lng_copy = CAST(lng AS DECIMAL(7,4)); 

cela semble être nécessaire dans MySQL Workbench cmd timesout mais en utilisant:

show full processlist; 

il montre encore que la course - alors voici le meilleur moniteur est cmd.

+1

'CAST ('- 1.234' AS décimal (6,4)) ' Fonctionne très bien sur mon extrémité s'assurer que toutes les valeurs dans lng_copy ont des valeurs et peuvent convertir en décimal (6,4) ressemble proprement à l'un d'eux est '' – JasonSec

+0

comme dit @JasonSec. voir: http://dev.mysql.com/doc/refman/5.6/fr/cast-functions.html Dupe possible: http://stackoverflow.com/questions/18705119/mysql-how-to-convert-varchar- latitude-longitude-à-décimal-champs –

+0

'UPDATE latlng_data SET lng_copy = lng * 1' * ...cache – dognose

Répondre

0

case est cochée avec:

SELECT * FROM t31data_happyenergy.latlng_data where lng_copy <> CAST(lng AS DECIMAL(7,4)); 

qui retourne maintenant aucun résultat et peut être mieux optimisé car tous sont numériques, avec de mauvaises données pleinement évaluées pour une longitude.

Je recommande également d'utiliser une fenêtre de commande mysql car la plupart des applications expirent lorsque des requêtes étendues sont utilisées avec ces grandes données.

Donc, fondamentalement, le processus est allé [VÉRIFIER TOUJOURS ENTRE CHAQUE QUERY que je suis arrivé LAZY ET RECOMMENCER Dû COMME UNE REQUETE A TORT):

-- convert all mostly read only tables to myisam: 
-- dropped old lat and lng after checking same data by 

SELECT count(*) FROM latlng_postcode where CAST(lat AS DECIMAL(7,4))!=latcopy; 
SELECT count(*) FROM latlng_postcode where CAST(lng AS DECIMAL(7,4))!=lngcopy; 

ALTER TABLE `latlng_postcode` 
CHANGE COLUMN `latcopy` `lat` FLOAT(7,4) NULL DEFAULT NULL, 
CHANGE COLUMN `lngcopy` `lng` FLOAT(7,4) NULL DEFAULT NULL; 

-- then index (are these the best settings ?? 
ALTER TABLE `latlng_postcode` 
DROP INDEX `pcode` , 
ADD INDEX `pcode` USING BTREE (`postcode`(5) ASC), 
ADD INDEX `lat` USING BTREE (`lat`(4) ASC), 
ADD INDEX `lng` USING BTREE (`lng`(4) ASC); 
+0

Merci à tous pour la réponse, il semble que le dognose était sur la bonne voie et conduit à vérifier si des lignes existent qui ont une chaîne vide - ce qui semble avoir été le cas quand il a échoué. – Datadimension

0

Je pense que la façon la plus simple de convertir des nombres dans MySQL est d'utiliser la conversion silencieuse. C'est-à-dire, utilisez la chaîne dans une opération arithmétique et toutes les erreurs de conversion sont ignorées. Une chaîne sans numéro est interprété comme 0:

UPDATE latlng_data 
    SET lng_copy = lng + 0.0; 

Here est une documentation pertinente.

EDIT:

Si vous êtes préoccupé correspondant à des valeurs que correctes, puis vérifier le format de la chaîne

WHERE lng rlike '[0-9]+[.]?[0-9]*' 
+0

Merci, mais dans ce cas, il en résulte une valeur de longitude valide où il manquait un. Cela cacherait malheureusement une erreur d'être détecté. – Datadimension