I have a question and maybe someone has gone through the same problem and can help. I'm working on a project where I need to create a hierarchical XML document from hierarchical data. I have the query that pulls the data and the problem I'm facing is that the query is too long for the querystring parameter accepted by DBMS_XMLGEN.newcontextfromhierarchy (queryString varchar2)
I tried using a with clause but that was not recognized when selecting from the resultset which looks understandable.
SELECT XMLRoot( XMLELEMENT
("clients",
(SELECT DBMS_XMLGEN.getxmltype
(DBMS_XMLGEN.newcontextfromhierarchy
('SELECT level,
XMLElement("client",
XMLElement("client_number", client_number),
XMLElement("parent_client_number", parent_client_number),
XMLElement("level", level),
XMLElement("client_level", client_level))
FROM clients
START WITH parent_client_number = ''900002''
CONNECT BY PRIOR client_number = parent_client_number
ORDER siblings BY parent_client_number'))
FROM DUAL), (XMLELEMENT())),VERSION '1.0') as XMLDATA
FROM DUAL;
The query is much longer than the one above but that will give an idea of what I'm running.
This is the exact error I'm getting.
ORA-01704: string literal too long
Has anyone faced this problem before and have any ideas of how to overcome it?
Thanks, Sergio
Yeah, always a problem when code has to be in a VARCHAR2 with length limitations on it :-)
If DBMS_XMLGEN.newcontextfromhierarchy had accepted a CLOB, the solution would have been to build the CLOB in lumps of several literals that each was smaller than the limit. But DBMS_XMLGEN.newcontextfromhierarchy unfortunately uses a VARCHAR2.
Classic solution would be to write the query as a view and then the string could simply be "select * from myview where ..." Unfortunately you kind of need a "parameter" to the view to put in the START WITH clause.
One way to do that could be to use a context as described in #1 in this link: http://mahmoudoracle.blogspot.dk/2012/06/create-view-with-parameter.html#.VAVdNPmSwt0 .
Create a context to hold the parameter(s) (see the link).
Define the view something like:
Just before your DBMS_XMLGEN call, set the parameter:
And then the query string would just be:
This method could handle as long a query as it is possible to build into a view (which is a lot, I don't know how much, but a lot ;-)
If the greater part of your code is the XMLELEMENT("client"...) part, an alternative (and perhaps simpler) solution would be something like:
And your query in the DBMS_XMLGEN call would become something like:
Just moving all the XML generation out to a function might make your code small enough, it would depend on whether there are other tables or joins or the number of parameters to the function would be too large in itself.
So it can be a choice of methods - if the function makes the query "small enough", it is the simpler method. If the function is not enough, the parameterized view should be able to handle it - it is just a little more "unclear what happens" to future managers of this code ;-)