为什么Oracle的varchar排序顺序与varchar比较的行为不匹配?

问题描述:

为什么Oracle的varchar排序顺序与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; 

的SQL语句产生

B002AACD0A 
000000000000 
978123456789 

取消对WHERE-限制后,结果是

B002AACD0A 
978123456789 

我本来期望得到的结果是只978123456789因为B002AACD0A在无限制地运行查询时返回000000000000之前。

这种行为如何解释?我应该如何对varchars进行排序和比较,以便像我能用整数一样工作?

编辑:有趣的是,将限制更改为x>'B002AACD0A'时,结果为空。将其更改为x>978123456789返回B002AACD0A

I.e.比较时:

B002AACD0A > 978123456789 > 000000000000 

但排序

978123456789 > 000000000000 > B002AACD0A 

EDIT 2时:当显式地(order by NLSSORT(x,'NLS_SORT=BINARY_AI'))使用二进制排序,其结果是B002AACD0A>978123456789>000000000000和比较的行为相匹配。但我仍然不知道为什么会发生这种情况。

+0

什么版本的Oracle是你吗?我看到一些非常不同的东西...我用000000000000,978123456789,B002AACD0A跟第一个查询,然后是978123456789,B002AACD0A什么时候取消注释。我的版本是10.2.0.3.0。 – greghmerrill

+0

我正在使用10.2.0.4.0。我不惊讶地发现这种排序行为不同,可能与'NLS_SORT'设置有关(在我的情况下,它是'GERMAN')。但无论如何,我希望排序和比较在单个查询中以类似的方式表现... –

+0

9.2.0.7.0,10.2.0.1.0,11.2.0.1.0和11.1.0.6.0(不要问)全部返回000000000000,978123456789,B002AACD0A ... – Ben

彼得,

分拣的行为由NLS_SORT会话参数调节,而对于比较的行为取决于NLS_COMP参数。你必须有一个不匹配的。

我用下面的参数得到相同的结果,你这样做:

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

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

但是当两者相匹配的结果是一致的:

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

太好了!非常感谢您指出这一点,我不知道有一个名为NLS_COMP的参数。 –