2011-12-21 76 views
1

创建Oracle视图时,我有下面的语句。该声明将返回一个特定值作为MYVALUE列。创建表时Oracle查询子查询失败

(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,该视图创建失败,没有为什么

(2.1的SQLDeveloper)介绍:“失败:警告:执行有警告完成”。

而且,只是为了尝试和缩小问题,我删除了ORDER BY,并ROWNUM如下,和同样的错误发生

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

最后,我知道CS.primary_key是一个有效的参考,如我在没有问题的情况下在我的观点的其他部分使用。

任何想法,为什么引用是有效的,或者如何获得更详细的错误信息?

编辑:更新开始打开括号

编辑2:感谢迄今的回应。这里是问题的总结,我认为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

你的SQL语句和逗号的括号中有奇数个括号,它们不应该是等等。你可以发布你正在运行的所有代码来生成你的视图吗?这将有助于确定您的参考范围等。 – Ollie 2011-12-21 11:21:56

+0

什么是CS.primary_key?它从何而来? – 2011-12-21 11:34:15

+0

你可以显示整个查询,这只是一个片段? – MatBailie 2011-12-21 12:02:12

回答

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的引用在范围内。

+0

感谢您的回复。我认为CS引用在范围内,请参阅我的评论“EDIT2” – xchagger 2011-12-21 14:46:58

+0

我认为CS引用超出了范围,因为它超过了嵌套在子查询中的1个级别。你有没有试过我在答案中提出的建议,看看是否属于这种情况? – Ollie 2011-12-21 14:52:01

+0

试着只执行视图的SELECT部分​​,让我知道你得到了什么样的oracle错误信息? – Ollie 2011-12-21 15:03:50