- Este tópico contém 5 respostas, 2 vozes e foi atualizado pela última vez 6 anos, 10 meses atrás por José Laurindo Chiappa.
-
AutorPosts
-
12 de fevereiro de 2018 às 9:59 pm #109183Anderson RibeiroParticipante
Para inserir pdfs em um campo blob no PostgreSQL, no insert é só utilizar a função lo_import(‘/path/file.pdf’)
Existe alguma função no Oracle similar à função lo_import do PostgreSQL?
13 de fevereiro de 2018 às 9:58 pm #109184José Laurindo ChiappaModeradorBlz ? Então, primeira coisa eu ** sempre ** indico que vc explique DETALHADAMENTE o que vc quer ao invés de se basear numa funcionalidade de outro SGBD, pois NÃO APENAS dificilmente quem conhece bem teu SGBD exemplo conhece também o RDBMS Oracle MAS TAMBÉM sempre há detalhes a se considerar – por exemplo, por não conhecer bem o PostgerSQL eu não sei se essa tal ‘lo_import’ lê um arquivo que está na máquina servidora do SGBD ou numa máquina-cliente, se é uma built-in interna do SGBD ou se demanda alguma instalação a mais, nada de nada…. okdoc ??
AO QUE ENTENDO (baseado na minha POUCA experiência com o Post e no artigo http://www.andersonmedeiros.com/importar-arquivos-pdf-postgresql/), essa tal é uma função interna do SGBD que lê um arquivo presente no servidor do SGBD (ou disponibilizado para acesso por parte do servidor, via NFS ou coisa assim) e insere o conteúdo lido numa coluna do tipo Binary Object, BLOB no Oracle : o equivalente no RDBMS Oracle seria a package DBMS_LOB, nela há uma rotina LOADFROMFILE que faz exatamente isso, https://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:232814159006 tem um exemplo loho na primeira resposta – ignore a parte que vem depois de “Now here is the package that can retrieve the pdf…”, a carga do .PDF é o que foi feito antes desse parágafo… VC vai ver que é basicamente criar a tabela com a coluna BLOB que vc quer (tem que ser BLOB e não CLOB, já que .PDF é binário), tem que criar um “sinônimo” pra pasta do servidor aonde vc vai ler o arquivo (é o objeto chamado DIRECTORY que o Autor cria no exemplo), e imediatamente antes de vc chamar o LOADFROMFILE vc tem que ter aberto um file handler via DBMS_LOB.FILEOPEN, e depois de carregar o .PDF vc fecha o file handler, certinho como tá feito no exemplo…[]s
Chiappa
OBS : evidentemente, se for OUTRA a sua necessidade (por exemplo, se vc quer carregar o arquivo a partir duma máquina-cliente, digamos) vc teria que usar OUTRAS funcionalidades do RDBMS Oracle , veja https://blogs.oracle.com/searchtech/loading-documents-and-other-file-data-into-the-oracle-database para refs…
13 de fevereiro de 2018 às 10:56 pm #109185Anderson RibeiroParticipanteO insert a ser feito é onde o SGBD do PostgreSQL está executando, ou seja, localmente.
Ao acessar o Postgres via linha de comando, basta executar a instrução: INSERT INTO PROCESSODOCUMENTO(ID,DS_ARQUIVO,DTHINCLUSAO,DOCUMENTOARQUIVO) VALUES(1,’MATEMATICA’,’30/05/2016′,lo_import(‘/home/phoenix/files/070698d8-0dfd-11e8-91b9-847bebfeb61e.pdf’));
que o PDF é inserido.Pelo link que postou, não basta apenas um simples insert para inserir um pdf no Oracle 🙁
Mas irei verificar, obrigado!
14 de fevereiro de 2018 às 2:36 pm #109186José Laurindo ChiappaModeradorDiferentes SGBDs manipulam dados não-escalares de maneiras diferentes, sim – pode ter certeza disso…
No caso do RDBMS Oracle, os LOBs são tratados como arquivos, ie : vc o ‘abre’, lê/grava e depois ‘fecha’ ele, e essa manipulação é feita por uma API interna, a package DBMS_LOB, é isso aí… E como eu disse/mostrei nos links, esss API trabalha não com as pastas do servidor diretamente, mas com um ‘atalho’, um ‘sinônimo’ que aponta pra pasta que vc quer acessar, o chamado DIRECTORY, que TEM que ser criado (uma vez só) antes do teu programa manipular LOBs… Não é NADA complexo mas vc TEM que conhecer o conceito para o poder usar, sim….[]s
Chiappa
14 de fevereiro de 2018 às 5:39 pm #109187José Laurindo ChiappaModeradorO ponto principal no RDBMS Oracle é que essa API contida na package DBMS_LOB é feita em PL/SQL, então vc deve a chamar a partir do PL/SQL, e não da linguagem SQL ‘pura’… Por exemplo, vou encapsular a chamada do DBMS_LOB.LOADFROMFILE numa procedure minha – podia optar por encapsular todo o INSERT na tabela no PL/SQL numa procedure ou function (e aí a tua Aplicação simplesmente chamaria ela), ou Até Mesmo podia chamar uma função PL/SQL que já faz todo o necessário direto do insert (que imagino é o que faz essa lo_import), mas vamos na simplicidade… E claro, no caso eu tenho uma base de teste no Windows, se a sua base estiver no Linux os CONCEITOS são os mesmos mas muda as permisssões exigidas no SO e a sintaxe do PATH do directory já que linux usa ‘/’ e Windows usa ”, claro :
=> como dito, TENHO que ter o objeto do tipo DIRECTORY criado antes :
SYSTEM:@XE:SQL>create directory DOWNLOADS as ‘C:Usersjlchi_000Downloads’;
Diretório criado.
=> e logicamente tenho que ter a tabela criada :
SYSTEM:@XE:SQL>create table TAB_PDFS (
2 id_do_pdf number,
3 descr_do_pdf varchar2(250),
4 coluna_contendo_pdf blob);Tabela criada.
=> Ó os .PDFs na minha pasta :
C:Usersjlchi_000Downloads>dir database*.pdf
O volume na unidade C não tem nome.
O Número de Série do Volume é 340C-E794Pasta de C:Usersjlchi_000Downloads
03/05/2017 11:21 402.152 database-links-masterclass_1.pdf
03/05/2017 11:22 420.041 database-links-masterclass_2.pdf
2 arquivo(s) 822.193 bytes
0 pasta(s) 146.175.492.096 bytes disponíveisC:Usersjlchi_000Downloads>
==> antes de criar a procedure que encapsula a chamada à package DBMS_LOB, vou Ativar saída na tela no sql*plus (que é a tool que estou usando aqui) :
SYSTEM:@XE:SQL>set serveroutput on size unlimited
=> OK, vou criar a procedure exemplo :
SYSTEM:@XE:SQL>CREATE OR REPLACE PROCEDURE CARREGA_PDF(P_id_do_pdf number, P_arquivo_pdf varchar2) AS
2 v_lob_locator blob;
3 v_file_locator bfile := bfilename(‘DOWNLOADS’, P_arquivo_pdf); — Obter file handler
4 v_blob_size integer;
5 v_file_size integer;
6 BEGIN
7 select coluna_contendo_pdf into v_lob_locator from TAB_PDFs where id_do_pdf = P_id_do_pdf for update of coluna_contendo_pdf;
8 dbms_lob.fileopen(v_file_locator);
9 v_file_size := dbms_lob.getlength(v_file_locator);
10 dbms_output.put_line(‘Tamanho do arquivo carregado: ‘ || v_file_size);
11 dbms_lob.loadfromfile(v_lob_locator, v_file_locator, v_file_size);
12 —
13 v_file_size := dbms_lob.getlength(v_lob_locator);
14 dbms_output.put_line(‘Tamanho da coluna blob: ‘ || v_file_size);
15 exception
16 when others then
17 dbms_output.put_line(‘Deu o seguinte erro:’);
18 dbms_output.put_line(sqlcode || sqlerrm);
19 END;
20 /Procedimento criado.
SYSTEM:@XE:SQL>
==> Pronto…. Como indicado antes, a coluna TEM que ter um LOB vazio aonde o LOADFROMFILE vai apendar os bytes lido do arquivo, ele NÃO cria o LOB em si :
SYSTEM:@XE:SQL>insert into TAB_PDFS values(1, ‘Parte1/2 do curso de dblinks’, empty_blob());
1 linha criada.
==> Chamo a rotina de carga em PL/SQL com o INSERT feito via SQL :
SYSTEM:@XE:SQL>exec CARREGA_PDF(1, ‘database-links-masterclass_1.pdf’);
Tamanho do arquivo carregado: 402152
Tamanho da coluna blob: 402152Procedimento PL/SQL concluído com sucesso.
=> De novo :
SYSTEM:@XE:SQL>insert into TAB_PDFS values(2, ‘Parte2/2 do curso de dblinks’, empty_blob());
1 linha criada.
SYSTEM:@XE:SQL>exec CARREGA_PDF(2, ‘database-links-masterclass_2.pdf’);
Tamanho do arquivo carregado: 420041
Tamanho da coluna blob: 420041Procedimento PL/SQL concluído com sucesso.
SYSTEM:@XE:SQL>commit;
Commit concluído.
SYSTEM:@XE:SQL>
E é isso, ok ??
[]s
Chiappa
IMPORTANTE : isto é SIMPLESMENTE UM EXEMPLO, de forma alguma use este código em produção, sim sim ?? Estude ele, EM CONJUNTO com os manuais Oracle, entenda os conceitos e aí escreva O SEU, yes ??
19 de fevereiro de 2018 às 11:50 pm #109192José Laurindo ChiappaModeradorBlz ? Só para estudos/referência, segue um exemplo fazendo que nem o Postgre faz, ie, chamando uma função na hora do INSERT, direto :
==> Apago os dados do meu teste anterior, mantendo o DIRECTORY, a tabela com a coluna BLOB e os arquivos a carregar :
SYSTEM:@XE:SQL>truncate table TAB_PDFS;
Tabela truncada.
=> Crio uma Function minha, pra “esconder” a chamada à package DBMS_LOB :
SYSTEM:@XE:SQL>create or replace function lo_import(p_filename varchar2) return blob is
2 bf bfile := bfilename(‘DOWNLOADS’,p_filename);
3 b blob;
4 begin
5 dbms_lob.createtemporary(b,true);
6 dbms_lob.fileopen(bf, dbms_lob.file_readonly);
7 dbms_lob.loadfromfile(b,bf,dbms_lob.getlength(bf));
8 dbms_lob.fileclose(bf);
9 return b;
10 end;
11 /Função criada.
==> PRONTINHO, posso inserir chamando uma função no meio do INSERT, que nem o Postgre faz :
SYSTEM:@XE:SQL>insert into TAB_PDFS values(1, ‘Parte1/2 do curso de dblinks’, lo_import(‘database-links-masterclass_1.pdf’) );
1 linha criada.
SYSTEM:@XE:SQL>insert into TAB_PDFS values(2, ‘Parte2/2 do curso de dblinks’, lo_import(‘database-links-masterclass_2.pdf’) );
1 linha criada.
SYSTEM:@XE:SQL>commit;
Commit concluído.
SYSTEM:@XE:SQL>
==> Posso consultar :
SYSTEM:@XE:SQL>select id_do_pdf, descr_do_pdf, dbms_lob.getlength(COLUNA_CONTENDO_PDF) as TAMANHO_DO_ARQ_CARREGADO from TAB_PDFS;
ID_DO_PDF DESCR_DO_PDF TAMANHO_DO_ARQ_CARREGADO
———- ——————————- ————————
1 Parte1/2 do curso de dblinks 402152
2 Parte2/2 do curso de dblinks 420041SYSTEM:@XE:SQL>
[]s
Chiappa
-
AutorPosts
- Você deve fazer login para responder a este tópico.