2011-08-25 2 views
8

Una sentencia SQL como¿Por qué el orden varchar de Oracle no coincide con el comportamiento de la comparación varchar?

select * from (
    select '000000000000' as x from dual 
    union 
    select '978123456789' as x from dual 
    union 
    select 'B002AACD0A' as x from dual 
) /*where x>'000000000000'*/ order by x; 

produce

B002AACD0A 
000000000000 
978123456789 

Después descomentando la DONDE restricción, el resultado es

B002AACD0A 
978123456789 

lo que habría esperado que el resultado sea justo 978123456789 desde B002AACD0A se devuelve antes de 000000000000 al ejecutar la consulta sin restricción.

¿Cómo se puede explicar este comportamiento? ¿Y cómo se supone que debo ordenar y comparar los varchar para que puedan funcionar juntos como lo hago con los enteros?

EDIT: Bastante curioso, al cambiar la restricción a x>'B002AACD0A', el resultado está vacío. Cambiarlo a x>978123456789 devuelve B002AACD0A.

I.e. al comparar:

B002AACD0A > 978123456789 > 000000000000 

pero al ordenar

978123456789 > 000000000000 > B002AACD0A 

EDIT 2: Cuando se utiliza explícitamente tipo binario (order by NLSSORT(x,'NLS_SORT=BINARY_AI')), el resultado es B002AACD0A>978123456789>000000000000 y coincide con el comportamiento de comparación. Pero todavía no tengo ni idea de por qué está sucediendo esto.

+0

¿Qué versión de Oracle estás? Veo algo muy diferente ... Obtengo 000000000000, 978123456789, B002AACD0A con la primera consulta, luego 978123456789, B002AACD0A cuando el comentario está sin comentar. Mi ver es 10.2.0.3.0. – greghmerrill

+0

Estoy usando 10.2.0.4.0. No me sorprende ver que el género se comporta diferente, probablemente relacionado con la configuración 'NLS_SORT' (en mi caso, es' GERMAN'). Pero de todos modos, esperaría ordenar y comparar para comportarse de manera similar en una sola consulta ... –

+0

9.2.0.7.0, 10.2.0.1.0, 11.2.0.1.0 y 11.1.0.6.0 (no hacer preguntar) todos devuelven 000000000000, 978123456789, B002AACD0A ... – Ben

Respuesta

13

Pedro,

el comportamiento de la clasificación está regulado por el parámetro NLS_SORT sesión, mientras que el comportamiento de las comparaciones depende del parámetro NLS_COMP. Debes tener un desajuste.

puedo obtener el mismo resultado como lo hace con los siguientes parámetros:

SQL> SELECT * 
    2 FROM nls_session_parameters 
    3 WHERE parameter IN ('NLS_COMP', 'NLS_SORT'); 

PARAMETER      VALUE 
------------------------------ ---------------------------------------- 
NLS_SORT      FRENCH 
NLS_COMP      BINARY 

Sin embargo, cuando los dos se hacen coincidir el resultado es consistente:

SQL> alter session set nls_comp=LINGUISTIC; 

Session altered 

SQL> select * from (
    2 select '000000000000' as x from dual 
    3 union 
    4 select '978123456789' as x from dual 
    5 union 
    6 select 'B002AACD0A' as x from dual 
    7 ) /*where x>'000000000000'*/ order by x; 

X 
------------ 
B002AACD0A 
000000000000 
978123456789 

SQL> select * from (
    2 select '000000000000' as x from dual 
    3 union 
    4 select '978123456789' as x from dual 
    5 union 
    6 select 'B002AACD0A' as x from dual 
    7 ) where x > '000000000000' order by x; 

X 
------------ 
978123456789 
+0

¡Genial! Muchas gracias por señalar esto, no sabía que hay un parámetro llamado NLS_COMP. –

Cuestiones relacionadas