Cómo poner la primera letra de una frase en mayúsculas con MySQL

Normalmente los sistemas de programación y bases de datos nos proveen con una función relativamente simple cuya utilidad consiste en transformar la primera letra de una frase o palabra a mayúsculas, en php es ucfirst(), en Oracle es initcap (en el caso de transformar una frase, la función de Oracle pone cada primera palabra en mayúsculas), pero parece ser que MySQL no la tiene, por lo que tenemos que explorar un poco más y usar una solución más creativa. Pongamos como ejemplo esta frase:

mysql> SET @frase = 'bienvenidos a cambrico.net'; 
Query OK, 0 rows affected (0.00 sec) 
mysql> SELECT @frase; 
+----------------------------+ | 
@frase | 
+----------------------------+ | 
bienvenidos a cambrico.net | 
+----------------------------+ 
1 row in set (0.00 sec)

Nota: He utilizado una variable de mysql con SET y @ para hacer las siguientes operaciones un poco mas simples. Tenemos funciones como UPPER/UCASE y LOWER/LCASE para transformar a mayúsculas o minúsculas la cadena:

mysql> SELECT UPPER(@frase); 
+----------------------------+ | 
UPPER(@frase) | 
+----------------------------+ | 
BIENVENIDOS A CAMBRICO.NET | 
+----------------------------+ 
1 row in set (0.00 sec)

Y para obtener la primera letra de la cadena en mayúsculas podemos utilizar un encadenado de las siguientes funciones: LEFT, para tomar el primer caracter de la izquierda y SUBSTR para coger los restantes, de esta forma tenemos aislada la primera letra. Aplicamos UPPER para transformarla en mayúsculas y unimos la cadena de nuevo con CONCAT (si tenemos sql_mode en ANSI_QUOTES, podemos usar ||)

mysql> SELECT CONCAT(UPPER(LEFT(@frase,1)),SUBSTR(@frase,2));
+------------------------------------------------+ | 
CONCAT(UPPER(LEFT(@frase,1)),SUBSTR(@frase,2)) | 
+------------------------------------------------+ | 
Bienvenidos a cambrico.net | 
+------------------------------------------------+ 
1 row in set (0.00 sec)

Actualizo: Para hacer lo que comenta Roberto, es decir, poner todas las palabras con la primera letra en mayúscula, tienes que hacer un procedimiento o una función (esto solo es posible a partir de MySQL 5.0). Os dejo un ejemplo:

DELIMITER // 
DROP FUNCTION IF EXISTS initcap; // 
CREATE FUNCTION initcap(cadena VARCHAR(100)) RETURNS VARCHAR(100) 
BEGIN 
DECLARE pos INT DEFAULT 0; 
DECLARE tmp VARCHAR(100) DEFAULT ''; 
DECLARE result VARCHAR(100) DEFAULT ''; 
REPEAT SET pos = LOCATE(' ', cadena); 
 IF pos = 0 THEN SET pos = CHAR_LENGTH(cadena); 
 END IF; 
 SET tmp = LEFT(cadena,pos); 
 SET result = CONCAT(result, UPPER(LEFT(tmp,1)),SUBSTR(tmp,2)); 
 SET cadena = RIGHT(cadena,CHAR_LENGTH(cadena)-pos); 
UNTIL CHAR_LENGTH(cadena) = 0 END REPEAT; 
RETURN result; 
END; //

Y a partir de ahora, en la base de datos que hayamos creado la función, podremos utilizarla:

mysql> SELECT initcap(@frase); 
+----------------------------+ | 
initcap(@frase) | 
+----------------------------+ | 
Bienvenidos A Cambrico.net | 
+----------------------------+ 
1 row in set (0.00 sec)

Con una pequeña modificación de la función anterior, podemos filtrar las palabras de menos de 4 caracteres (por ejemplo), para no poner en mayúsculas la mayoría de conectores:

DELIMITER // 
DROP FUNCTION IF EXISTS initcap; // 
CREATE FUNCTION initcap(cadena VARCHAR(100)) RETURNS VARCHAR(100) 
BEGIN 
DECLARE pos INT DEFAULT 0; 
DECLARE tmp VARCHAR(100) 
DEFAULT ''; 
DECLARE result VARCHAR(100) DEFAULT ''; 
REPEAT SET pos = LOCATE(' ', cadena); 
 IF pos = 0 THEN SET pos = CHAR_LENGTH(cadena); 
 END IF; 
 SET tmp = LEFT(cadena,pos); 
 IF CHAR_LENGTH(tmp) < 4 THEN SET result = CONCAT(result, tmp); 
 ELSE SET result = CONCAT(result, UPPER(LEFT(tmp,1)),SUBSTR(tmp,2)); 
 END IF; 
 SET cadena = RIGHT(cadena,CHAR_LENGTH(cadena)-pos); 
UNTIL CHAR_LENGTH(cadena) = 0 END REPEAT; 
RETURN result; 
END; //

Y el resultado sería ligeramente distinto:

mysql> SELECT initcap(@frase); 
+----------------------------+ | 
initcap(@frase) | 
+----------------------------+ | 
Bienvenidos a Cambrico.net | 
+----------------------------+ 
1 row in set (0.00 sec) 

Comentarios

muy buen ejemplo me sirvio de algo por asi decirlo pero oye una pregunta dentro de esa misma cadena a que haces referencia con eso de

(@frase,1) a lo ultimo con ,1
(@frase,2) a lo ultimo con ,2

y como le puedo hacer para poner la segunda letra = en mayuscula

puede ser asi??
concat(upper(left(@frase,1)),(upper(left(@frase,2))),substr(@frase,3))

el resultado que quiero es este :Bienvenidos a Cambrico.net
P.D. :tomando en cuenta el ejemplo anterior
si mas que agregar gracias XD
"saludos"

He actualizado el post para incluir cómo hacer lo que comentas, es un poco más avanzado, pero usando solamente SQL no conozco otra opción.
Espero que te sirva
Un saludo!

Holas

Como siempre te escribo para dorar la píldora y nunca comento nada técnico pregunto (sabes que se más bien poco o nada de mySQL):
En caso de que cadena = 'sí', esta función, ¿no te devolvería 'sí'? Es decir, para el caso de una palabra de longitud menos a 4 no iría bien no?

Repito que no se nada de mySQL

Vale, ya lo he visto. No he dicho nada :P

Roberto, esa era precisamente la intención de la modificación en sí, que las cadenas cortas no se pusieran en mayúsculas, si las quisieras todas, no tienes más que usar la primera versión :)

Ya ya se como lo querías hacer. Decía que "no funcionaría" si la cadena sólo fuera una palabra menor de cuatro letras, una pijada ;)

Interesante....
Me sirvio de gran utilidad
Saludoj

Bueno, siempre puedes aplicar la primera función (poner en mayúscula la primera letra de la frase) sobre el resultado de la segunda (poner en mayúscula la primera letra de cada palabra mayor de 3 caracteres)... O modificar levemente la segunda para que si es el primer carácter lo ponga en mayúscula en cualquier caso.

update indice set Item= CONCAT(UPPER(SUBSTRING(Item,1,1)) ,LOWER(SUBSTRING(Item,2)));

con eso actualizarias tu tabla con todos los registros la primera letra mayuscula y el resto en minusculas

Hola Pak0s,
Tu solución es una alternativa similar a la que yo planteo inicialmente:
<code>SELECT CONCAT(UPPER(LEFT(@frase,1)),SUBSTR(@frase,2));</code>

Pero solamente pone la primera letra en mayúsculas y el resto en minúsculas, al final del artículo hay dos opciones avanzadas para mysql 5 y posteriores que permiten poner todas las palabras de una frase con la primera letra en mayúsculas.

Gracias por comentar!

GRACIAS, me super sirvió...no lo pude ejecutar desde phpmyadmin, al principio pense que era un tema de permisos, porque no soy root, pero desde el query browser de mysql funcionó PERFECTO.

ahora el SELECT initcap(text) si funciona desde phpmyadmin

Federico

Mar del Plata, Argentina

Seria bueno modificar:

SET tmp = LEFT(cadena,pos);

SET tmp = LOWER(LEFT(cadena,pos)); -- ya que el campo en la BD puede estar todo en mayúsculas..

Saludos,

DVT

Tengo un campo para introducir texto "texarea", me gustaría saber si se puede hace que devuelva las 10 primeras letras(por poner un ejemplo) en mayúsculas de los caracteres introducidos. Se que se puede hacer con la primera letra del texto, de la palabra, pero no doy con la forma de hacer que introduzcas el numero de caracteres a poner en mayúscula.
no se si se puede hacer.
Si sabéis como hacerlo, os agradezco que me digáis como.
Muchas gracias de antemano

Ejemplo de lo que pido seria.

Introduzco: holaaaaaaaaaaaaa
Me devuelve: HOLAAAaaaaaaa

dependiendo del numero de caracteres que elijas.ç
gracias

Si deseo usar esta funcion para hacer un update en la bd a un campo que se denomina nombre como tendria que hacerlo, por que usando;

update producto set Nombre=initcap(Nombre)

No me funciona la consulta les agradezco puedan darme una respuesta

Hola Pedro, te doy las gracias por el gran aporte, me ha servido mucho para cambiar los titulos y las descripciones en mi sitio http://www.onenutrition.cl/ Solo mencionar que existe un par de pequeñas correcciones encuanto a la posición de los delimiter para que funcione en phpMy Admin. Quedaría como sigue:

DROP FUNCTION IF EXISTS initcap;
DELIMITER //
CREATE FUNCTION initcap(cadena VARCHAR(255)) RETURNS VARCHAR(255)
BEGIN
DECLARE pos INT DEFAULT 0;
DECLARE tmp VARCHAR(255)
DEFAULT '';
DECLARE result VARCHAR(255) DEFAULT '';
REPEAT SET pos = LOCATE(' ', cadena);
IF pos = 0 THEN SET pos = CHAR_LENGTH(cadena);
END IF;
SET tmp = LEFT(cadena,pos);
IF CHAR_LENGTH(tmp) < 4 THEN SET result = CONCAT(result, tmp);
ELSE SET result = CONCAT(result, UPPER(LEFT(tmp,1)),SUBSTR(tmp,2));
END IF;
SET cadena = RIGHT(cadena,CHAR_LENGTH(cadena)-pos);
UNTIL CHAR_LENGTH(cadena) = 0 END REPEAT;
RETURN result;
END//
DELIMITER ;

Saludos y gracias nuevamente

Alguien sabe como hacer que una cadena de texto dejar mayúsculas despues de puntuación?
Ejemplo: "EL CARACOL VA POR EL SOL. QUE VIVA LA GRACIA"
Resultado: "El caracol va por el sol. Que viva la gracia"

Añadir nuevo comentario