为什么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
和比较的行为相匹配。但我仍然不知道为什么会发生这种情况。
答
彼得,
分拣的行为由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的参数。 –
什么版本的Oracle是你吗?我看到一些非常不同的东西...我用000000000000,978123456789,B002AACD0A跟第一个查询,然后是978123456789,B002AACD0A什么时候取消注释。我的版本是10.2.0.3.0。 – greghmerrill
我正在使用10.2.0.4.0。我不惊讶地发现这种排序行为不同,可能与'NLS_SORT'设置有关(在我的情况下,它是'GERMAN')。但无论如何,我希望排序和比较在单个查询中以类似的方式表现... –
9.2.0.7.0,10.2.0.1.0,11.2.0.1.0和11.1.0.6.0(不要问)全部返回000000000000,978123456789,B002AACD0A ... – Ben