tablas - ¿Hay una manera simple de convertir datos de MySQL en Title Case?
porque se dañan las tablas en mysql (11)
Tengo una tabla MySQL donde todos los datos en una columna se ingresaron en MAYÚSCULAS, pero necesito convertirlos a Title Case, con reconocimiento de "pequeñas palabras" similares al guión de Daring Fireball Title Case .
Encontré esta excelente solución para transformar cadenas en minúsculas, pero la función Title Case parece haber quedado fuera de mi versión de MySQL. ¿Hay una manera elegante de hacer esto?
¡Cortejar! No soy útil con SQL en absoluto; Este es el método que funcionó para mí:
- Exporte la tabla como un archivo de texto en formato .sql.
- Abra el archivo en Textmate (que ya tenía a mano).
- Seleccione las filas con datos MAYÚSCULAS.
- Elija "Convertir" del menú "Texto", y seleccione "a la Portada".
Encuentre y reemplace cada instancia de:
INSERT INTO `Table` (`Col1`, `Col2`, `Etc`, ...) VALUES
con los valores minúsculos correctos.
- Importa la tabla de nuevo a la base de datos.
- Use la
UPDATE table SET colname=LOWER(colname);
para restablecer los valores en minúsculas para las columnas que deberían estar minúsculas.
La razón por la que no intenté usar Textmate antes fue porque no pude encontrar la manera de convertir una sola columna en Title Case sin arruinar los otros datos, pero este método parece funcionar. Gracias por su orientación y apoyo!
El caso definitivo para buscar tal función está en la documentación .
Desafortunadamente, tienes las funciones LOWER () y UPPER (), pero no Title Case. Su mejor opción sería declarar su propia función que se divide en espacios, ignora sus pequeñas palabras y hace un UPPER en el primer carácter de cada palabra restante.
Esta funciona para mí.
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
Esto funciona para mí en My 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 ;
La respuesta dependerá del tipo de datos de la columna, es decir, nombres de personas, nombres de lugares, títulos de libros, etc. Si está buscando una solución SQL, lo haría en varias actualizaciones, por ejemplo:
- La secuencia inicial es: "PARA MATAR A UN PELUCHE MOCKINGBIRD"
- Convertir a mayúsculas iniciales: "Matar a un ruiseñor"
- Convierta palabras pequeñas en minúsculas si no comienzan la cadena: "Matar a un ruiseñor"
Mi solución para el caso adecuado simple:
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
Úselo como:
SELECT proper_case("JOHN DOE");
Salida:
John Doe
Si necesita lanzar acrónimos personalizados y otros patrones de capitalización personalizados en la mezcla, he generalizado la respuesta 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 ;
Básicamente consiste en una función de sustitución de palabras insensible a mayúsculas y minúsculas y una función para poner en mayúscula la primera letra de cada palabra y realizar algunas transformaciones para palabras específicas.
Espero que sea útil para alguien.
Usé algo como esto
UPDATE `tablename`
SET `fieldname` = CONCAT(UCASE(SUBSTRING(`fieldname`,1,1)),'''', LCASE(SUBSTRING(`fieldname`,2,LENGTH(`fieldname`))))
Nota: Esto solo convertirá el primer carácter en mayúscula. y el resto del valor a minúsculas.
puedes hacer esto con concat (), substring () y length (), pero solo puedo ver que funciona para una palabra. ¿Hay alguna razón específica por la que no puedas hacer esto en el código de tu aplicación, en lugar de mysql?
umm algo como esto puede funcionar
UPDATE table_name SET `col_name`= CONCAT( UPPER( SUBSTRING( `col_name`, 1, 1 ) ) , LOWER( SUBSTRING( `col_name` FROM 2 ) ) );
Editar
Eureka! Literalmente mi primera función SQL. Sin garantía ofrecida. Haga una copia de seguridad de sus datos antes de usarlos. :)
Primero, defina la siguiente función:
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 ;
Esto reducirá todas las apariciones de palabra en str.
Luego defina esta función propia modificada:
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 ;
Uso
Verifique que funcione como se espera:
SELECT tcase(title) FROM table;
Úselo:
UPDATE table SET title = tcase(title);
Fuente: http://www.artfulsoftware.com/infotree/queries.php?&bw=1070#122