【问题标题】:query works on oracle 12c but does not work on 11g查询适用于 oracle 12c,但不适用于 11g
【发布时间】:2018-06-09 19:32:21
【问题描述】:

我在 sql (oracle) 中有简单(但不那么聪明)的代码。 此 SQL 在 oracle 版本 12c 上可以正常工作,但在 oracle v. 11g 上存在异常。你能给我回答为什么吗?



    create table app_status (id_status int, description varchar2(20 char), range_char char(1));
    /
    create table app (id_app int,  description varchar2(20 char), range_char char(1));
    /
    insert into app_status (id_status, description,range_char) values (1,'opis 1','a');
    insert into app_status (id_status, description,range_char) values (2, 'opis 2','b');
    insert into app_status (id_status, description,range_char) values (3, 'opis 3','a');
    insert into app_status (id_status, description,range_char) values (4, 'opis 4','a');
    /
    insert into app (id_app,description,range_char) values (1,'app 1','a');
    insert into app (id_app,description,range_char) values (2,'app 2','a');
    insert into app (id_app,description,range_char) values (3,'app 3','a');
    insert into app (id_app,description,range_char) values (4,'app 4','b');
    insert into app (id_app,description,range_char) values (5,'app 5','a');
    insert into app (id_app,description,range_char) values (6,'app 6','a');
    insert into app (id_app,description,range_char) values (7,'app 7','c');
    insert into app (id_app,description,range_char) values (8,'app 8','a');
    insert into app (id_app,description,range_char) values (9,'app 9','a');
    /


    -- this query does not work on oracle v.11g
    select * from app where not exists (
           select id_status from (
                  select id_STATUS FROM APP_STATUS 
                  WHERE APP_STATUS.RANGE_CHAR = APP.RANGE_CHAR 
                  ORDER BY ID_STATUS DESC 
           ) WHERE ROWNUM=1);

我在 oracle 11g 的规范中找不到信息,为什么它不起作用。也许它在 12c 上是不正确的,但更高版本可以容忍不规则性?

【问题讨论】:

  • Oracle 11g 有什么异常?
  • select * from app where not exists (select id_status from (select id_STATUS FROM APP_STATUS WHERE APP_STATUS.RANGE_CHAR = APP.RANGE_CHAR ORDER BY ID_STATUS DESC ) WHERE ROWNUM=1) 命令行错误:23 列: 123 错误报告 - SQL 错误:ORA-00904:“APP”。“RANGE_CHAR”:无效标识符 00904。00000 -“%s:无效标识符”*原因:*操作:

标签: oracle oracle11g oracle12c


【解决方案1】:

欢迎来到 SO!

我可以在 11g 上重现您的异常:

SELECT * 
  FROM app
 WHERE NOT EXISTS ( 
                   SELECT id_status 
                     FROM (
                           SELECT id_status 
                             FROM app_status 
                            WHERE app_status.range_char = app.range_char 
                            ORDER BY id_status DESC
                           ) 
                     WHERE ROWNUM=1
                   );
Version 11.2.0.2 ORA-00904: "APP"."RANGE_CHAR": invalid identifier
Version 12.2.0.1 OK

我同意@krokodilko,查询可以而且应该简化,例如

SELECT * 
  FROM app 
 WHERE NOT EXISTS ( 
                   SELECT * 
                     FROM app_status 
                    WHERE app_status.range_char = app.range_char 
                   );

然后在 11.2 和 12.2 中运行,我仍然不明白为什么这在 11.2 中被视为错误。

有人知道详情吗?

【讨论】:

【解决方案2】:

只需注释掉一个子查询并删除 ORDER BY:

 select * from app where not exists (
  --         select id_status from (
                  select id_STATUS FROM APP_STATUS 
                  WHERE APP_STATUS.RANGE_CHAR = APP.RANGE_CHAR 
  --                ORDER BY ID_STATUS DESC 
 --          ) WHERE ROWNUM=1
 );

或者干脆删除它们:

     select * from app where not exists (
                      select id_STATUS FROM APP_STATUS 
                      WHERE APP_STATUS.RANGE_CHAR = APP.RANGE_CHAR 
     );

这个子查询在NOT EXISTS运算符中是不必要的,这个运算符检查是否存在任何行,不需要只过滤掉1条记录,也不需要排序resutset。

顺便说一句,如果你删除这个子查询和 ORDER BY,那么整个查询可能会更快,同时给出完全相同的结果。

【讨论】:

  • 是的,我知道。这不是我的查询,我只想在不修改源代码(通过休眠生成查询)的情况下迁移 oracle v.11g 上的应用程序。
  • 好吧,展示你的休眠代码和实体映射。不幸的是,如果不更改源代码,您将无法从 Oracle 12c 迁移到 11g,这是不可能的。
猜你喜欢
  • 2011-05-20
  • 1970-01-01
  • 2021-06-24
  • 2013-06-13
  • 2020-10-15
  • 2020-04-13
  • 2021-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多