部分选择中不使用NLS_SORT

时间:2015-04-27 16:01:57

标签: oracle oracle12c

我已将nls_sort参数设置为BINARY_AI以执行排序不区分大小写。我在系统和会话中设置它:

alter session set nls_sort='BINARY_AI';
alter system set nls_sort='BINARY_AI' scope=spfile;

此查询的排序正确无误:

SELECT s."Id", s."Label" FROM "Software" s ORDER BY s."Label"

    Id   |  Label
_______________________
10218    | Able2Extract
10217    | AVS Video Recorder

如果我使用此查询执行部分选择:

SELECT * FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY "Label" ASC) AS MYROW, subSelect.* 
    FROM (
        SELECT s."Id", s."Label" FROM "Software" s
    ) subSelect
) WHERE MYROW BETWEEN 1 AND 100

排序不区分大小写:

    Id   |  Label
_______________________
10217    | AVS Video Recorder
10218    | Able2Extract

错误在哪里?

1 个答案:

答案 0 :(得分:1)

您没有在第二个查询中指定排序顺序,因为您没有ORDER BY子句,因此结果以不确定的顺序返回。

您的MYROW值是根据NLS排序顺序分配的,但您只能使用它来过滤,而不是对结果集进行排序。您可以再次使用它:

SELECT "Id", "Label" FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY "Label" ASC) AS MYROW, subSelect.* 
    FROM (
        SELECT s."Id", s."Label" FROM "Software" s
    ) subSelect
) WHERE MYROW BETWEEN 1 AND 100
ORDER BY MYROW;

或按标签订购:

SELECT "Id", "Label" FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY "Label" ASC) AS MYROW, subSelect.* 
    FROM (
        SELECT s."Id", s."Label" FROM "Software" s
    ) subSelect
) WHERE MYROW BETWEEN 1 AND 100
ORDER BY "Label";

使用ROW_NUMBER时,您也不需要两级子查询,就像ROWNUM一样;你可以简化一下:

SELECT "Id", "Label" FROM (
    SELECT s."Id", s."Label",
      ROW_NUMBER() OVER (ORDER BY s."Label" ASC) AS MYROW
    FROM "Software" s
) WHERE MYROW BETWEEN 1 AND 100
ORDER BY "Label";

内部查询返回MYROW的期望值(比较SQL小提琴,for 'binary'for 'binary_ai')。但那是使用11.2.0.2,它也适用于11.2.0.3。我目前没有12c实例可供测试,但其他人可能能够验证那里的行为。

如果您在12.1.0.1中看到MYROW的错误值,则可能会点击错误18353141或16934803,这两个错误都在右侧区域中显示,并且在12.1.0.2补丁集发行说明中提到。查看My Oracle Support了解详情。