在 Oracle 10g 上创建聚合函数返回无用的错误

Posted

技术标签:

【中文标题】在 Oracle 10g 上创建聚合函数返回无用的错误【英文标题】:Creating a aggregation function on Oracle 10g returning unhelpful error 【发布时间】:2011-09-26 10:01:44 【问题描述】:

我得到了一些帮助,并被引导至 this page 和 this explanation,这应该包含一种有效的聚合方式。

建议使用 de COLLECT 函数和其他一些自定义的东西。我正在尝试与它相处,但错误消息(加上我的新手)并不是最有帮助的。

功能:

CREATE OR REPLACE TYPE t_varchar2_tab AS TABLE OF VARCHAR2(4000);

CREATE OR REPLACE FUNCTION tab_to_string (
    p_varchar2_tab  IN  t_varchar2_tab, 
    p_delimiter     IN  VARCHAR2 DEFAULT ',')
RETURN VARCHAR2 IS
  l_string     VARCHAR2(32767);
BEGIN
  FOR i IN p_varchar2_tab.FIRST .. p_varchar2_tab.LAST LOOP
    IF i != p_varchar2_tab.FIRST THEN
      l_string := l_string || p_delimiter;
    END IF;
    l_string := l_string || p_varchar2_tab(i);
  END LOOP;
  RETURN l_string;
END tab_to_string;

还有我的测试:

with my_table as
(
    select 'user1' as usrid, 'ab' as prodcode from dual union
    select 'user1' as usrid, 'bb' as prodcode from dual union
    select 'user1' as usrid, 'a' as prodcode from dual union
    select 'user2' as usrid, 'db' as prodcode from dual union
    select 'user2' as usrid, 'b' as prodcode from dual union
    select 'user2' as usrid, 'bfdd' as prodcode from dual
)
select
    usrid, 
    tab_to_string(CAST(COLLECT(prodcode) AS t_varchar2_tab)) AS codes
from
    my_table
group by
    usrid

会给我一个ORA-06553: PLS-306: wrong number or types of arguments in call to 'TAB_TO_STRING'

这几乎是我一开始提到的源代码的复制和过去,这个功能对我来说很有意义..我错过了什么?

谢谢!

[编辑] Codo 发现问题之一是 Oracle 将 'a' 理解为 char,而不是 varchar。这就把问题带到了真正的问题上。我对其进行了更新,使其集中。

【问题讨论】:

如果排除 IF i != p_varchar2_tab.FIRST THEN l_string := l_string || p_delimiter;万一;会发生什么? @FlorinGhita 没有变化......同样的错误。想法? @filippo:您的示例不再有效。如果prodcode 列中的所有值都具有相同的长度,则它使用CHAR 类型而不是VARCHAR。除此之外,您是否尝试过我昨天提议的tab_to_string(CAST(COLLECT(prodcode) AS t_varchar2_tab), ',')? (在 Oracle 11g 上,它仍然可以工作。) @Codo 对不起!错过了,重新编辑它以使其恢复正常。是的,我试过那个逗号,结果是一样的ORA-06553。我会尝试改变函数,让它只有一个参数,看看效果如何。 【参考方案1】:

由于我不太明白的原因,Oracle 认为合成表的 PRODCODE 列不是 VARCHAR2 列。如果您稍微修改 PRODCODE 值之一,它将起作用:

with my_table as
(
    select 'user1' as usrid, 'ab' as prodcode from dual union
    select 'user1' as usrid, 'b' as prodcode from dual union
    select 'user1' as usrid, 'c' as prodcode from dual union
    select 'user2' as usrid, 'd' as prodcode from dual union
    select 'user2' as usrid, 'e' as prodcode from dual union
    select 'user2' as usrid, 'f' as prodcode from dual
)
select
    usrid, 
    tab_to_string(CAST(COLLECT(prodcode) AS t_varchar2_tab)) AS codes
from
    my_table
group by
    usrid

【讨论】:

我怀疑'a' 属于CHAR 类型 唷,这太蹩脚了,但成功了。不,我遇到的错误是PLS-306: wrong number or types of arguments。对此有什么想法? 在 Oracle 11g 上,如果我将 'a' 更改为 'ab',它无需任何进一步更改即可工作。我只能猜测:可能您在 10g 中明确指定了第二个参数p_delimiter @Codo:在​​ 10g 中,COLLECT 语法无效。 @Benoit:为什么不呢?它是在 10g 中引入的(请参阅SQL reference)。

以上是关于在 Oracle 10g 上创建聚合函数返回无用的错误的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 10g 从两个不同的行和列聚合成一行

ORACLE 10g 中的三列字符串聚合

Oracle分析函数

Oracle使用简单函数

在子查询、标准或 Oracle 功能中混合聚合值和非聚合值?

Oracle 10g 监听hang处理