【问题标题】:Table or view does not exist - Oracle complains about a comma rather than an actual table or view name表或视图不存在 - Oracle 抱怨逗号而不是实际的表或视图名称
【发布时间】:2011-04-12 14:19:32
【问题描述】:

我以前从未见过这个...我有一个这样开始的查询:

with q1 as
     (select a.V_ID, a.D_ID, a.C_ID,
               case when a.percent > 0 THEN 'Y' ELSE 'N' end L_val,
               a.C_val
       from ab_a_table a
       where a.C_ID =  '00000003' -- '00000007' --  test values
             and a.B_VAL = '6010001'
             and a.Q = '11234567')
select case
           when ... /* rest of query omitted */

当我尝试运行它时,Oracle 抱怨说 table or view does not exist。但是 它在第 3 行突出显示了 ',',而不是实际的表/视图名称:

当 a.percent > 0 THEN 'Y' ELSE 'N' end L_VAL 时, * 第 3 行的错误: ORA-00942: 表或视图不存在

我省略的查询的其余部分相当长且复杂——如有必要,我将对其进行清理并发布——现在我只想说这个错误仅在我添加引用q1 的第三个子查询时才开始。事实上,似乎我可以删除 3 个子查询中的任何一个,整个事情都会执行(尽管结果不正确),所以感觉就像我遇到了某种 Oracle 错误而不是纯 SQL 错误。有趣的是,我可以将q1 的主体作为独立查询运行,并且这样做没有问题。只有当我运行整个查询时,它才会抱怨q1 中的逗号后面的逗号。

有没有人经历过这种情况?

(使用 Oracle 10g)。


编辑:尝试添加 AS 关键字。现在的结果是:

a.perc_fault > 0 THEN 'Y' ELSE 'N' end AS L_VAL, a.C_VAL 的情况 * 第 3 行的错误: ORA-00942: 表或视图不存在

看起来星号在相同的位置,但在 V 下方,因为单词 L_VAL 已移动了 3 个字符。很奇怪……

【问题讨论】:

  • 这有点远,但尝试将有问题的行更改为“case when a.percent > 0 THEN 'Y' ELSE 'N' end AS L_VAL” - 换句话说,添加“AS”关键字。
  • 显然错误超出了公用表表达式,因此您应该发布完整的语句。我强烈认为突出显示只是指向错误的位置 - 无论是什么工具进行突出显示,因为“Oracle”不会进行错误突出显示
  • @FrustratedWithFormsDesigner:你的补丁级别是多少?在 10.2.0.4 补丁集中有一个与 ORA-00942 和 WITH 子句相关的错误修复:5130732。它有点模糊,但看起来优化器搞砸了,所以我相信添加或删除子查询可能会有所作为。 (错误报告中的示例也指向第 3 行)。
  • @FrustratedWithFormsDesigner:Metalink 注释和错误不建议任何解决方法。您可以尝试提示,但不知道有什么帮助 - 吮吸它的情况,我害怕。 (PUSH_SUBQ、UNNEST 或 NO_UNNEST 可能......)。否则,您将不得不重新设计查询以避免连接。唯一发生的另一件事是使函数返回一个引用游标,并用其中的游标替换子查询。不管你做什么都有潜在的性能影响。
  • 如果问题是 WITH 子句错误 Alan Poole 描述了尝试将 WITH 子句更改为内联视图。或者创建一个实际的视图。

标签: sql oracle oracle10g ora-00942


【解决方案1】:

假设您遇到了 Oracle 错误并且无法修补数据库,您可以尝试将子查询移动到函数中。不完全确定这是否可行,并假设您的 PL/SQL 版本在一个包中,或者有一个可以添加功能的可用版本:

在包装规格中:

type q1_rec is record(
    d_id ab_a_table.v_id%TYPE,
    v_id ab_a_table.d_id%TYPE,
    c_id ab_a_table.c_id%TYPE,
    l_val char(1),
    c_val ab_a_table.c_val%TYPE);
type q1_arr is varray(9999); -- assuming you can pick a max size
function q1 return q1_arr pipelined;
pragma restrict_references(q1, wnds);

