Sql Oracle中listagg的替代方案?

Sql Oracle中listagg的替代方案?,sql,oracle,varchar,clob,Sql,Oracle,Varchar,Clob,Listag是Oracle 11.2中引入的一个函数!现在,这个函数正在困扰我们allot,我们正在从MySQL迁移到Oracle,我们有一个查询: SELECT p_id, MAX(registered) AS registered, listagg(MESSAGE, ' ') within GROUP (ORDER BY registered) AS MESSAGE FROM umm_parent_id_remarks_v m GROUP BY

Listag是Oracle 11.2中引入的一个函数!现在,这个函数正在困扰我们allot,我们正在从MySQL迁移到Oracle,我们有一个查询:

SELECT
    p_id,
    MAX(registered) AS registered,
    listagg(MESSAGE, ' ') within GROUP (ORDER BY registered) AS MESSAGE
  FROM
    umm_parent_id_remarks_v m
  GROUP BY
    m.p_id;
据我们所知,它在MySQL中运行良好 让我们烦恼的是,甲骨文公司将VARCAR退回,而不是我们需要的CLOB! 文本很大,我们确实需要它是CLOB

这就是我想做的

创建CLOB类型的CLOB_T表

然后创建函数

create or replace
function listaggclob (t in clob_t) 
  return clob
as 
  ret clob := '';
  i   number;
begin
  i := t.first;
  while i is not null loop
    if ret is not null then
      ret := ret || ' ';
    end if;
    ret := ret || t(i);
    i := t.next(i);
  end loop;
  return ret;
end;
现在,如果我运行它:

  SELECT
        p_id,
        MAX(registered) AS registered,
        listaggclob(cast(collect (MESSAGE) as clob_t)) MESSAGE
      FROM
        umm_parent_id_remarks_v m
      GROUP BY
        m.p_id;
我明白了

ORA-22814:属性或元素值大于类型中指定的值

有什么解决办法吗

感谢您使用或。

您可能需要查看


显示了不同的字符串聚合技术。它们包括一个用户定义聚合函数的示例。

您可以通过使用
MULTISET
而不是
COLLECT
来解决
ORA-22814
错误:

SELECT
    p_id,
    MAX(registered) AS registered,
    listaggclob(cast(multiset(
        select MESSAGE
        from umm_parent_id_remarks_v
        where umm_parent_id_remarks_v.p_id = m.p_id
    ) as clob_t)) MESSAGE
  FROM
    umm_parent_id_remarks_v m
  GROUP BY
    m.p_id;

Wem_CONCAT为我工作

SELECT replace(WMSYS.WM_CONCAT(myTable.name), ',', ';')
FROM myTable
GROUP BY myTable.id

我用一个“replace”来包装它,以指定与WM_CONCAT(',')使用的项目分隔符(';')不同的项目分隔符

使用xmlAgg,示例如下所示:

SELECT RTRIM(XMLAGG(XMLELEMENT(E,colname,',').EXTRACT('//text()') ORDER BY colname).GetClobVal(),',') AS LIST
FROM tablename;
这将返回clob值,因此无需创建自定义函数。

--创建Clobe类型-- 创建或替换类型“MSCONCATIMPL_CLOB”作为对象( 结果字符串CLOB, 分隔符VARCHAR2(10)

)); / --创建Clobe类型主体--

创建或替换类型主体“MSCONCATIMPL\u CLOB”为 静态函数odciaggregateinitialize(io_srccontext IN OUT msconcatimpl_clob)返回编号 是 开始 io_srccontext:=msconcatimpl_clob( 无效的 无效的 ); io_srccontext.delimiter:=''; 返回odciconst.success; 结束ODCIaggregate初始化

MEMBER FUNCTION odciaggregateiterate (
    self IN OUT msconcatimpl_clob,
    value   IN CLOB
) RETURN NUMBER
    IS
BEGIN
    IF
        value IS NOT NULL
    THEN
        IF
            self.resultstring IS NULL
        THEN
            self.resultstring := self.resultstring || value;
        ELSE
            self.resultstring := self.resultstring
             || self.delimiter
             || value;
        END IF;
    END IF;

    RETURN odciconst.success;
END odciaggregateiterate;

MEMBER FUNCTION odciaggregateterminate (
    self            IN msconcatimpl_clob,
    o_returnvalue   OUT CLOB,
    i_flags         IN NUMBER
) RETURN NUMBER
    IS
BEGIN
    o_returnvalue := self.resultstring;
    RETURN odciconst.success;
END odciaggregateterminate;

MEMBER FUNCTION odciaggregatemerge (
    self IN OUT msconcatimpl_clob,
    i_ctx2   IN msconcatimpl_clob
) RETURN NUMBER
    IS
BEGIN
    IF
            self.resultstring IS NULL
        AND
            i_ctx2.resultstring IS NOT NULL
    THEN
        self.resultstring := i_ctx2.resultstring;
    ELSIF
        self.resultstring IS NOT NULL
    AND
        i_ctx2.resultstring IS NOT NULL
    THEN
        self.resultstring := self.resultstring
         || self.delimiter
         || i_ctx2.resultstring;
    END IF;

    RETURN odciconst.success;
END odciaggregatemerge;
结束; /

--创建Clobe函数--

创建或替换函数ms_concat_clob(输入VARCHAR2)返回clob 并行_启用 使用msconcatimpl_clob进行聚合;
/

我确实编写了我自己的函数,并且更新了我的问题,请再次检查我的问题,谢谢。我不知道为什么会出现这种错误-可能值得将其作为一个新问题发布,这样会让更多的人看到。这是一组很好的选项。有关于哪个更快的信息吗?我没有关于性能的信息。我想这主要取决于总体执行计划以及它们如何融入该执行计划。因此,不同的查询可能会有所不同。请注意,WM_CONCAT在12c、Express Edition和任何未安装Workspace Manager的数据库中都不可用。目前不支持也没有文档记录。Xmlagg速度非常慢。是否有快速的替代方案?
MEMBER FUNCTION odciaggregateiterate (
    self IN OUT msconcatimpl_clob,
    value   IN CLOB
) RETURN NUMBER
    IS
BEGIN
    IF
        value IS NOT NULL
    THEN
        IF
            self.resultstring IS NULL
        THEN
            self.resultstring := self.resultstring || value;
        ELSE
            self.resultstring := self.resultstring
             || self.delimiter
             || value;
        END IF;
    END IF;

    RETURN odciconst.success;
END odciaggregateiterate;

MEMBER FUNCTION odciaggregateterminate (
    self            IN msconcatimpl_clob,
    o_returnvalue   OUT CLOB,
    i_flags         IN NUMBER
) RETURN NUMBER
    IS
BEGIN
    o_returnvalue := self.resultstring;
    RETURN odciconst.success;
END odciaggregateterminate;

MEMBER FUNCTION odciaggregatemerge (
    self IN OUT msconcatimpl_clob,
    i_ctx2   IN msconcatimpl_clob
) RETURN NUMBER
    IS
BEGIN
    IF
            self.resultstring IS NULL
        AND
            i_ctx2.resultstring IS NOT NULL
    THEN
        self.resultstring := i_ctx2.resultstring;
    ELSIF
        self.resultstring IS NOT NULL
    AND
        i_ctx2.resultstring IS NOT NULL
    THEN
        self.resultstring := self.resultstring
         || self.delimiter
         || i_ctx2.resultstring;
    END IF;

    RETURN odciconst.success;
END odciaggregatemerge;