2011-08-25 12 views
8

Một câu lệnh SQL nhưTại sao thứ tự sắp xếp varchar của Oracle không phù hợp với hành vi của so sánh 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; 

mang

B002AACD0A 
000000000000 
978123456789 

Sau uncommenting WHERE-hạn chế, kết quả là

B002AACD0A 
978123456789 

tôi dự kiến ​​sẽ có kết quả là chỉ 978123456789 từ B002AACD0A được trả về trước 000000000000 khi chạy truy vấn mà không bị hạn chế.

Làm cách nào để giải thích hành vi này? Và làm thế nào tôi phải sắp xếp và so sánh varchars để họ có thể làm việc cùng nhau như tôi có thể làm với số nguyên?

EDIT: Vui đủ, khi thay đổi giới hạn thành x>'B002AACD0A', kết quả sẽ trống. Thay đổi nó thành x>978123456789 trả về B002AACD0A.

I.e. khi so sánh:

B002AACD0A > 978123456789 > 000000000000 

nhưng khi sắp xếp

978123456789 > 000000000000 > B002AACD0A 

EDIT 2: Khi sử dụng loại nhị phân explicitely (order by NLSSORT(x,'NLS_SORT=BINARY_AI')), kết quả là B002AACD0A>978123456789>000000000000 và phù hợp với hành vi của so sánh. Nhưng tôi vẫn không có một đầu mối tại sao điều này đang xảy ra.

+0

gì phiên bản của oracle là bạn không? Tôi thấy một cái gì đó rất khác nhau ... Tôi nhận được 000000000000, 978123456789, B002AACD0A với truy vấn đầu tiên, sau đó 978123456789, B002AACD0A khi không được chú ý. Phiên bản của tôi là 10.2.0.3.0. – greghmerrill

+0

Tôi đang sử dụng 10.2.0.4.0. Tôi không ngạc nhiên khi thấy kiểu xử lý khác nhau, có thể liên quan đến cài đặt 'NLS_SORT' (trong trường hợp của tôi, đó là' GERMAN'). Nhưng dù sao, tôi sẽ mong đợi sắp xếp và so sánh với hành xử theo cách tương tự trong một truy vấn ... –

+0

9.2.0.7.0, 10.2.0.1.0, 11.2.0.1.0 và 11.1.0.6.0 (không yêu cầu) tất cả trở lại 000000000000, 978123456789, B002AACD0A ... – Ben

Trả lời

13

Peter,

hành vi của các phân loại được quy định bởi tham số NLS_SORT phiên, trong khi hành vi để so sánh phụ thuộc vào các tham số NLS_COMP. Bạn phải có sự không phù hợp.

tôi có được kết quả tương tự như bạn làm với các thông số sau:

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

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

Tuy nhiên khi hai được kết hợp kết quả là phù hợp:

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

Tuyệt vời! Cảm ơn rất nhiều vì đã chỉ ra điều này, tôi không biết rằng có một tham số có tên là NLS_COMP. –