Surgiu a necessidade de recuperar uma informação, esta sendo um XML, salvo dentro de um BLOB e, construí o código à seguir para suprir essa necessidade:
DECLARE
VBLOB BLOB;
VCLOB CLOB;
VCHAR VARCHAR2(32767);
VXML SYS.XMLTYPE;
VTAM PLS_INTEGER := 0;
VT XMLTYPE;
var_clob_line_count number;
var_clob_line varchar2(4000);
-- Nota: Criar temporária Temp_arquivo com 2 colunas (seq,descricao)
-- 1 Função para Converter o Blob para Clob
FUNCTION blob_to_clob (blob_in IN BLOB)
RETURN CLOB
AS
v_clob CLOB;
v_varchar VARCHAR2(32767);
v_start PLS_INTEGER := 1;
v_buffer PLS_INTEGER := 32767;
BEGIN
DBMS_LOB.CREATETEMPORARY(v_clob, TRUE);
FOR i IN 1..CEIL(DBMS_LOB.GETLENGTH(blob_in) / v_buffer)
LOOP
--
v_varchar := UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(blob_in, v_buffer, v_start));
DBMS_LOB.WRITEAPPEND(v_clob, LENGTH(v_varchar), v_varchar);
v_start := v_start + v_buffer;
--
END LOOP;
--
RETURN v_clob;
--
END blob_to_clob;
-- 2 Ler o Clob (como Xmltype e recuperar as tags por linha)
procedure show_xml (p_xml in xmltype
,p_output in boolean default false)
is
l_str long;
vindice PLS_INTEGER := 0;
vstring CLOB;
BEGIN
--
l_str := p_xml.extract ('/*').getstringval ();
-- Libera temporária para o XML
DELETE temp_arquivo;
--
LOOP
vstring := NULL;
exit when l_str is null;
vindice := vindice + 1;
vstring := substr (l_str, 1, instr (l_str, chr (10)) - 1);
-- Popula temporária com tags XML
INSERT INTO temp_arquivo (seq,descricao)
VALUES (vindice,vstring);
-- Display em tela
IF p_output THEN
dbms_output.put_line (substr (l_str, 1, instr (l_str, chr (10)) - 1));
END IF;
--
l_str := substr (l_str, instr (l_str, chr (10)) + 1);
--
end loop;
--
COMMIT;
--
end show_xml;
BEGIN
select XML
INTO vblob
from tabela_com_coluna_xml
where id = 1
and tipo_xml = '06';
-- 1 blob to clob
VCLOB := blob_to_clob(VBLOB);
--
show_xml(xmltype(vclob),true);
--
VCHAR := VCLOB;
--
END;
/*
Testar
select * from temp_arquivo
order by seq
*/
Espero que ajude e, comentários e sugestões sempre bem vindos.
Abraço,
Trevisolli