在包体中:

function q1 return q1_arr pipelined is
    cursor c is
        select a.V_ID, a.D_ID, a.C_ID,
               case when a.percent > 0 THEN 'Y' ELSE 'N' end L_val,
               a.C_val
       from ab_a_table a
       where a.C_ID =  '00000003' -- '00000007' --  test values
             and a.B_VAL = '6010001'
             and a.Q = '11234567');
begin
    for r in c loop
        pipe row(r);
    end loop;
end;

然后在您的主查询中将子查询替换为table(q1())

使用引用游标或嵌套表格可能会更简洁一些,但需要在包之外构建表格类型,我猜你想根据你关于使用视图的额外对象评论来避免这种情况。

【讨论】:

  • 我可能会朝着这个方向前进,但需要一些时间来弄清楚如何将事情分开......
  • 我的代码并不完全相同,但想法相似——我将巨型查询的子查询分成 3 个游标,然后将整个内容包装在一个包含大约十几行的函数中以控制哪个查询运行。它很难看,但它可以工作,因为该函数存在于我的脚本中,我什至不必编译任何包! :)
【解决方案2】:

我不确定我是否遇到过 Oracle 错误 5130732,但感觉确实如此。无论如何,我重写了这样的查询:

select case ... 
from
    (select ...
     from (select a.V_ID, a.D_ID, a.C_ID,
               case when a.percent > 0 THEN 'Y' ELSE 'N' end L_val,
               a.C_val
       from ab_a_table a
       where a.C_ID =  '00000003' -- '00000007' --  test values
             and a.B_VAL = '6010001'
             and a.Q = '11234567') q1,  <other tables>
    where ...) subquery1,
    (select ...
     from (select a.V_ID, a.D_ID, a.C_ID,
               case when a.percent > 0 THEN 'Y' ELSE 'N' end L_val,
               a.C_val
       from ab_a_table a
       where a.C_ID =  '00000003' -- '00000007' --  test values
             and a.B_VAL = '6010001'
             and a.Q = '11234567') q1,  <other tables>
    where ...) subquery2,
    (select ...
     from (select a.V_ID, a.D_ID, a.C_ID,
               case when a.percent > 0 THEN 'Y' ELSE 'N' end L_val,
               a.C_val
       from ab_a_table a
       where a.C_ID =  '00000003' -- '00000007' --  test values
             and a.B_VAL = '6010001'
             and a.Q = '11234567') q1,  <other tables>
    where ...) subquery3, <other tables>
where....

是的,我在每个使用它的子查询中都包含了q1 的副本,现在一切正常。一个真实的视图也可以,但这更容易(从政治上讲,即 - 没有对需要进行分析的环境的代码提升请求,没有关于数据库中后期添加对象的会议等......)


更新

现在我已经将查询添加到我的 PL/SQL 脚本中,Oracle 给了我ORA-00600 [qcscpqbTxt], [600],这似乎与 Oracle 错误 #5765958.... * sigh *... 任何人都可以建议解决方法?我没有 metalink 访问权限(好吧,我可能会通过 DBA,如果这能以某种方式引起他们的注意)。

【讨论】:

  • 您的 DBA 可能已经知道 ORA-600 将在警报日志中。 5765968 似乎指的是 ANSI 连接和/或绑定变量;猜测您的 PL/SQL 版本将有变量而不是硬编码值。也有对 5532110 的引用,但看不到任何详细信息。也看不到提到的解决方法。目前尚不清楚它是否仍然是导致问题的子查询,但我想似乎很可能。我可能仍然会考虑在您的 PL/SQL 中返回一个 ref 游标的本地函数,如果只是希望优化器不会试图太聪明的话。你也试过这里的提示吗?
  • @Alex Poole:今天早些时候,DBA 向我发送了错误的跟踪文件。他说他可能会开始联系 Oracle,但我会先尝试使用 code-mixed-with-query 来分离。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-22
  • 1970-01-01
  • 2021-09-13
相关资源
最近更新 更多