2

我对 Oracle 10g 和COLLECT函数的使用有疑问。我今天早上才发现它的存在,但是有一个问题可以通过结合使用它来解决member of

最初我编写了如下所示的代码,它返回错误“ORA_00932:不一致的数据类型:预期的 UDT 得到 -”。

with my_tab as (
  select 1 as cola, 1 as colb from dual union all
  select 1 as cola, 2 as colb from dual union all
  select 2 as cola, 3 as colb from dual union all
  select 2 as cola, 4 as colb from dual union all
  select 3 as cola, 3 as colb from dual union all
  select 3 as cola, 4 as colb from dual union all
  select 4 as cola, 1 as colb from dual union all
  select 4 as cola, 2 as colb from dual 
)
select 
  cola, 
  colb_vals
from (
  select 
    cola, 
    collect(colb) as colb_vals
  from my_tab
  group by cola
)
where 2 member of colb_vals

我觉得这有点奇怪,因为在 Oracle 10.2.4.0 中,数据库似乎会创建一个临时系统生成的用户定义类型,并使用它。如果我删除条件 ( where 2 member of colb_vals),那么代码将运行并显示检索到的数据包括临时 UDT(名为 SYSTPblahblahblah==)。

经过一番搜索,我意识到我可以通过使用CREATE TYPE然后使用CAST函数来更改嵌套表的类型来解决这个问题。哪个有效。

这是使用CREATE TYPE number_ntt as TABLE OF NUMBER;并替换collect(colb)cast(collect(colb) as number_ntt)

然后我尝试使用在包中创建的嵌套表类型,因为我只需要此类型可用于单个包中的一个过程中的一个特定查询。我无法让它工作。

create or replace package mike_temp_pkg as
  type number_ntt is table of number;
end mike_temp_pkg;

这次替换collect(colb)cast(collect(colb) as mike_temp_pkg.number_ntt)

这导致 ORA-00932:无效数据类型。

所以我的问题实际上分为两部分:

  1. 为什么系统生成的用户定义类型适用于select 而不适用于member of

  2. 为什么类型需要是 SQL 类型而不是包中的 PL/SQL 类型?我并没有真正经常定义类型,所以这个问题可能有一个简单的答案。

4

1 回答 1

2

(1)

COLLECT 函数文档指出“要获得此函数的结果,您必须在 CAST 函数中使用它。” 我怀疑它根本不支持任何用途,除了其内容的简单转储,除非您将其转换为定义的类型。

(2)

SQL 解析器不了解或访问在 PL/SQL 块中定义的类型。即使您在 PL/SQL 代码中执行 SQL 语句,该语句也基本上被移交给一个独立的解析器(PL/SQL 变量名被绑定变量占位符替换)。

于 2010-11-24T16:03:32.923 回答