2012-11-08 22 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;