2011-08-25 11 views
8

Un'istruzione SQL comePerché l'ordinamento varchar di Oracle non corrisponde al comportamento del confronto 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 

Dopo decommentando WHERE-restrizione, il risultato è

B002AACD0A 
978123456789 

mi sarei aspettato il risultato di essere solo 978123456789 dal B002AACD0A viene restituito prima di 000000000000 durante l'esecuzione della query senza restrizioni.

Come si spiega questo comportamento? E come posso ordinare e confrontare i varchar in modo che possano lavorare insieme come posso fare con gli interi?

MODIFICA: Abbastanza divertente, quando si modifica la restrizione su x>'B002AACD0A', il risultato è vuoto. La modifica a x>978123456789 restituisce B002AACD0A.

I.e. quando si confrontano:

B002AACD0A > 978123456789 > 000000000000 

ma quando sono ordinati

978123456789 > 000000000000 > B002AACD0A 

EDIT 2: Usando ordinamento binario esplicitamente (order by NLSSORT(x,'NLS_SORT=BINARY_AI')), il risultato è B002AACD0A>978123456789>000000000000 e corrisponde al comportamento di paragone. Ma ancora non ho idea del perché questo sta accadendo.

+0

Quale versione di Oracle stai? Vedo qualcosa di molto diverso ... Ottengo 000000000000, 978123456789, B002AACD0A con la prima query, quindi 978123456789, B002AACD0A quando non commentato. La mia versione è 10.2.0.3.0. – greghmerrill

+0

Sto usando 10.2.0.4.0. Non mi sorprende vedere il tipo che si comporta in modo diverso, probabilmente correlato all'impostazione 'NLS_SORT' (nel mio caso, è' TEDESCO'). Comunque, mi aspetterei che sort e paragonarsi si comportino in modo simile all'interno di una singola query ... –

+0

9.2.0.7.0, 10.2.0.1.0, 11.2.0.1.0 e 11.1.0.6.0 (non chiedere) tutti restituiscono 000000000000, 978123456789, B002AACD0A ... – Ben

risposta

13

Peter,

il comportamento del l'ordinamento è regolato dal parametro NLS_SORT della sessione, mentre il comportamento per i confronti dipende dal parametro di NLS_COMP. Devi avere una mancata corrispondenza.

ottengo lo stesso risultato come si fa con i seguenti parametri:

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

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

Tuttavia quando i due sono abbinati il ​​risultato è coerente:

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

Ottimo! Grazie mille per averlo indicato, non sapevo che esistesse un parametro chiamato NLS_COMP. –