2012-02-23 11 views
13

listaggはOracle 11.2で導入された関数です!今、この関数は、私たちが割り当てる盗聴され、我々は、MySQLからOracleに移行すると、私たちは、このクエリを持っている:Oracleのlistaggの代わりに?

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を返し、ないOracleの下にあり、私たちが必要とする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:属性または要素の値は、タイプで指定されたよりも大きく、

解決方法はありますか?あなた

答えて

14
+1

+1収集リンクありがとうございます! – tbone

+0

私自身の機能を書いて、私の質問を更新しました。再度質問をしてください、ありがとう –

+0

私はなぜあなたがそのエラーを受けているのか分かりません - それはおそらく新しい質問として投稿する価値があります、そのようにそれを見て。 –

2

user-defined aggregate functionsをご覧ください。

異なる文字列集約技術がhereと表示されています。これには、ユーザー定義の集約関数の例が含まれています。

+0

良いオプションがあります。より速い情報がありますか? –

+0

パフォーマンスに関する情報はありません。私はそれが主に全体の実行計画とその実行計画にどのように適合するかに依存していると思います。したがって、クエリごとに異なる可能性があります。 – Codo

2

かわりCOLLECTMULTISETを使用して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; 
2

WM_CONCATは私のために働きました。

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

Iは、異なるアイテムセパレータを指定する「置換」とそれを包んだ(「;」)WM_CONCATで使用されるもの(「」)から。

+2

12c、Express Edition、およびWorkspace Managerがインストールされていないデータベースでは、WM_CONCATは使用できません。 –

+1

現在サポートされておらず、また文書化されていません –

1

使用XMLAGG、例を以下に示します。

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

これは、CLOB値とそのカスタム関数を作成する必要はありませんが返されます。

0

- Clobeタイプの作成 - (、 resultstring 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 

)をオブジェクトとしてTYPE "MSCONCATIMPL_CLOBを" CREATE OR REPLACE。 / - Clobeタイプ本体の作成 -

のTYPE BODY "MSCONCATIMPL_CLOBを" CREATE OR REPLACE 静的関数odciaggregateinitialize(io_srccontextで実施msconcatimpl_clob)RETURNのNUMBER は io_srccontext BEGIN ISの:= msconcatimpl_clob( NULL、 をNULL ); io_srccontext.delimiter:= ''; RETURN odciconst.success; END odciaggregate initialize;

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; /

- Clobe関数の作成 -

msconcatimpl_clobを用いて機能ms_concat_clob(入力VARCHAR2)RETURNのCLOB PARALLEL_ENABLE AGGREGATEを作成するか、またはREPLACE。 /

関連する問題