Búsquedas LIKE con acentos en SQL Server

Posted by hunk in sql server, tips on February 21, 2010

Hay ocasiones en las que tenemos que hacer búsquedas de palabras o que concuerden con el patrón en la base de datos, lo más común es usar LIKE. Por lo general esto basta, pero hay ocasiones donde en la BD se tiene acentos y no podemos decir aahhh saben que, pues deben poner los acentos bien, para estos casos la DB nos permite hacer estas búsquedas con acentos si el COLLATION es correcto, pero hay ocasiones donde no podemos cambiarlo o no es correcto para hacer búsquedas con acentos en las palabras, para eso podemos hacer el pequeño truco que explicare continuación (Esto en SQL Server), pero veamos mi ejemplo y la solución para búsqueda con acentos.

En mi app tengo un campo que es autocomplete, esto es el usuario va escribiendo  la palabra y conforme escribe la palabra le mostraba los posibles resultados de sus búsqueda, podemos hacerlo fácilmente con el siguiente plugin de JQuery (Autocomplete) todo bien hasta este momento.

La query que el sistema hace es algo como esto:

SELECT id,nombre FROM usuarios WHERE nombre LIKE '%mi_palabra%';

Parece que todo esta funcionando correctamente, me regresa los usuarios que concuerdan con la palabra, por ejemplo si la palabra es “ponce” me regresa los nombres que contienen “ponce”, pero si la búsqueda es “gomez” regresa todos los que en la DB están como “gomez”, pero no los que están como “gómez”, y al escribir “gómez” regresa todos los que están como “gómez” y no los que están como “gomez”, por tanto no esta funcionado correctamente, después de una rápida búsqueda en Google de cómo hacer búsquedas con LIKE de palabras con acento en todas de las paginas encontré que se debe modificar el collation de la tabla o la DB, de la siguiente forma:

ALTER DATABASE [nombrebasededatos] COLLATE Modern_Spanish_CI_AI

Pero en mi caso yo no puedo modificar el collation de la tabla o de la DB, yo no puedo modificar el collation de la tabla por que yo uso una vista de otra tabla y aquí es donde entra el problema, como hacer búsquedas con acentos si no podemos cambiar el collation de la tabla o de la BD por alguna circunstancia?

Durante estos años que he estado en el desarrollo de app siempre he podido darle la vuelta a este tipo de problemas, se que siempre hay una solución aun que no se tan elegante ni la mejor, siempre hay una solución.

Bueno sabemos que en las búsquedas de LIKE existen wildcarts (%,_) siempre había usado eso wildcarts en MySQL, busque la sentencia LIKE en la referencia de MSDN dado que en esta ocasión estoy usando SQL Server y encontré el wildcart [ ], este wildcart  contiene la siguiente descripció:

“Cualquier carácter individual del intervalo ([a-f]) o del conjunto ([abcdef]) que se ha especificado.”

Con el siguiente párrafo como ejemplo

“WHERE au_lname LIKE ‘[C-P]arsen’ busca apellidos de autores que terminen en arsen y empiecen por cualquier carácter individual entre C y P, como Carsen, Larsen, Karsen, etc. En las búsquedas de intervalos, los caracteres incluidos en el intervalo pueden variar, dependiendo de las reglas de ordenación de la intercalación.”

Por lo tanto podemos hacer un query como lo siguiente:

SELECT id,nombre FROM usuarios WHERE nombre LIKE '%g[oó]mez%';

Y con eso obtendríamos todos los gomez y gómez. Podemos decir que gran parte del problema ya lo tenemos resuelto, solo nos resta identificar todas aquellas letras que pueden ser acentuadas, como por ejemplo cuando identifiquemos “o”,”ò”,”ó” o “ö” hacemos el remplazo por [oóòö] o las letras “u”,”ù”,”ú” o “ü” remplazariamos por [uúùü] dependiendo el lenguaje de programación que uses será la forma de remplazo ahí entra nuestro amigo expresiones regulares,  en mi caso use preg_replace y quedo solucionado el problema, la query final que hace el sistema para gomez es:

SELECT id,nombre FROM usuarios WHERE nombre LIKE '%g[oóòö]m[eèéë]z%';

Bueno espero que esto le sirva a alguien más.

Byte

Be Sociable, Share!

3 Responses

  1. Está muy bueno, pero no entiendo el like que pones ya que en ese caso es gómez o gomez y así lo pones explicitamente en la consulta, pero poniendo solo el nombre le la columna como sería?, en donde iría los […] ?.

  2. los […] se ponen en lugar de las letras que pueden ser acentuadas, yo lo que hice fue identificar que letras pueden ser acentuadas y por cueles opciones sera remplazada,

  3. Encontré tu solución interesante la intente implementar y cree una función para remplazar mis vocales y ñ’s por sus correspondientes acentuadas, y funciono bien con palabras cortas (4-5 letras) pero no me da resultados correctos con palabras grandes o con más de 4 vocales.

    La solución que encontré entonces es agregar collate(SQL_LATIN1_GENERAL_CP1_CI_AI) en la clausula where

    SELECT id,nombre
    FROM usuarios
    WHERE nombre COLLATE SQL_LATIN1_GENERAL_CP1_CI_AI LIKE ‘%gomez%’;

    De esta manera la columna nombre es tratada como “acento insensitive” y no hay que remplazar las vocales o las “ñ”