Olá Amigos(a), tudo bem?
Ocorreu uma situação
onde precisei imprimir um campo BLOB que mantinha um XML de nota
fiscal eletrônica.
O sistema que uso aqui
na empresa não me permite trabalhar com um campo BLOB por se tratar
de um campo de armazenamento de binários, levando em consideração
o fato de que eu “SEI” que neste campos nosso sistema só
armazena texto, então precisei converter o campo para CLOB.
Para isto precisei
fazer uso dos pacotes DBMS que trabalha com os LOBS.
Criei uma função onde
eu passo um BLOB e que me retorna um CLOB.
Também passo mais dois
parâmetros, são eles: v_amount e v_offset.
Uso “v_amount” para
dizer qual o tamanho em bites que pretendo extrair a partir de
v_offset.
Não posso deixar
passar um campo de uma vez, pois corro o risco do XML ser maior que a
buffer disponível na constante “dbms_lob.lobmaxsize” (que
carrega o valor do parâmetro DB_BLOC_SIZE do banco no caso o meu é
8192).
Até pensei em mudar o
parâmetro, mais por um simples detalhe, entendi que não poderia.
Isto porque este valor é definido na criação do banco de dados.
Como o Oracle trabalha com blocos, então o banco aqui foi definido
com 8192 de blocagem.
Agora segue a função:
create or replace
function CONVERT_BLOB_TO_CLOB(v_blob_in in blob, v_amount in integer,
v_offset in integer)
return clob is
v_file_clob
clob;
v_blob
blob;
v_file_size
integer := dbms_lob.lobmaxsize; – Aqui eu pego o valor maximo
(DB_BLOC_SIZE).
v_dest_offset
integer := 1;
v_src_offset
integer := 1;
v_blob_csid
number := dbms_lob.default_csid;
v_lang_context
number := dbms_lob.default_lang_ctx;
v_warning
integer;
v_length
integer;
v_off
integer := v_offset;
BEGIN
– OBTER O TAMANHO
TOTAL DO CAMPO
v_length :=
dbms_lob.getlength(v_blob_in);
– VERIFICAR SE O OQUE
ESTA SENDO PEDIDO DE FATO EXISTE.
IF(v_length < v_off
) THEN
v_off := v_length;
End If;
– PEGAR SOMENTE UM
PEDAÇO DO VALOR
v_blob :=
dbms_lob.substr(v_blob_in,v_amount, v_off);
– RESERVA UMA AREA
TEMPORÁRIA PARA CONVERTER OS DADOS.
dbms_lob.createtemporary(v_file_clob,
true);
– CONVERTE OS DADOS
dbms_lob.converttoclob(v_file_clob,
v_blob,
v_file_size,
v_dest_offset,
v_src_offset,
v_blob_csid,
v_lang_context,
v_warning);
Return v_file_clob;
END;
– USANDO FUNCTION NO
SQL, PERCEBA QUE PASSO O MESMO CAMPO PELOMENOS UMAS TRES VEZES.
– O TIPO VARCHAR2 SÓ
ENTENDE ATÉ 4000 CARACTERS, E NO MEU CASO, MEU SISTEMA TAMBÉM NÃO
NÃO LÊ CLOB, ENTÃO DEPOIS DA FUNCTION PRECISEI FAZER CAST DO CLOB
PRA VARCHAR2.
Select
cast(CONVERT_BLOB_TO_CLOB(XML,
4000, 1) as varchar2(4000)) as MYXML1,
cast(CONVERT_BLOB_TO_CLOB(XML,
4000, 4001) as varchar2(4000)) as MYXML2,
cast(CONVERT_BLOB_TO_CLOB(XML,
4000, 8001) as varchar2(4000)) as MYXML3
From TABELAX Where
TABELAX.nfe = '01 000067861';
Agora resta concatenar
os campos no teu sistema e trabalhar da forma que achar melhor.
espero ter ajudado!