- Este tópico contém 7 respostas, 2 vozes e foi atualizado pela última vez 7 anos, 6 meses atrás por José Laurindo Chiappa.
-
AutorPosts
-
16 de maio de 2017 às 10:51 pm #108754airoospParticipante
Boa tarde,
Estou pesquisando informações sobre como gravar uma imagem e/ou arquivo pdf no banco de dados. Entendi que o processando usando procedure só funciona se for criado um diretório no servidor onde o banco de dados esta instalado. (create directory e depois grant read, write on …)
É isso mesmo? Dessa forma o usuário do SO precisará ter acessa a uma pasta do servidor, o que acaba comprometendo a segurança.
Alguém tem alguma ideia/dica?
Exemplo, gravar o arquivo imagem1.jpg da minha estação de trabalho no banco de dados 10g com Windows.
Obrigado.
Airton
17 de maio de 2017 às 12:34 am #108755José Laurindo ChiappaModeradorSeguinte : se vc for programar ** diretamente ** no database, as ** duas ** linguagens-padrão do database Oracle (ie, SQL e PL/SQL) *** não possuem *** comandos para vc enviar dados binários pela rede : TODAS as built-ins capazes de ler um arquivo (ie, DBMS_LOB.LOADFROMFILE, UTL_FILE, EXTERNAL TABLES, etc) ** exigem ** que o arquivo a ser lido esteja PRESENTE numa pasta/diretório diretamente acessível pelo RDBMS, o que implica em ** OU ** vc usar uma pasta/diretório criada fisicamente no próprio servidor (no seu caso, a máquina-cliente teria que enviar o arquivo via FTP ou SCP ou coisa assim (até EMAIL que seja, se o servidor Oracle tem acesso ao servidor de email) para o servidor Oracle), ** OU ** então vc pode usar um dos recursos que permitem que o servidor do RDBMS ‘enxergue’ uma pasta dum servidor remoto como se fosse local (ie, usar um mount-point NFS ou Samba ou share de Windows)…. E que fique BEM CLARO :
a. o usuário final *** NÃO VAI LOGAR **** na máquina do RDBMS, nunca, de maneira alguma : se vc usar a opção de enviar o arquivo da máquina do usuário para o servidor do RDBMS Oracle, vai haver algum PROGRAMA NÃO-INTERATIVO, com senha criptografada, que vai fazer o FTP ou o SCP da máquina do usuário para o servidor do RDBMS
b. para EVITAR que cada máquina de cada usuário tenha um diretório compartilhado é TOTALMENTE POSSÍVEL vc usar um Combinação de técnicas, tipo : há um servidor de arquivos, o usuário grava lá o arquivo que quer enviar pro banco (via um share Windows montado como um drive local na máquina dele), e depois uma OUTRA rotina transfere o arquivo pro servidor Oracle, ** OU ** então o servidor Oracle acessa o servidor de arquivos via NFS/Samba/Windows share/o que vc tiver/puder…
==> Já se NÃO FOR OBRIGADO a programar diretamente dentro do database, aí sim vc tem Opções diversas para escrever um programa que vai estar sendo executado na máquina-cliente (ou no Browser da máquina-cliente, que seja), fazer com que seu programa leia o arquivo desejado, abra uma conexão com o banco e envie pela rede esse arquivo binário pro servidor do banco ou mesmo direto pro database…. Três opções comuns de programação para isso são :
a. JAVA : http://www.dba-oracle.com/t_insert_image_blob_client_pc.htm é um exemplo
b. APEX : http://oracledba.bigresource.com/Application-Express-direct-file-upload-from-end-user-machine-to-sftp-server–Mr3433ZnF.html é um exemplo
c. Oracle Forms : desde muito tempo o Forms tem a capacidade de criar um item de tela que reflete uma coluna de uma tabela no database (o que o Forms chama de DATABASE ITEM), aí tudo que vc inserir nesse objeto do programa (inclusive um arquivo binário que vc leu do cliente) vai ser enviado e gravado pro database… Eu fiz isso muito na época do Forms 6i client/server, hoje em dia o Forms é WEB então talvez algum ponto mais seja necessário mas o conceito ainda existe afaik..
Mas muitas outras linguagens de programação externas ao database são capazes de ler arquivos na máquina-cliente onde estão sendo executados, abrir uma conexão ao banco e enviar pedaços binários pro banco, a serem inseridos numa coluna BLOB que p programa abriu na sessão….
EU, PESSOALMENTE, não tiver quase nenhuma experiência com essas opções externas ao database (exceção feita ao Forms), pois sempre que precisei apelei pra alguma das built-ins do banco e ou enviei o arquivo ou compartilhei com o servidor Oracle uma máquina remota que continha o arquivo….
[]s
Chiappa
17 de maio de 2017 às 9:10 pm #108756José Laurindo ChiappaModeradorBlz ? Dois detalhes que esqueci de dizer : são meio Óbvios, mas acho que vale a pena os citar claramente…. São eles :
a. SE as máquinas dos usuários finais tem acesso direto ao banco via rede (isso *** não *** é Comum, normalmente por uma questão de segurança as pessoas conectam pela rede no servidor de Aplicação e é o servidor de aplicação que conecta no banco), E essas máquinas possuem o software cliente Oracle full instalado, vc ** NÃO PRECISA escrever o seu programa externo que lê o arquivo binário residindo na máquina do usuário e o envia pela rede para o banco : junto com o software cliente Oracle a Oracle já nos dá um programa PRONTINHO capaz de fazer isso, esse programa se chama SQL*LOADER…. Usando o exemplo em http://www.idevelopment.info/data/Oracle/DBA_tips/LOBs/LOBS_9.shtml, veja abaixo que consegui fazer isso de boas : EVIDENTEMENTE, a interface dele não é muito amigável, vc provavelmente faria o seu aplicativo executar automaticamente para o usuário o sql*loader.
O exemplo :==> mostro que os arquivos binários que quero carregar estão na minha máquina de usuário local :
[oracle@localhost ~]$ ls -ltr
total 327280
….
drwxrwxr-x 3 oracle oracle 4096 May 17 13:39 tmp
-rw-rw-r– 1 oracle oracle 4200 May 17 13:44 scsi_se.gif
-rw-rw-r– 1 oracle oracle 5041 May 17 13:44 scsi_hvd_diff.gif
-rw-rw-r– 1 oracle oracle 3505 May 17 13:44 scsi_lvd.gif
-rw-rw-r– 1 oracle oracle 4279 May 17 13:44 scsi_lvd_se.gif==> veja que meu PC (Linux no caso) tem acesso via rede ao meu banco remoto (neste caso um XE sob Windows mas não importa) :
[oracle@localhost ~]$ tnsping XE_SID
TNS Ping Utility for Linux: Version 11.2.0.2.0 – Production
Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.1)(PORT = 1521))) (CONNECT_DATA = (SID = XE)))
OK (0 msec)
[oracle@localhost ~]$==> lá no banco de dados eu tenho uma tabela para onde quero carregar meus binários – vou criar uma tabelinha-exemplo :
[oracle@localhost ~]$ sqlplus system/oracle@xe_sid
Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 – 64bit ProductionSYSTEM:@xe_sid:SQL>
CREATE TABLE test_blob (
id NUMBER(15)
, username VARCHAR2(30)
, file_name VARCHAR2(1000)
, image BLOB
, timestamp DATE
)
/Table created.
SYSTEM:@xe_sid:SQL>exit
Disconnected from Oracle Database 11g Express Edition Release 11.2.0.2.0 – 64bit Production==> para que a “mágica” aconteça preciso de um control file, que indica pro sql*loader o nome da tabela e as especificações de onde carregar os dados :
[oracle@localhost ~]$ cat load_test_blob_data.ctl
load data
infile *
replace
into table test_blob
FIELDS TERMINATED BY ‘,’
(
id INTEGER external
, username CHAR
, file_name CHAR
, image LOBFILE(file_name)
TERMINATED BY EOF
NULLIF file_name=’NONE’
, timestamp SYSDATE
)
begindata
1,JHUNTER,scsi_se.gif
2,MHUNTER,scsi_hvd_diff.gif
3,AHUNTER,scsi_lvd.gif
4,AHUNTER,scsi_lvd_se.gif[oracle@localhost ~]$
==> ok, com toda a config em cima, é só chamar o sql*loader a partir da minha máquina : como eu disse, é ESTA CHAMADA e ESTA config de cima que vc faria sem seu usuário ver :
[oracle@localhost ~]$ sqlldr userid=system/oracle@xe_sid control=load_test_blob_data.ctl log=load_test_blob_data.log
SQL*Loader: Release 11.2.0.2.0 – Production
Commit point reached – logical record count 5
==>> PRONTINHO, “mágica” feita, o meu PC de usuário final transmitiu os arqs binários pela rede E os gravou no BLOB adequado :
[oracle@localhost ~]$ sqlplus system/oracle@xe_sid
Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 – 64bit ProductionSYSTEM:@xe_sid:SQL>select * from test_blob;
ID USERNAME FILE_NAME
———- —————- ——————————————————————–
IMAGE
———————————————————————————————————————————
TIMESTAMP
———
1 JHUNTER scsi_se.gif
47494638396170008900F70000000000FFFF00FFFF08FFFF10FFFF18FFFF21FFFF29FFFF31FFFF39FFFF42FFFF4AFFFF52FFFF5AFFFF63FFFF6BFFFF73FFFF7BF
……
17-MAY-172 MHUNTER scsi_hvd_diff.gif
4749463839618C008C00F70000000000FFFF00FFFF08FFFF10FFFF18FFFF21FFFF29FFFF31FFFF39FFFF42FFFF4AFFFF52FFFF5AFFFF63FFFF6BFFFF73FFFF7BF
….
17-MAY-173 AHUNTER scsi_lvd.gif
47494638396161008800F70000000000FFFF00FFFF08FFFF10FFFF18FFFF21FFFF29FFFF31FFFF39FFFF42FFFF4AFFFF52FFFF5AFFFF63FFFF6BFFFF73FFFF7BF
…
17-MAY-174 AHUNTER scsi_lvd_se.gif
47494638396171008900F70000000000FFFF00FFFF08FFFF10FFFF18FFFF21FFFF29FFFF31FFFF39FFFF42FFFF4AFFFF52FFFF5AFFFF63FFFF6BFFFF73FFFF7BF
…
17-MAY-17SYSTEM:@xe_sid:SQL>
b. eu não o disse mas se vc for optar pela solução de fazer o usuário transferir o arquivo da máquina dele prum servidor único (que depois vc compartilha com o servidor Oracle via Samba, Windows filesharing, NFS, o que for, OU então esse servidor intermediário é que transfere o arquivo pro servidor Oracle, para que depois vc use as built-ins do banco pra carregar pra tabela) , Logicamente vc NÂO PRECISA ter um servidor de arquivos dedicado só pra isso : hoje em dia é comum, como eu disse acima, que exista um servidor de Aplicação, que naturalmente já se conecta via rede com o servidor Oracle….
[]s
Chiappa
18 de maio de 2017 às 4:39 pm #108757airoospParticipanteChiappa,
Agradeço a solução que você passou usando o sqlloader, fiz o teste aqui e funcionou. O detalhe é que, para usar o sqlloader vou ter que montar o arquivo .CTL de acordo com o arquivo de imagem que o usuário passar, pois o objetivo do processo é arquivar no banco imagens de ocorrências.
Um outro teste que fiz foi criar uma pasta na minha estação de trabalho, atribuir a permissão de leitura, e no DIRECTORY criado no banco consegue fazer ele acessar a pasta usando \CPU….PASTA, dessa forma o usuário copia o arquivo para esta pasta e ao executar a procedure, a mesma faz a carga da imagem.
Obrigado.
Airton
18 de maio de 2017 às 8:32 pm #108758José Laurindo ChiappaModeradorSegue minha resposta e obs para cada item :
“Agradeço a solução que você passou usando o sqlloader, fiz o teste aqui e funcionou.”
==> Sim, se a máquina de usuário onde está o arquivo a enviar pra coluna LOB possui acesso ao servidor Oracle pela rede E possui o client Oracle full instalado yep, o sql*loader foi FEITO para carregar dados de arquivos nessas condições…. A dúvida, como eu disse, era SE o teu ambiente estava assim configurado, pois Não É raro que as máquinas dos usuários NUNCA tenham acesso pela rede ao servidor do banco de dados mas sim a um servidor de aplicações : se teu ambeinte não é aasim okdoc, nenhum impedimento….
“O detalhe é que, para usar o sqlloader vou ter que montar o arquivo .CTL de acordo com o arquivo de imagem que o usuário passar, pois o objetivo do processo é arquivar no banco imagens de ocorrências.”
==> Sim, mas o arquivo de controle do sql*loader é um simples arquivo-texto ASCII, que pode ser criado facilmente – e relembrando, já que vc NÃO VAI exigir que o usuário rode na mão o sql*loader, vc VAI mesmo ter que criar algum front-end para que o usuário acione o loader, então Não Vejo assim tanta dificuldade para que esse mesmo front-end que vc vai criar também já crie um arquivo de controle apropriado para o(s) arquivo(s) a serem carregados….
“Um outro teste que fiz foi criar uma pasta na minha estação de trabalho, atribuir a permissão de leitura, e no DIRECTORY criado no banco consegue fazer ele acessar a pasta usando \CPU….PASTA, dessa forma o usuário copia o arquivo para esta pasta e ao executar a procedure, a mesma faz a carga da imagem.”
==> Sim, quando eu citei ‘compartilhamento Windows’ era em algo assim que eu estava pensando : o ponto é que normalmente numa rede Emptresarial o acesso via UNC (com \) ** não ** é Automático, pede alguma config de rede/permissionamento, ou pede instalação de software de compartilhamento NFS-like…
SE na sua rede isso não é assim e basta criar a pasta na máquina-cliente que o servidor Oracle já enxerga okdoc, maravilha : é uma Excelente opção também….[]s
Chiappa
18 de maio de 2017 às 8:35 pm #108759José Laurindo ChiappaModeradorAh, detalhe : obviamente, para que possam ser acessadas pelo servidor do Oracle via UNC , as máquinas ** todas ** dos usuários que possuam arquivos a serem carregados PRECISAM criar pastas, e lá no RDBMS vc TEM que criar um DIRECTORY para cada pasta de cada máquina…
Se isso não te afeta em nada ok, vai em frente….[]s
Chiappa
18 de maio de 2017 às 10:16 pm #108760airoospParticipanteChiappa,
Para a solução que estou adotando, usei as informações que você passou, mas algumas coisas que pesquisei. Quanto aos acessos para os usuários utilizarem a aplicação, estes terão que ser definidos, pois eu consigo fazer devido as permissões que tenho.
Mas acredito que definindo algumas regras não será problema.Obrigado.
Airton
19 de maio de 2017 às 12:30 am #108761José Laurindo ChiappaModeradorBlz… Agora que vc tem as infos necessárias todas vc tá tranquilo pra escolher e desenvolver a melhor solução…
[]s
Chiappa
-
AutorPosts
- Você deve fazer login para responder a este tópico.