简体   繁体   English

Oracle中listagg的替代方案?

[英]alternative to listagg in Oracle?

listagg is a function introduced in Oracle 11.2! listagg是Oracle 11.2中引入的一个函数! now this function is bugging us allot, we are migrating from MySQL to Oracle and we have this query: 现在这个功能正在困扰我们分配,我们正在从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;

is works fine in MySQL as far as we know what bugging us is under Oracle it returns VARCAR and not CLOB as we need! 只要我们知道在Oracle下面有什么烦恼它就会返回VARCAR而不是我们需要的CLOB! the text is huge and we do need it to be CLOB ! 文字很大,我们确实需要它是CLOB

here is what I tried to do! 这是我试图做的!

create a CLOB_T table of CLOB Type! 创建一个CLOB类型的CLOB_T表!

then create the function 然后创建功能

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;

now if I run it: 现在,如果我运行它:

  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;

I get 我明白了

ORA-22814: attribute or element value is larger than specified in type ORA-22814:属性或元素值大于类型中指定的值

is there any solution for it? 它有什么解决方案吗?

thanks you 谢谢

WM_CONCAT worked for me. WM_CONCAT为我工作。

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

I wrapped it with a "replace" to specify a different item separator (';') from the one used by WM_CONCAT (','). 我用“替换”包装它以指定与WM_CONCAT(',')使用的分隔符不同的项目分隔符(';')。

Use xmlAgg, example is shown below: 使用xmlAgg,示例如下所示:

SELECT RTRIM(XMLAGG(XMLELEMENT(E,colname,',').EXTRACT('//text()') ORDER BY colname).GetClobVal(),',') AS LIST
FROM tablename;

This will return clob value and so no need to create custom function. 这将返回clob值,因此无需创建自定义函数。

You might want to look at user-defined aggregate functions . 您可能希望查看用户定义的聚合函数

Differnt string aggregation techniques are shown here . 这里显示不同的字符串聚合技术。 They include an example for user-defined aggregate functions. 它们包含用户定义的聚合函数的示例。

You can solve the ORA-22814 error by using MULTISET instead of COLLECT : 您可以使用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;

-- Creating Clobe Type -- CREATE OR REPLACE TYPE "MSCONCATIMPL_CLOB" AS OBJECT ( resultstring CLOB, delimiter VARCHAR2(10), - 创建Clobe类型 - 创建或替换类型“MSCONCATIMPL_CLOB”作为对象(结果字符串CLOB,分隔符VARCHAR2(10),

STATIC FUNCTION odciaggregateinitialize ( io_srccontext IN OUT msconcatimpl_clob ) RETURN NUMBER,

MEMBER FUNCTION odciaggregateiterate (
    self IN OUT msconcatimpl_clob,
    value   IN CLOB
) RETURN NUMBER,

MEMBER FUNCTION odciaggregateterminate (
    self            IN msconcatimpl_clob,
    o_returnvalue   OUT CLOB,
    i_flags         IN NUMBER
) RETURN NUMBER,

MEMBER FUNCTION odciaggregatemerge (
    self IN OUT msconcatimpl_clob,
    i_ctx2   IN msconcatimpl_clob
) RETURN NUMBER

); ); / -- Creating Clobe Type Body -- / - 创建Clobe Type Body -

CREATE OR REPLACE TYPE BODY "MSCONCATIMPL_CLOB" IS STATIC FUNCTION odciaggregateinitialize ( io_srccontext IN OUT msconcatimpl_clob ) RETURN NUMBER IS BEGIN io_srccontext := msconcatimpl_clob( NULL, NULL ); 创建或替换类型身体“MSCONCATIMPL_CLOB”是静态功能odciaggregateinitialize(io_srccontext IN OUT msconcatimpl_clob)返回号码是否开始io_srccontext:= msconcatimpl_clob(NULL,NULL); io_srccontext.delimiter := ' '; io_srccontext.delimiter:=''; RETURN odciconst.success; 返回odciconst.success; END odciaggregateinitialize; END odciaggregateinitialize;

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;

END; 结束; / /

-- Creating Clobe Function -- - 创建Clobe功能 -

CREATE OR REPLACE FUNCTION ms_concat_clob ( input VARCHAR2 ) RETURN CLOB PARALLEL_ENABLE AGGREGATE USING msconcatimpl_clob; 创建或替换函数ms_concat_clob(输入VARCHAR2)使用msconcatimpl_clob返回CLOB PARALLEL_ENABLE AGGREGATE; / /

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM