|
SQL - Ignorar Mayúsculas, Minúsculas y Acentos |
|
|
Son muchas las ocasiones en que, al hacer ordenaciones (order by) o búsquedas (where), queremos ignorar la distinción entre mayúsculas y minúsculas, así como cualquier tipo de acento.
Oracle 10g proporciona una forma bastante limpia de solucionar este problema, mediante variables del entorno idiomático de la sesión (NLS_COMP y NLS_SORT).
Hay un excelente artículo que explica todo ésto en OraFaq, en el cual me he basado para hacer esta nota técnica:
He creado en mi BD (Oracle 10g) una tabla, llamada PRUEBA_ACENTOS, donde la columna C1 contiene mayúsculas, minúsculas y acentos.
En primero lugar vamos a comprobar los valores de las variables NLS_SORT y NLS_COMP para mi sesión:
SQL> select * from nls_session_parameters where parameter in ('NLS_SORT','NLS_COMP');
PARAMETER VALUE
------------------------------ ----------------------------------------
NLS_SORT SPANISH
NLS_COMP BINARY
2 rows selected
Si hacemos una consulta sobre la tabla PRUEBA_ACENTOS, ordenando por la columna C1, observaremos que como NLS_SORT vale SPANISH, aplica la ordenación alfabética de España (y lo hace correctamente):
SQL> select c1 from prueba_acentos order by c1;
C1
--------------------
ENERO
Enero
enero
Énero
énero
junio
MAYO
Mayo
mayo
9 rows selected
Ahora vamos a comprobar que si le asginamos el valor BINARY a NLS_SORT, hará una ordenación en base al valor binario de los caracteres (y por tanto la ordenación alfabética NO es correcta):
SQL> select c1 from prueba_acentos order by c1;
C1
--------------------
ENERO
Enero
MAYO
Mayo
enero
junio
mayo
Énero
énero
9 rows selected
Por tanto, si en nuestra BD Oracle 10g, observamos que las ordenaciones "no se hacen bien", comprobaremos el valor de la variable de nuestra sesión NLS_SORT.
Vamos a ver qué otros valores podemos darle a NLS_SORT. Si, independiente del idioma, queremos hacer una ordenación "ingorando mayúsculas" (o "case insensitive"), podemos usar el valor BINARY_CI; en cuyo caso (para ordenar) asigna el mismo valor a mayúsculas y minúsculas, pero NO hace lo mismo para los acentos:
SQL> alter session set nls_sort=binary_ci;
SQL> select c1 from prueba_acentos order by c1;
C1
--------------------
enero
ENERO
Enero
junio
Mayo
MAYO
mayo
Énero
énero
9 rows selected
Si queremos que además de ignorar mayúsculas y minúsculas, lo haga también con los acentos, debemos asignar a NLS_SORT el valor BINARY_AI
SQL> alter session set nls_sort=binary_ai;
SQL> select c1 from prueba_acentos order by c1;
C1
--------------------
énero
Enero
ENERO
Énero
enero
junio
Mayo
mayo
MAYO
9 rows selected
Ahora vamos a ver qué ocurre con las búsquedas (comparaciones en el where). El comportamiento de las búsquedas viene regulado por el valor de la variable NLS_COMP, de la sesión correspondiente, en combinación con NLS_SORT. Hasta el momento, NLS_COMP continúa valiendo BINARY, pues no lo hemos cambiado. Si hacemos una búsqueda de las filas cuya columna C1 empieza por "E", veremos q sólo devuelve dos, pues está distinguiendo mayúsculas de minúsculas, así como acentos:
SQL> select c1 from prueba_acentos where c1 like 'E%';
C1
--------------------
Enero
ENERO
2 rows selected
Si queremos que al hacer la búsqueda NO distinga entre mayúsculas y minúsculas, ni acentos; asignaremos el valor LINGUISTIC a NLS_COMP (además de asegurarnos de que NLS_SORT=BINARY_AI):
SQL> alter session set nls_comp=linguistic;
SQL> select c1 from prueba_acentos where c1 like 'E%';
C1
--------------------
énero
Enero
ENERO
Énero
enero
5 rows selected
Nota: también podemos usar la función TRANSLATE, pero en este caso estamos introduciendo código nuevo (yo no lo haría si dispongo de Oracle 10g). Ejemplo:
SQL> select c1, TRANSLATE(UPPER(c1), 'ÁÉÍÓÚÀÈÌÒÙÄËÏÖÜÂÊÎÔÛ', 'AEIOUAEIOUAEIOUAEIOU') from prueba_acentos;
C1 TRANSLATE(UPPER(C1),'ÁÉÍÓÚÀÈÌÒÙÄËÏÖÜÂÊÎÔÛ','AEIOUAEIOUAEIOUAEIOU')
-------------------- ------------------------------------------------------------------
énero ENERO
Enero ENERO
ENERO ENERO
Énero ENERO
enero ENERO
Mayo MAYO
mayo MAYO
MAYO MAYO
junio JUNIO
9 rows selected
|
|
Última modificación ( 26.08.2011 )
|