'CLOB String litteral too long
I'm facing an issue here, and wondering if there's an easy solution, I'm using the PL/SQL code below. the goal is to iterate one xml node, and update a table with the content of all which is between the opening and closing of this node. The function works well for that.
Issue is that I want to process a huge XML string, more than 150K lines, and 6M characters. and I get the 'string litteral too long' error, even if a CLOB is supposed to handle huge content. So I'm wondering if there's an easy way to process this anyway, or if this is another type of restriction can be modified elsewhere ?
DECLARE
v_XML_INPUT CLOB := '<xmlString>';
v_COUNT NUMBER;
v_TOTAL_COUNT NUMBER;
v_XML_SECTION CLOB;
v_TEMPLATE_FULL_NAME VARCHAR2(128);
BEGIN
SELECT REGEXP_COUNT(v_XML_INPUT, '<templates>', 1) INTO v_TOTAL_COUNT FROM DUAL;
DBMS_OUTPUT.PUT_LINE(v_TOTAL_COUNT);
v_COUNT := 1;
WHILE v_COUNT <= v_TOTAL_COUNT
LOOP
SELECT REGEXP_SUBSTR(v_XML_INPUT, '(\<templates\W)(.+?)(\</templates\W)',1,v_COUNT,'n') INTO v_XML_SECTION FROM DUAL;
SELECT
xt.TEMPLATE_FULL_NAME
INTO v_TEMPLATE_FULL_NAME
FROM XMLTABLE(
'/templates'
PASSING XMLType(v_XML_SECTION)
COLUMNS TEMPLATE_FULL_NAME VARCHAR2(128) PATH 'templateFullName'
) xt;
DBMS_OUTPUT.PUT_LINE(v_TEMPLATE_FULL_NAME);
UPDATE
TEMPLATES
SET
LAST_UPDATE = SYSDATE,
XML_TEMPLATE_SOURCE = v_XML_SECTION
WHERE TEMPLATE_FULL_NAME = v_TEMPLATE_FULL_NAME;
v_COUNT := v_COUNT +1;
END LOOP;
COMMIT;
END;
Thanks in advance for your insight :-)
Solution 1:[1]
The problem is that the XML that you are pasting is too large to be stored in a VARCHAR2. When you are pasting it into the PL/SQL code, it is stored in a VARCHAR2 before being converted to a CLOB.
Instead of doing this (notice how the XML is all in one block):
DECLARE
v_XML_INPUT CLOB := '<xml>
<subelement>
<subelement2>123</subelement2>
</subelement>
</xml>';
BEGIN
NULL;
END;
/
Try splitting the lines of the XML into separate VARCHAR2 blocks with a text editor (very easy with Visual Studio Code), then concatenate them together when assigning to the CLOB:
DECLARE
v_XML_INPUT CLOB
:= '<xml>'
|| ' <subelement>'
|| ' <subelement2>123</subelement2>'
|| ' </subelement>'
|| '</xml>';
BEGIN
NULL;
END;
/
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | EJ Egyed |
