Oracle View子查询在创建表时失败

时间:2011-12-21 10:58:03

标签: sql oracle view subquery

创建Oracle视图时,我有以下声明。该语句将特定值返回为MYVALUE列。

(SELECT myval 
  FROM (SELECT myval 
          FROM mytable 
         WHERE primary_key = /*CS.primary_key*/ 12345 
         ORDER BY table_primary_key ASC) 
 WHERE ROWNUM < 2) AS MYVALUE,

内部查询可以返回多行。我只对第一条记录感兴趣,它必须由table_primary_key订购,因此使用子查询来允许ROWNUM选择。

当我在上面的当前状态下创建查询时,视图已成功创建。当我取消注释CS.primary_key并删除硬编码的12345时,视图创建失败,没有说明原因

  

(SQLDeveloper 2.1):&#34;失败:警告:执行完成并发出警告&#34;。

另外,为了尝试缩小问题范围,我删除了ORDER BYROWNUM,如下所示,并发生了同样的错误

(SELECT myval 
  FROM (SELECT myval 
          FROM mytable 
         WHERE primary_key = CS.primary_key) 
) AS MYVALUE,

最后,我知道CS.primary_key是一个有效的参考,因为我在视图的其他部分中使用而没有问题。

知道为什么引用有效,或者如何获得更详细的错误消息?

编辑:更新了开始左括号

EDIT2:感谢目前为止的回复。以下是问题的摘要,我认为CS.PRIMARY键应该在范围内,因为我在查询中的其他位置使用它。下面的代码有效,但如果我将硬编码的1替换为CS.primary_key,则会失败:

drop view myview;
drop table mytable;
drop table mytable_parent;
drop table proof_table;

-- ISSUE TABLES
create table mytable_parent ( primary_key number primary key );
create table mytable ( primary_key number, myval varchar(255), parent_primary_key number);
insert into mytable_parent values (1);
insert into mytable_parent values (2);
insert into mytable values (1, 'myval1-1', 1);
insert into mytable values (2, 'myval1-2', 1);
insert into mytable values (3, 'myval2-1', 2);

-- EXAMPLE TABLE TO PROVE CS.* WORKS
create table proof_table ( primary_key number primary key, parent_primary_key number, any_old_value varchar(255));
insert into proof_table values (1, 1, 'proofval1-1');
insert into proof_table values (2, 2, 'proofval1-2');

-- VIEW
CREATE OR REPLACE FORCE VIEW myview AS 
  SELECT 

  -- PROOF STATEMENT USING CS.primary_key SUCCESSFULLY
  (SELECT any_old_value FROM proof_table WHERE parent_primary_key IN 
    (SELECT primary_key FROM proof_table WHERE parent_primary_key = 

    -- USING CS REFERENCE, NO PROBLEM
    CS.primary_key)

  ) AS PROOF_VALUE,

  -- PROBLEM STATEMENT
  (SELECT myval FROM (SELECT myval FROM mytable 
         WHERE parent_primary_key = /*CS.primary_key*/ 1
         ORDER BY primary_key ASC) 
  WHERE ROWNUM < 2) AS MYVALUE  

  -- DEFINE CS
  FROM mytable_parent CS;

1 个答案:

答案 0 :(得分:0)

根据您提供的有限信息,我建议CS.PRIMARY_KEY超出子查询的范围。因此,当您使用文字时它会编译好,并且在必须解析对CS.PRIMARY_KEY的引用时不编译。

包括子查询中引用的表CS(使用相关标准)以检查是否是这种情况。 如果是,那么您将需要重写查询以确保CS表在其所有依赖项的范围内。

希望它有所帮助...

请参阅此链接中的详细信息:http://etutorials.org/SQL/Mastering+Oracle+SQL/Chapter+5.+Subqueries/5.4+Inline+Views/

您将看到内联视图在外部查询之前执行,并且对CS表的引用过于嵌套会导致它超出范围。

替换您进行排序的嵌套子查询:

(SELECT myval 
   FROM (SELECT myval 
           FROM mytable
          WHERE parent_primary_key = CS.primary_key
          ORDER BY primary_key ASC)
   WHERE ROWNUM < 2) AS MYVALUE

使用分析函数或其他限制行的方式,它将正常工作

这是未经测试的,但用以下代码替换上述代码:

(SELECT DISTINCT 
        FIRST_VALUE(myval) OVER (PARTITION BY parent_primary_key ORDER BY primary_key) 
   FROM mytable
  WHERE parent_primary_key = CS.primary_key) AS MYVALUE 

可能接近你想要的,对CS的引用也在范围内。