8

現在、次のクエリがあります。

SELECT 
    CASE 
       WHEN ('[Param.3]' = 'SELECTED')
          THEN (SELECT RTRIM(XMLELEMENT("Rowset", XMLAGG(RW.R ORDER BY RW."ID")), ' ' ) AS Orders
                FROM TMTABLE UL, XMLTABLE('Rowsets/Rowset/Row' PASSING UL.TEXT COLUMNS "ID" NUMBER(19) PATH 'ID', R xmltype path '.') AS RW
                WHERE ID BETWEEN '[Param.1]' and '[Param.2]')
       WHEN ('[Param.3]' = 'ALL' )
          THEN (SELECT RTRIM(XMLELEMENT("Rowset", XMLAGG(RW.R ORDER BY RW."ID")) , ' ' ) AS Orders
                FROM TMTABLE UL, XMLTABLE('Rowsets/Rowset/Row' PASSING UL.TEXT COLUMNS "ID" NUMBER(19) PATH 'ID', R xmltype path '.') AS RW)
    END AS Orders
FROM 
    dual

XML AGGを使用して単一の行にマージするXML行の数が少ない場合、このクエリは正常に機能します。ただし、マージするXML行の数が多い場合、このクエリは次のエラーをスローします。

ORA-19011:文字stringバッファが小さすぎます

この機能を実現するには、どのような変更を適用する必要がありますか?

4

2 に答える 2

17

.getClobVal()RTRIMの前に、XMLTypeの結果に追加する必要があります。

XMLAGGは、大量のデータで正常に機能します。また、TRIMはCLOBで正常に機能します。ただし、これらを組み合わせると、OracleはXMLTypeをCLOBではなくVARCHAR2に変換しようとします。

例:

create or replace function test_function return clob is
    v_clob clob;
begin
    v_clob := v_clob || lpad('a', 4000, 'a');
    v_clob := v_clob || lpad('b', 4000, 'b');
    return v_clob;
end;
/

--Works fine, returns an XMLType
select xmlagg(xmlelement("asdf", test_function)) from dual;

--Works fine, returns a CLOB
select trim(test_function) from dual;

--ORA-19011: Character string buffer too small
select trim(xmlagg(xmlelement("asdf", test_function))) from dual;

--Works
select trim(xmlagg(xmlelement("asdf", test_function)).getClobVal()) from dual;
于 2012-11-09T05:34:17.100 に答える
2

結果の最後に区切り文字が返されるため、追加する必要があります。getClobVal()また、追加する必要があります。rtrim()

SELECT RTRIM(XMLAGG(XMLELEMENT(E,colname,',').EXTRACT('//text()') ORDER BY colname).GetClobVal(),',')
  FROM tablename;
于 2015-03-13T10:01:23.893 に答える