簡體   English   中英

Oracle中listagg的替代方案?

[英]alternative to listagg in Oracle?

listagg是Oracle 11.2中引入的一個函數! 現在這個功能正在困擾我們分配,我們正在從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;

只要我們知道在Oracle下面有什么煩惱它就會返回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:屬性或元素值大於類型中指定的值

它有什么解決方案嗎?

謝謝

WM_CONCAT為我工作。

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

我用“替換”包裝它以指定與WM_CONCAT(',')使用的分隔符不同的項目分隔符(';')。

使用xmlAgg,示例如下所示:

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

這將返回clob值,因此無需創建自定義函數。

您可能希望查看用戶定義的聚合函數

這里顯示不同的字符串聚合技術。 它們包含用戶定義的聚合函數的示例。

您可以使用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;

- 創建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

); / - 創建Clobe Type Body -

創建或替換類型身體“MSCONCATIMPL_CLOB”是靜態功能odciaggregateinitialize(io_srccontext IN OUT msconcatimpl_clob)返回號碼是否開始io_srccontext:= msconcatimpl_clob(NULL,NULL); io_srccontext.delimiter:=''; 返回odciconst.success; 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;

結束; /

- 創建Clobe功能 -

創建或替換函數ms_concat_clob(輸入VARCHAR2)使用msconcatimpl_clob返回CLOB PARALLEL_ENABLE AGGREGATE; /

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM