SYS_CONNECT_BY_PATH leads to "ORA-01489: result of string concatenation is too long"

I'm using SYS_CONNECT_BY_PATH to do string aggregation. The general shape of the query is something like this:

select /*a bunch of fields unrelated to the problem*/,
--Use SYS_CONNECT_BY_PATH to glue together all the chunks of XML. 
--The XSL header and footer are prepended and appended here.
 , XMLType(to_clob('<?xml version="1.0"?><!-- begining of XSL file -->,'<!-- Next Section -->'))||'</xsl:stylesheet>')) AS XSL
from (
  select /*a bunch of fields unrelated to the problem*/
    case when x = 1 then to_clob('
    /*a bunch of XSL*/
     <xsl:text>'||subq.new_c_value||'</xsl:text>
    /*a whole bunch more xsl*/')
    else
     to_clob('/*a bunch of different XSL*/             
     <xsl:text>'||subq.new_f_value||'</xsl:text>
    /*a whole bunch more xsl*/')
    end as xsl,
  --curr and prev are to help with using sys_connect_by_path do string aggregation.
    rownum AS curr,
    rownum -1 AS prev
  from (Select /* details of subq not relevant */ ) as subq
)
CONNECT BY prev = PRIOR curr 
START WITH curr = 1;

Basically, I'm running a query to generate XSL that is used to correct XML files. I'm using sys_connect_by_path to combine the strings together into one single chunk, which is easier than copying and pasting many values from many rows. I can't use any custom string aggregate functions because this query runs on a production database where I can't just go and create functions as I want.

The problem is that running my query will return:

ORA-01489: result of string concatenation is too long
01489. 00000 -  "result of string concatenation is too long"
*Cause:    String concatenation result is more than the maximum size.
*Action:   Make sure that the result is less than the maximum size.

...in cases where there is too much data. As you can see, I've been applying the to_clob() function to anywhere I think it might help, but it doesn't seem to have made much difference. Are there any other ways to handle this besides resorting to PL/SQL? I'd prefer to keep this as a query because the result of this query is exported to a report template which shows a number of useful pieces of information side-by-side with the XSL. It would be nice to be able to do all of this in one single step rather than in several steps.

(Oracle 10g)


Eventually, I found this page:

http://www.sqlsnippets.com/en/topic-11787.html

about string aggregation techniques in Oracle. I suspect the only ones that will work in my situation are the XML method and the Model methods. I couldn't get the model methods to work quite right so I just went with the XML method.

Upvotes: 3

Views: 6894

Answers (2)

Jon Heller
Jon Heller

Reputation: 36807

select
    xmlroot
    (
        xmlelement
        (
            "xsl:stylesheet"
            ,XMLAttributes
            (
                '1.0' as version
                ,'http://www.w3.org/1999/XSL/Transform' as "xmlns:xsl"
                ,'http://test' as "xmlns:ns0"
            )
            ,(
                xmlagg(xmlelement("xsl:text", val))
            )
        )
        ,version '1.0'
    )
from
(
    --Test >4000 characters
    select 1 id, cast(rpad('a',4000,'a') as varchar2(4000)) val from dual union all
    select 1 id, cast(rpad('b',4000,'b') as varchar2(4000)) val from dual union all
    select 1 id, cast(rpad('c',4000,'c') as varchar2(4000)) val from dual union all
    select 1 id, cast(rpad('d',4000,'d') as varchar2(4000)) val from dual
);

Upvotes: 1

psaraj12
psaraj12

Reputation: 5072

Sorry my answer relies on Creating String aggregate package but might be useful in the long run You can use the Stragg Package instead of sys_connect_by_path mentioned in AskTom in the below link

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2196162600402

in that package there is a declaration and some logic for handling long which you can change for handling CLOB according to your needs

Upvotes: 0

Related Questions