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

2022-01-25 00:00:00 sorting compare oracle

类似的 SQL 语句:

An SQL statement like:

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 限制后,结果为:

After uncommenting the WHERE-restriction, the result is:

B002AACD0A
978123456789

我原以为结果只是 978123456789,因为在无限制运行查询时 B002AACD0A000000000000 之前返回.

I would have expected the result to be just 978123456789 since B002AACD0A is returned before 000000000000 when running the query without restriction.

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

How can this behavior be explained? And how am I supposed to sort and compare varchars so that they can work together like I can do with integers?

好笑,将限制改为x>'B002AACD0A'时,结果为空.将其更改为 x>978123456789 将返回 B002AACD0A.

Funny enough, when changing the restriction to x>'B002AACD0A', the result is empty. Changing it tox>978123456789 returns B002AACD0A.

即比较时:

B002AACD0A > 978123456789 > 000000000000

但是在排序的时候:

978123456789 > 000000000000 > B002AACD0A 

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

When using binary sort explicitely (order by NLSSORT(x,'NLS_SORT=BINARY_AI')), the result is B002AACD0A>978123456789>000000000000 and matches the behavior of comparison. But I still do not know why this is happening.

推荐答案

彼得,

排序的行为由 NLS_SORT 会话参数,而比较的行为取决于 NLS_COMP 参数.你肯定有不匹配的地方.

the behaviour of the sorting is regulated by the NLS_SORT session parameter, whereas the behaviour for comparisons is dependent upon the NLS_COMP parameter. You must have a mismatch.

使用以下参数,我得到的结果与您相同:

I obtain the same result as you do with the following parameters:

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

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

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

However when the two are matched the result is consistent:

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

相关文章