Y at-il un moyen simple de convertir des données MySQL en cas de titre?
-
19-09-2019 - |
Question
J'ai une table MySQL où toutes les données dans une colonne ont été saisies en MAJUSCULES, mais je dois convertir pour titre de cas, avec la reconnaissance des « petits mots se apparente » à la balise Daring Fireball Titre scénario cas.
J'ai trouvé cette excellente solution pour transformer les chaînes en minuscules, mais la fonction de cas Titre semble avoir été laissé sur ma version de MySQL. Y at-il une façon élégante de le faire?
La solution 7
Woo! Je ne suis pas à portée de main avec SQL du tout; Voici la méthode qui a fonctionné pour moi:
- Exporter la table sous forme de fichier texte au format .sql.
- Ouvrez le fichier dans TextMate (que j'avais déjà à portée de main).
- Sélectionnez les lignes avec des données MAJUSCULES.
- Choisissez « Convertir » dans le menu « Texte » et sélectionnez « pour casse de titre ».
-
Rechercher et remplacer chaque instance:
INSERT INTO `Table` (`Col1`, `Col2`, `Etc`, ...) VALUES
avec les valeurs correctes minuscules.
- Importer la table de nouveau dans la base de données.
- Utilisez
UPDATE table SET colname=LOWER(colname);
pour réinitialiser les valeurs minuscules pour les colonnes qui doivent être en minuscules.
La raison pour laquelle je ne l'ai pas essayer d'utiliser TextMate avant était que je ne pouvais pas comprendre comment convertir une seule colonne à titre de cas sans ruiner les autres données, mais cette méthode semble fonctionner. Merci pour vos conseils et votre soutien!
Autres conseils
Modifier
Eureka! Littéralement ma première fonction SQL. Aucune garantie offerte. Sauvegardez vos données avant d'utiliser. :)
D'abord, définir la fonction suivante:
DROP FUNCTION IF EXISTS lowerword;
SET GLOBAL log_bin_trust_function_creators=TRUE;
DELIMITER |
CREATE FUNCTION lowerword( str VARCHAR(128), word VARCHAR(5) )
RETURNS VARCHAR(128)
DETERMINISTIC
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE loc INT;
SET loc = LOCATE(CONCAT(word,' '), str, 2);
IF loc > 1 THEN
WHILE i <= LENGTH (str) AND loc <> 0 DO
SET str = INSERT(str,loc,LENGTH(word),LCASE(word));
SET i = loc+LENGTH(word);
SET loc = LOCATE(CONCAT(word,' '), str, i);
END WHILE;
END IF;
RETURN str;
END;
|
DELIMITER ;
Cela réduira toutes les occurrences du mot dans str.
Définissez ensuite cette fonction appropriée modifiée:
DROP FUNCTION IF EXISTS tcase;
SET GLOBAL log_bin_trust_function_creators=TRUE;
DELIMITER |
CREATE FUNCTION tcase( str VARCHAR(128) )
RETURNS VARCHAR(128)
DETERMINISTIC
BEGIN
DECLARE c CHAR(1);
DECLARE s VARCHAR(128);
DECLARE i INT DEFAULT 1;
DECLARE bool INT DEFAULT 1;
DECLARE punct CHAR(17) DEFAULT ' ()[]{},.-_!@;:?/';
SET s = LCASE( str );
WHILE i <= LENGTH( str ) DO
BEGIN
SET c = SUBSTRING( s, i, 1 );
IF LOCATE( c, punct ) > 0 THEN
SET bool = 1;
ELSEIF bool=1 THEN
BEGIN
IF c >= 'a' AND c <= 'z' THEN
BEGIN
SET s = CONCAT(LEFT(s,i-1),UCASE(c),SUBSTRING(s,i+1));
SET bool = 0;
END;
ELSEIF c >= '0' AND c <= '9' THEN
SET bool = 0;
END IF;
END;
END IF;
SET i = i+1;
END;
END WHILE;
SET s = lowerword(s, 'A');
SET s = lowerword(s, 'An');
SET s = lowerword(s, 'And');
SET s = lowerword(s, 'As');
SET s = lowerword(s, 'At');
SET s = lowerword(s, 'But');
SET s = lowerword(s, 'By');
SET s = lowerword(s, 'For');
SET s = lowerword(s, 'If');
SET s = lowerword(s, 'In');
SET s = lowerword(s, 'Of');
SET s = lowerword(s, 'On');
SET s = lowerword(s, 'Or');
SET s = lowerword(s, 'The');
SET s = lowerword(s, 'To');
SET s = lowerword(s, 'Via');
RETURN s;
END;
|
DELIMITER ;
Utilisation
Vérifiez qu'il fonctionne comme prévu:
SELECT tcase(title) FROM table;
Utilisez:
UPDATE table SET title = tcase(title);
Source: http://www.artfulsoftware.com/infotree/ queries.php? & pc = 1070 # 122
hmm quelque chose comme cela peut fonctionner
UPDATE table_name SET `col_name`= CONCAT( UPPER( SUBSTRING( `col_name`, 1, 1 ) ) , LOWER( SUBSTRING( `col_name` FROM 2 ) ) );
Si vous avez besoin de jeter des acronymes personnalisés et d'autres modèles de capitalisation personnalisée dans le mélange que j'ai généralisé la réponse de hobodave:
DELIMITER |
CREATE FUNCTION replaceword( str VARCHAR(128), word VARCHAR(128) )
RETURNS VARCHAR(128)
DETERMINISTIC
BEGIN
DECLARE loc INT;
DECLARE punct CHAR(27) DEFAULT ' ()[]{},.-_!@;:?/''"#$%^&*<>';
DECLARE lowerWord VARCHAR(128);
DECLARE lowerStr VARCHAR(128);
IF LENGTH(word) = 0 THEN
RETURN str;
END IF;
SET lowerWord = LOWER(word);
SET lowerStr = LOWER(str);
SET loc = LOCATE(lowerWord, lowerStr, 1);
WHILE loc > 0 DO
IF loc = 1 OR LOCATE(SUBSTRING(str, loc-1, 1), punct) > 0 THEN
IF loc+LENGTH(word) > LENGTH(str) OR LOCATE(SUBSTRING(str, loc+LENGTH(word), 1), punct) > 0 THEN
SET str = INSERT(str,loc,LENGTH(word),word);
END IF;
END IF;
SET loc = LOCATE(lowerWord, lowerStr, loc+LENGTH(word));
END WHILE;
RETURN str;
END;
|
DELIMITER ;
DELIMITER |
CREATE FUNCTION tcase( str VARCHAR(128) )
RETURNS VARCHAR(128)
DETERMINISTIC
BEGIN
DECLARE c CHAR(1);
DECLARE s VARCHAR(128);
DECLARE i INT DEFAULT 1;
DECLARE bool INT DEFAULT 1;
DECLARE punct CHAR(27) DEFAULT ' ()[]{},.-_!@;:?/''"#$%^&*<>';
SET s = LCASE( str );
WHILE i <= LENGTH( str ) DO
BEGIN
SET c = SUBSTRING( s, i, 1 );
IF LOCATE( c, punct ) > 0 THEN
SET bool = 1;
ELSEIF bool=1 THEN
BEGIN
IF c >= 'a' AND c <= 'z' THEN
BEGIN
SET s = CONCAT(LEFT(s,i-1),UCASE(c),SUBSTRING(s,i+1));
SET bool = 0;
END;
ELSEIF c >= '0' AND c <= '9' THEN
SET bool = 0;
END IF;
END;
END IF;
SET i = i+1;
END;
END WHILE;
SET s = replaceword(s, 'a');
SET s = replaceword(s, 'an');
SET s = replaceword(s, 'and');
SET s = replaceword(s, 'as');
SET s = replaceword(s, 'at');
SET s = replaceword(s, 'but');
SET s = replaceword(s, 'by');
SET s = replaceword(s, 'for');
SET s = replaceword(s, 'if');
SET s = replaceword(s, 'in');
SET s = replaceword(s, 'n');
SET s = replaceword(s, 'of');
SET s = replaceword(s, 'on');
SET s = replaceword(s, 'or');
SET s = replaceword(s, 'the');
SET s = replaceword(s, 'to');
SET s = replaceword(s, 'via');
SET s = replaceword(s, 'RSS');
SET s = replaceword(s, 'URL');
SET s = replaceword(s, 'PHP');
SET s = replaceword(s, 'SQL');
SET s = replaceword(s, 'OPML');
SET s = replaceword(s, 'DHTML');
SET s = replaceword(s, 'CSV');
SET s = replaceword(s, 'iCal');
SET s = replaceword(s, 'XML');
SET s = replaceword(s, 'PDF');
SET c = SUBSTRING( s, 1, 1 );
IF c >= 'a' AND c <= 'z' THEN
SET s = CONCAT(UCASE(c),SUBSTRING(s,2));
END IF;
RETURN s;
END;
|
DELIMITER ;
Pour l'essentiel, il se compose d'un mot insensible à la casse remplacer la fonction et une fonction de capitaliser la première lettre de chaque mot et effectuer quelques transformations pour des mots spécifiques.
Hope son utile à quelqu'un.
Ma solution pour de simples cas approprié:
CREATE FUNCTION `proper_case`(str varchar(128)) RETURNS varchar(128)
BEGIN
DECLARE n, pos INT DEFAULT 1;
DECLARE sub, proper VARCHAR(128) DEFAULT '';
if length(trim(str)) > 0 then
WHILE pos > 0 DO
set pos = locate(' ',trim(str),n);
if pos = 0 then
set sub = lower(trim(substr(trim(str),n)));
else
set sub = lower(trim(substr(trim(str),n,pos-n)));
end if;
set proper = concat_ws(' ', proper, concat(upper(left(sub,1)),substr(sub,2)));
set n = pos + 1;
END WHILE;
end if;
RETURN trim(proper);
END
Utilisez-le comme:
SELECT proper_case("JOHN DOE");
Sortie:
John Doe
je quelque chose comme ça
UPDATE `tablename`
SET `fieldname` = CONCAT(UCASE(SUBSTRING(`fieldname`,1,1)),'', LCASE(SUBSTRING(`fieldname`,2,LENGTH(`fieldname`))))
Note: Ceci ne convertir le premier caractère en majuscules. et reste de la valeur en minuscules.
vous pouvez le faire avec concat (), substring (), et la longueur () mais je ne peux que le voir travailler pour un seul mot. Y at-il une raison particulière pour laquelle vous ne pouvez pas le faire dans le code de votre application, au lieu de MySQL?
Celui-ci fonctionne pour moi.
UPDATE `suburbs`
SET title2 = CONCAT_WS(' ',
CONCAT(UPPER(LEFT(SUBSTRING_INDEX(title, ' ',1),1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',1),2))),
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',2),LENGTH(SUBSTRING_INDEX(title, ' ',1)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',2),3 + LENGTH(SUBSTRING_INDEX(title, ' ',1))))),
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',3),LENGTH(SUBSTRING_INDEX(title, ' ',2)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',3),3 + LENGTH(SUBSTRING_INDEX(title, ' ',2))))),
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',4),LENGTH(SUBSTRING_INDEX(title, ' ',3)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',4),3 + LENGTH(SUBSTRING_INDEX(title, ' ',3))))),
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',5),LENGTH(SUBSTRING_INDEX(title, ' ',4)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',5),3 + LENGTH(SUBSTRING_INDEX(title, ' ',4))))),
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',6),LENGTH(SUBSTRING_INDEX(title, ' ',5)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',6),3 + LENGTH(SUBSTRING_INDEX(title, ' ',5))))),
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',7),LENGTH(SUBSTRING_INDEX(title, ' ',6)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',7),3 + LENGTH(SUBSTRING_INDEX(title, ' ',6))))),
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',8),LENGTH(SUBSTRING_INDEX(title, ' ',7)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',8),3 + LENGTH(SUBSTRING_INDEX(title, ' ',7))))),
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',9),LENGTH(SUBSTRING_INDEX(title, ' ',8)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',9),3 + LENGTH(SUBSTRING_INDEX(title, ' ',8))))),
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',10),LENGTH(SUBSTRING_INDEX(title, ' ',9)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',10),3 + LENGTH(SUBSTRING_INDEX(title, ' ',9))))),
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',11),LENGTH(SUBSTRING_INDEX(title, ' ',10)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',11),3 + LENGTH(SUBSTRING_INDEX(title, ' ',10))))))
WHERE 1
Cela fonctionne pour moi dans mon SQL 5.0
DELIMITER |
CREATE FUNCTION CamelCase(str VARCHAR(8000))
RETURNS VARCHAR(8000)
BEGIN
DECLARE result VARCHAR(8000);
SET str = CONCAT(' ',str,' ');
SET result = '';
WHILE LENGTH(str) > 1 DO
SET str = SUBSTR(str,INSTR(str,' ')+1,LENGTH(str));
SET result = CONCAT(result,UPPER(LEFT(str,1)), LOWER(SUBSTR(str,2,INSTR(str,' ') - 1)) ) ;
SET str = SUBSTR(str,INSTR(str,' '),LENGTH(str));
END WHILE;
RETURN result;
END
|
DELIMITER ;
Le cas définitif à rechercher une telle fonction est dans la documentation .
Malheureusement, vous avez des fonctions BAS () et supérieur (), mais aucun cas de titre. Votre meilleur pari serait de déclarer votre propre fonction qui divise sur les espaces, ne tient pas compte de vos petits mots, et fait une plus haute sur le premier caractère de chaque mot restant.
La réponse va dépendre de ce type de données est dans la colonne, à savoir est-il des personnes, noms de lieux, titres de livres, etc. Si vous êtes à la recherche d'une solution SQL, je le ferais dans plusieurs mises à jour, par exemple:
- Chaîne initiale est: "To Kill a Mockingbird"
- Convertir en majuscule initiale: « To Kill A Mockingbird "
- Convertir petits mots en minuscules si ils ne commencent pas à la chaîne: « Pour Kill a Mockingbird "