2012-11-08 29 views
5

目前,我有以下查詢:XMLAGG與RTRIM問題

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: Character string buffer too small

什麼變化,我需要申請,使這項工作?

回答

12

您需要添加.getClobVal()到您的XMLType結果,RTRIM之前。

XMLAGG適用於大量數據。 TRIM可以很好地與CLOB一起使用。但是,當您將它們放在一起時,Oracle會嘗試將XMLType轉換爲VARCHAR2而不是CLOB。

例子:

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; 
+0

我想下面的查詢:( 「行集」,XMLAGG(RW.R ORDER BY RW 「ID」)getClobVal()。)選擇XMLELEMENT, '')AS從TMTABLE UL,XMLTABLE(訂單 '行集/行集/列' 逝水UL.TEXT 列 「ID」 NUMBER(19)PATH 'ID', ř的XMLType路徑 )AS RW 但它給我follwoing錯誤 '':ORA-00932:不一致的數據類型:預期 - 得到了CHAR –

+0

@SohamShah我認爲你需要把'.getClobVal()'放在最後一個XML函數之後,而不僅僅是最後一個XMLAGG。嘗試:'XMLELEMENT(「Rowset」,XMLAGG(RW.R ORDER BY RW。「ID」),'').getClobVal()'。 –

1

您需要添加getClobVal()同時還需要rtrim(),因爲它會在結果的最後返回分隔符。

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