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

时间:2011-08-25 12:56:07

标签: oracle sorting compare

SQL语句,如:

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;

收率:

B002AACD0A
000000000000
978123456789

取消注释WHERE限制后,结果为:

B002AACD0A
978123456789

我希望结果只是978123456789,因为B002AACD0A000000000000之前无限制地运行查询时会返回。{/ p>

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

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

即。比较时:

B002AACD0A > 978123456789 > 000000000000

但在排序时:

978123456789 > 000000000000 > B002AACD0A 

当明确使用二进制排序(order by NLSSORT(x,'NLS_SORT=BINARY_AI'))时,结果为B002AACD0A>978123456789>000000000000并与比较行为相匹配。但我仍然不知道为什么会这样。

1 个答案:

答案 0 :(得分:14)

彼得,

排序的行为由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