【问题标题】:ORA-00932 if collection used in recursive CTE in where clauseORA-00932 如果集合在 where 子句中的递归 CTE 中使用
【发布时间】:2020-06-04 21:55:39
【问题描述】:

我有带有集合类型列的递归 CTE(这里使用sys.ku$_vcnt,因为它是内置的,任何集合类型都可以重现问题)。当 where 子句中 CTE 的递归部分使用集合列时,查询失败并出现 ORA-00932: inconsistent datatypes: expected UDT got SYS.KU$_VCNT 错误。

这是最小化的示例,在实际情况下,集合内容在where 子句中进行检查。任何收集的出现似乎都足以使查询失败 - 例如非空检查,如下例所示:

with r (l, dummy_coll, b) as (
  select 1 as l, sys.ku$_vcnt(), null from dual
  union all
  select l + 1
       , r.dummy_coll
       , case when r.dummy_coll is not null then 'not null' else 'null' end as b
  from r
  where l < 5 and r.dummy_coll is not null
)
select * from r;

如果从where 子句中删除and r.dummy_coll is not null,则查询成功。 select 子句中出现集合没有问题(b 列显示集合实际上不为空)。

为什么它不起作用以及如何强制 Oracle 从 where 子句中的先前递归级别查看集合列?

在 Oracle 11 和 Oracle 18 (dbfiddle) 中重现。

谢谢!

【问题讨论】:

    标签: oracle collections oracle11g recursive-query ora-00932


    【解决方案1】:

    是的,这对我来说就像一个错误。标量选择似乎是一种解决方法。这对你有用吗?

    SQL> with r (l, dummy_coll, b) as (
      2    select 1 as l, sys.ku$_vcnt(), null from dual
      3    union all
      4    select l + 1
      5         , r.dummy_coll
      6         , case when r.dummy_coll is not null then 'not null' else 'null' end as b
      7    from r
      8    where l < 5 and ( select r.dummy_coll from dual ) is not null
      9  )
     10  select * from r;
    
    L,DUMMY_COLL,B
    1,KU$_VCNT(),
    2,KU$_VCNT(),not null
    3,KU$_VCNT(),not null
    4,KU$_VCNT(),not null
    5,KU$_VCNT(),not null
    

    【讨论】:

    • 效果很好,谢谢!同时我提出了解决方法where l &lt; 5 and (cast(multiset(select * from table(r.dummy_coll)) as sys.ku$_vcnt) is not null,它也可以,你的更简单。
    • 由于实际情况是something not member of r.dummy_coll(由于接受的答案已成功替换为something not member of (select r.dummy_coll from dual)),因此替代解决方案也是something not in (select column_value from table(r.dummy_coll))。几周后我发现了它。
    猜你喜欢
    • 2021-12-23
    • 1970-01-01
    • 2018-07-07
    • 2019-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    相关资源
    最近更新 更多