NLS_SORT 部分未使用 select

NLS_SORT is not used in partial select

我已将 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:

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

哪里出错了?

您没有在第二个查询中指定排序顺序,因为您没有 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";

内部查询 returns MYROW 的预期值(比较 SQL Fiddle、for 'binary' and 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 了解详情。