Oracle COLLECT 函数和类型

发布于 2024-10-03 20:27:51 字数 1726 浏览 5 评论 0原文

我在 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: invalid datatype。

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

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

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

I've got an issue with Oracle 10g and the use of the COLLECT function. I only found out about its existence this morning but have a problem which could be solved by using it in association with the member of condition.

Initially I wrote the code shown below, which came back with the error "ORA_00932: inconsistent datatypes: expected UDT got -".

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

I found this a little strange since in Oracle 10.2.4.0, it seems that the database will create a temporary system generated user defined type, and use that. If I remove the condition, (where 2 member of colb_vals) then the code will run and show the data retrieved included the temporary UDT (named SYSTPblahblahblah==).

After a bit more searching, I realised that I could solve this be using CREATE TYPE and then using the CAST function to change the type of the nested table. Which worked.

This was using CREATE TYPE number_ntt as TABLE OF NUMBER; and replacing collect(colb) with cast(collect(colb) as number_ntt)

I then tried to use a nested table type created in a package, since I only need this type to be available for one particular query in one procedure in a single package. And I couldn't get it to work.

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

And this time replacing collect(colb) with cast(collect(colb) as mike_temp_pkg.number_ntt)

This resulted in ORA-00932: invalid datatype.

So the question I have is in two parts really:

  1. Why does the system generated user
    defined type work for the select
    but not for the member of?

  2. Why does the type need to be a SQL
    type and not a PL/SQL type in a
    package? I don't really define types
    that often so there might be a
    simple answer to that question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

深海夜未眠 2024-10-10 20:27:51

(1)

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

(2)

SQL 解析器不知道或无法访问 PL/SQL 块中定义的类型。即使当您在 PL/SQL 代码内部执行 SQL 语句时,该语句本质上也会被传递给独立的解析器(PL/SQL 变量名称被绑定变量占位符替换)。

(1)

The COLLECT function documentation states "To get the results of this function you must use it within a CAST function." I suspect it simply is not designed to support any uses, except a simple dump of its contents, unless you cast it to a defined type.

(2)

The SQL parser has no knowledge of or access to types defined in PL/SQL blocks. Even when you execute a SQL statement inside of PL/SQL code, the statement is essentially handed off to an independent parser (with PL/SQL variable names replaced by bind variable placeholders).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文