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のバグが何であるかを知る限り、MySQLでは問題なく動作しますが、必要に応じてCLOBではなくVARCARを返します。 テキストは巨大で、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:属性または要素の値がタイプで指定された値より大きい
それに対する解決策はありますか?
ありがとうございます
collect または 独自の集計関数を作成する を使用します。
WM_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値を返すため、カスタム関数を作成する必要はありません。
ユーザー定義の集計関数 を見たいと思うかもしれません。
異なる文字列集約手法を示します here 。これらには、ユーザー定義の集計関数の例が含まれています。
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;
-クローブタイプの作成-CREATE OR REPLACE TYPE "MSCONCATIMPL_CLOB" AS OBJECT(resultstring CLOB、delimiter 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
); /-クローブタイプボディの作成-
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); io_srccontext.delimiter:= ''; RETURN 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;
終わり; /
-クローブ関数の作成-
CREATE OR REPLACE FUNCTION ms_concat_clob(input VARCHAR2)RETURN CLOB PARALLEL_ENABLE AGGREGATE USING msconcatimpl_clob; /