- Este tópico contém 9 respostas, 2 vozes e foi atualizado pela última vez 14 anos, 9 meses atrás por
rman.
-
AutorPosts
-
17 de maio de 2011 às 5:03 pm #99256
Doug
ParticipantePessoal, bom dia…
Preciso escrever uma procedure na qual ira conter um campo do tipo long que ira gravar um arquivo txt com apenas uma linha e tamanho maior que 200K.
O complicado é que o usuario precisa que essa informação seja inserida apenas em uma linha… e nao consigo gravar utilizando “put”.
Alguma sugestão???
17 de maio de 2011 às 5:04 pm #99257Doug
ParticipanteCREATE OR REPLACE PROCEDURE ESSAKAI.PRC_XML_BUILDER_v1p3(pCD_XML in number,
pNM_ACAO in varchar2,
pMSG out varchar2) ISvXML_Versao_Ausente boolean := true;
in_file utl_file.file_type;
linebuf varchar2(32767);
filename varchar2(240);
buf_lob CLOB;
vMSG varchar2(240) default ‘Sucesso’;
vnCounter number := 0;BEGIN
filename := fun_XML_Nome_Arquivo(pNM_ACAO);
if filename is not null then
in_file := utl_file.fopen(‘DIR_XML_BFILE’, filename, ‘w’, 32767);BEGIN
Declare
— Documentos Assinados
cursor c4 is
select xdp.xdp_id_xct,
xdp.xdp_id_cbr,
substr(xdp.xdp_nm_doc, 1, length(xdp.xdp_nm_doc) – 4) xdp_nm_doc,
xdp.xdp_doc_locator,
xdp.xdp_doc_blob
from hw_xml_docprotesto xdp;
–where xdp.xdp_id_xct = pid_xct;
—
vAuxc4 c4%rowtype;
vQT_Carac pls_integer default 1024; — Quantidade de caracteres lidos de uma vez “Limitado ao tamanho do buffer 32767″
vTT_Compr pls_integer; — Quantidade de caracteres do campo blob
vNR_Grupo pls_integer := 0; — Parte inteira do Resultado de vTT_Compr dividido por vQT_Carac
vQT_Resto pls_integer := 0; — Parte resto do Resultado de vTT_Compr dividido por vQT_Carac
l_offset pls_integer default 1; — Ponteiro para início de leitura
primeira_vez boolean := true;
—
Begin
open c4;
fetch c4
into vAuxc4;
if c4%found then
vTT_Compr := nvl(dbms_lob.getlength(vAuxc4.xdp_doc_blob), 0);
vNR_Grupo := TRUNC(vTT_Compr / vQT_Carac);
vQT_Resto := MOD(vTT_Compr, vQT_Carac);For i in 1 .. vNR_Grupo loop
if primeira_vez then
linebuf := linebuf ||
dbms_lob.substr(vAuxc4.xdp_doc_blob,
vQT_Carac,
l_offset);
primeira_vez := FALSE;
else
linebuf := dbms_lob.substr(vAuxc4.xdp_doc_blob,
vQT_Carac,
l_offset);
end if;
l_offset := l_offset + vQT_Carac;
utl_file.put(in_file, linebuf); –alterado
— utl_file.put(in_file, linebuf);
linebuf := null;
— utl_file.fflush(in_file);if i = 30 then
exit;
linebuf := null;
end if;end loop;
linebuf := dbms_lob.substr(vAuxc4.xdp_doc_blob,
vQT_Resto – 2,
l_offset);
linebuf := linebuf || ‘” ‘;
utl_file.put(in_file, linebuf);
— utl_file.put ( in_file,linebuf ) ;
linebuf := null;
— utl_file.fflush(in_file);
end if;
close c4;
/* Exception
When UTL_FILE.INVALID_PATH then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 1 ‘||chr(10)||vMSG );
When UTL_FILE.INVALID_MODE then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 2 ‘||chr(10)||vMSG );
When UTL_FILE.INVALID_FILEHANDLE then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 3 ‘||chr(10)||vMSG );
When UTL_FILE.INVALID_OPERATION then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 4 ‘||chr(10)||vMSG );
When UTL_FILE.READ_ERROR then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 5 ‘||chr(10)||vMSG );
When UTL_FILE.WRITE_ERROR then
vMSG := sqlerrm;
dbms_output.put_line( ‘Otre.: 6 ‘||chr(10)||vMSG );
When UTL_FILE.INTERNAL_ERROR then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 7 ‘||chr(10)||vMSG );
When UTL_FILE.INVALID_FILENAME then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 8 ‘||chr(10)||vMSG );
When UTL_FILE.ACCESS_DENIED then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 9 ‘||chr(10)||vMSG );
When UTL_FILE.INVALID_OFFSET then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 10 ‘||chr(10)||vMSG );
When UTL_FILE.INVALID_MAXLINESIZE then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 11 ‘||chr(10)||vMSG );
When OTHERS then
DBMS_OUTPUT.PUT_LINE(SUBSTR(SQLERRM,1,255));
RAISE; */
End;
END DocProtesto;utl_file.fclose(in_file);
else
vMSG := ‘Não foi possível montar o nome do arquivo XML.’;
end if;
pMSG := vMSG;END PRC_XML_BUILDER_v1p3;
18 de maio de 2011 às 1:55 am #99264rman
ParticipanteDoug, o erro não está o no put.
Fiz alguns testes, e dei umas pesquisadas, porque de inicio não fazia sentido dar erro.
UTL_FILE.FOPEN (
location IN VARCHAR2,
filename IN VARCHAR2,
open_mode IN VARCHAR2,
max_linesize IN BINARY_INTEGER)
RETURN file_type;
max_linesize é o tamanho maximo de cada linha, incluindo o caracter de nova linha, logo temos 32767 bytes, que é igual a 31k menos 1b, max_linesize pode ir de 1 a 32767. Se não especificado o padrão é 1024.
O erro acontece no UTL_FILE.FCLOSE. Ao fechar o arquivo a linha é maior que o suportado, então da erro de escrita.
Como existe essa limitação de 31k menos 1b, não será possível por os 200k como desejado direto.
Uma alternativa é abrir o arquivo inicialmente em modo ‘W’ fechar o arquivo em seguida abrir o arquivo em modo ‘A’ e fecha lo novamente, desta forma é só fazer um loop ate terminar a linha.
Creio que a escrita no arquivo é feita no FCLOSE e não no PUT.
Segue um teste que eu fiz:
create or replace directory diretorio as 'c:temp';
create or replace procedure prc_save_text_archive(directory in Varchar2,name_archive in Varchar2) is
text_archive utl_file.file_type;
text varchar(30720);
trinta_k_bytes number;
begin
trinta_k_bytes := 30720;/*salvando 30k*/ text_archive := utl_file.fopen(directory,name_archive,'w',32767); for i in 1..trinta_k_bytes loop text := text || '1' ; end loop; utl_file.put(text_archive,text); utl_file.fclose(text_archive); /*salvando 60k*/ text_archive := utl_file.fopen(directory,name_archive,'a',32767); text := null; for i in 1..trinta_k_bytes loop text := text || '0' ; end loop; utl_file.put(text_archive,text); utl_file.fclose(text_archive); /*salvando 90k*/ text_archive := utl_file.fopen(directory,name_archive,'a',32767); text := null; for i in 1..trinta_k_bytes loop text := text || '1' ; end loop; utl_file.put(text_archive,text); utl_file.fclose(text_archive);end prc_save_text_archive;
call prc_save_text_archive('DIRETORIO','TESTE.TXT');
18 de maio de 2011 às 4:41 pm #99266Doug
ParticipanteMuito boa a explicação, mas me resta uma duvida…
Ao inves de add os 0 na linha de baixo, eu consigo concatenar para ele fazer uma “tripa” só ?
Ex : 11111111111111111111111100000000000000000000000011111111111111
18 de maio de 2011 às 10:55 pm #99272rman
Participante[quote=”Doug”:2ydh3dvo]Muito boa a explicação, mas me resta uma duvida…
Ao inves de add os 0 na linha de baixo, eu consigo concatenar para ele fazer uma “tripa” só ?
Ex : 11111111111111111111111100000000000000000000000011111111111111[/quote]
Pootz, realmente eu não tinha me atentado, ao salvar o arquivo automaticamente é colocado CR e LF no final do arquivo. E o pior, não é o PUT que faz isso. A solução se baseava abrir o arquivo pela segunda vez em mode de APPEND e ir adicionando o restante da linha.
A pergunta é ? É possível criar um arquivo texto sem o CR e LF no final do arquivo ? Eu não consegui…
Tentei outra solução usando o FFLUSH, mas para descarregar os dados da memoria para o arquivo é necessario de um CR e LF também, apesar de não ter dado certo, segue o test, quem sabe alguém possa continuar a solução apartir deste ponto.
create or replace procedure prc_save_text_archive(directory in varchar2,name_archive in varchar2) is
text_archive utl_file.file_type;
text varchar(30720);
trinta_k_bytes number default 30720;
begin
text_archive := utl_file.fopen(directory,name_archive,'w',32767);text := null; for i in 1..trinta_k_bytes loop text := text || '0' ; end loop; utl_file.put_line(text_archive,text); utl_file.fflush(text_archive); text := replace(text,'0','1'); utl_file.put_line(text_archive,text); utl_file.fflush(text_archive); text := replace(text,'1','0'); utl_file.put_line(text_archive,text); utl_file.fflush(text_archive); utl_file.fclose(text_archive);end prc_save_text_archive;
18 de maio de 2011 às 10:58 pm #99273Doug
ParticipanteAqui com fflush tbm nao deu certo…Por isso o desenvolvedor jogou o b.o pra mim, dizendo que pode ser algum patch da oracle.
18 de maio de 2011 às 11:05 pm #99274rman
Participante[quote=”Doug”:1b8x686s]Aqui com fflush tbm nao deu certo…Por isso o desenvolvedor jogou o b.o pra mim, dizendo que pode ser algum patch da oracle.[/quote]
Pelo que eu andei lendo, um bug que existia era na hora de exportar BLOB para arquivo texto, onde o Oracle adicionada CR e LF no final do arquivo. Se fosse uma .GIF por exemplo a GIF era danificada. Creio que na versão atual esse bug já foi corrigido.
Por que essa geração de arquivo não é feita através de uma aplicação Delphi, Java, PHP, etc… ? Creio que é muito mais simples…
18 de maio de 2011 às 11:11 pm #99275rman
ParticipanteSegue uma explicação do bug
http://www.idevelopment.info/data/Oracl … S_80.shtml
http://www.oracle-base.com/articles/9i/ExportBlob9i.php
O bug é em arquivo binario, mas o arquivo que você quer exportar é arquivo texto né ?
18 de maio de 2011 às 11:14 pm #99276Doug
Participante[quote=”rman”:2gi3x9ge]Segue uma explicação do bug
http://www.idevelopment.info/data/Oracl … S_80.shtml
http://www.oracle-base.com/articles/9i/ExportBlob9i.php
O bug é em arquivo binario, mas o arquivo que você quer exportar é arquivo texto né ?[/quote]
Sim , Sim..Arquivo texto….vou ler as explicacoes…
20 de maio de 2011 às 11:10 pm #99294rman
ParticipanteE ai Doug !
Conseguiu resolver o problema ?
Qual a solução aplicada ?
-
AutorPosts
- Você deve fazer login para responder a este tópico.