Galera, boa tarde.
Olha nóis aqui outra vez, mas uma dica para vocês.
Na dica de hoje vou apresentar como podemos armazenar arquivos de imagem no formato .jpeg e .jpg no Microsoft SQL Server 2008 R2.
Um dos maiores questionamentos que conheço na área de Banco de Dados, esta relacionado ao armazenamento de imagens no Banco de Dados. Dentre estes, gostaria de destacar:
- Quais o benefícios em se armazenar uma imagem no Banco de Dados?
- Teria perda de performance em armazenar uma imagem no Banco?
- Qual tipo de dados utilizar, Image ou Varbinary?
- Minha aplicação vai conseguir acessar normalmente o conteúdo da imagem?
E por ai vai, são inúmeras as dúvidas, ressalvas, questionamentos e até mesmo falta de conhecimento. Responder neste momento todos estes questionamentos, com certeza vai requerer muito tempo, como também, uma série de levantamentos de acordo com o cenário, necessidade e regras de negócio.
Eu particularmente sou mais conservador e procuro sempre levar em consideração se realmente é necessário armazenar este tipo de informação em um banco de dados, ainda mais nas últimas versões do Microsoft SQL Server 2008 e R2 que podemos fazer uso do FileStream para acesso direto a arquivos em disco, como também, no Microsoft SQL Server 2012 através do Filetable em conjunto com o FileStream.
Mesmo assim, com toda esta gama de recursos e facilidades procuro sempre alertar meus clientes, alunos e amigos de alguns impactos que considero básicos ao armazenar uma imagem no banco de dados:
- Aumento no tamanho do banco;
- Sobrecarga de processamento nas transações;
- Aumento do tamanho do arquivo de backup;
- Aumento no tempo de execução e restauração do backup; entre outros.
Pois bem, deixando de lado, estas considerações, vou tentar demostrar de forma simples como podemos fazer a carga de dois arquivos com extensão .jpg armazenados fisicamente em disco para uma tabela no Microsoft SQL Server 2008 R2 utilizando o tipo de dados Varbinary. Vale ressaltar que este tipo de dados foi introduzido a partir do SQL Server 2005 SP2, desde então considerado o melhor tipo de dados para se trabalhar com valores binários ou dados que serão tratados como binários.
Vamos lá, o código de exemplo utilizado nesta dica é bastante simples, inicialmente realizamos a criação de uma tabela denominada Imagens, conforme apresenta o Código 1, apresentado a seguir:
— Código 1 – Criando a Tabela Imagens –
Create Table Imagens
(
Codigo Int Identity(1,1) Not Null Primary Key,
NomedoArquivo Varchar(1000) Not Null,
Arquivo Varbinary(Max)
)
Após a criação da tabela, podemos passar para o segundo passo, que consiste na Carga dos arquivos “Assinatura.jpg” e “Imagem.jpg”, ambos localizados na pasta C:\Temp da Minha máquina para o meu Banco de Dados.
Este é o passo mais importante, pois estaremos utilizando o comando OpenRowSet em conjunto com a opção Bulk, realizando os seguintes passos:
- Identificação, acesso e leitura do conteúdo do arquivo em disco;
- Interpretar este conteúdo que será enviado para o SQL Server; e
- Realizar a conversão dos arquivos para o formato Varbinary.
Em todos estes passos, o comando OpenRowSet, não realiza qualquer tipo de sobrecarga de processamento por parte do SQL Server, ele trabalha de forma independente, utilizando so capacidade de acesso direto a dados, para somente ao final deste processo começar a fazer o envido destes dados para o SQL Server.
Observação: Através do comando OpenRowSet, conseguimos fazer acesso direto a dados disponibilizados em servidores remotos. Este comando tem como facilidade fazer uso de métodos únicos de acesso através de comunicação ad-hoc.
Bom, vamos então apresentar o segundo passo, denominado Código 2:
— Código 2 – Carga dos arquivos para a tabela Imagens –
INSERT INTO Imagens(NomedoArquivo, Arquivo)
SELECT ‘Image.jpg’, *
FROM OPENROWSET(BULK N’C:\Temp\Image.jpg’, SINGLE_BLOB) Load;
INSERT INTO Imagens(NomedoArquivo, Arquivo)
SELECT ‘Assinatura.jpg’, *
FROM OPENROWSET(BULK N’C:\Temp\Assinatura.jpg’, SINGLE_BLOB) Load;
Pronto agora que já conhecemos o Código 2, fica bem mais fácil entender a sua função e importância. Podemos notar que além do comando OpenRowSet e da opção Bulk, devemos também especificar que tipo de formato de arquivos estamos fazendo a carga para dentro do SQL Server. Isso é facilmente definido em nosso código através da opção Single_BLOB, onde estaremos informando para o SQL Server, que o trata-se de um simples objeto binário de grande tamanho.
Após isso, nossos dados já estão gravados no SQL Server, o que nos resta é fazer um simples Select consultando os dados nesta tabela que serão apresentados na Coluna Arquivo de forma Binária. Para que você possa apresentar estas imagens de uma forma legível, utilize qualquer aplicação ou gerador de relatórios fazendo uso de componentes do tipo Image, responsáveis em decodificar e converter o conteúdo binário em pontos mapeados conhecidos como bitmap.
Bem, mais uma vez quero agradecer a sua visita, vou encerrando mais esta dica por aqui.
Nos vemos por ai, em breve.
Valeu.
Meu amigo, muito bom seu artigo. Estou precisando armazenar em um banco de dados um arquivo XML. Posso utilizar o tipo de dados Varbinary? se eu precisar recuperar o arquivo do banco e gera-lo fisicamente novamente em uma pasta, qual seria o comando do SQL Server?? Abraços.
CurtirCurtir
Alexandre, bom dia.
Quero agradecer a sua visita ao meu blog. Espero poder ajudar.
Vamos com partes:
1 – Você deseja utilizar um arquivo XML e converter para Varbinary?
A resposta é sim, isso é possível de ser feito, você vai necessitar utilizar conversão explícita.
2 – Para gerar o arquivo em disco com os dados do seu banco, você poderá fazer isso através da ferramenta BIDS ou também utilizando o comando SQLCMD ou BCP. Sendo todos ferramentas externas do SQL Server.
Basicamente essas seriam as possibilidade iniciais.
Até mais.
CurtirCurtir
Excelente post, realmente deu certo aqui, uma outra perfunta, a possibilidade de eu importar um arquivo .PDF? e como faco para ler esse arquivo? Obrigado
CurtirCurtir
Poxa aqui não tá rolando :´(
tá dando o seguinte erro:
Cannot bulk load because the file “C:\Users…” could not be opened. Operating system error code 5(Acesso negado.).
Code Snipet:
INSERT INTO imagem (nomeImg,imgBinar)
SELECT ‘foto.jpg’,
* FROM OPENROWSET (BULK ‘C:\Users\…’,SINGLE_BLOB)LOAD;
O que que tô fazendo de errado????
Valeu e Parabéns pelo Blog, explanações claras e bastante detalhadas sem perder a objetividade!!!!
CurtirCurtir
WAlves, bom dia.
A mensagem de erro é clara, esta faltando permissão na pasta que contém os arquivos que você deseja utilizar no bulk.
CurtirCurtir
Então Junior, o problema é justamente esse!!! Por que não tenho permissão? estou fazendo isso no meu PC, meu perfil é ADMIN, to logando no banco com usuário sa, já tentei colocar o arquivo na area de trabalho compartilhada e nada…
CurtirCurtir
Codex,
De qual permissão você se referi? O usuário SA é System Administrator do SQL Server, ele não tem nenhuma relação com a parte de File Server do Windows, um teste que você poderia fazer é adicionar o seu usuário administrador na permissões da pasta ou em último caso o usuário Everyone.
Até mais.
CurtirCurtido por 1 pessoa
Olá Junior, parabéns pelo material, gostei bastante. Mas gostaria de uma informação adicional: preciso armazenar diversos tipos de documentos (jpg, xls, pdf, doc, etc…) e tenho utilizado apenas uma indexação no banco SQL. Existe alguma forma de salvar esses arquivos também no SQL como sugere com as imagens jpg ?
Obrigado,
Abraços,
Eduardo
CurtirCurtir
Eduardo, boa noite.
Obrigado por sua visita e comentário.
Em relação a sua dúvida você pode sim fazer o armazenamento deste tipo de arquivo utilizando o tipo de dados varbinary. A partir da versão 2012 a Microsoft adicionou o recurso chamado filetable que permite justamente armazenar de forma direta um arquivo em file system e ser acessado todas as informações e estrutura do arquivo diretamente no SQL Server.
Acredito que este pode ser o seu caminho.
Até mais.
CurtirCurtir
Lá no select vc usa o * não é isso .
Será que no lugar do asterisco eu não poderia colocar o nome da coluna por que o meu tá dando erro de subconsuta.
CurtirCurtir
Quero apenas trazer o arquivo sem o nome vc pode me ajudar?
CurtirCurtir
Oi Albert,
Sem o nome do que?
CurtirCurtir
Sem o nome da foto mas já conseguir obrigado.
CurtirCurtir
Albert, bom dia.
Sim, você pode fazer este teste.
CurtirCurtir
Vc sabe importa tabelas do Excel do formato xlsx para o sql Server será se tem Como?
CurtirCurtir
Albert, bom dia.
Sim, é possível, você pode fazer da mesma forma que os arquivos .xls.
CurtirCurtir
Albert,
Você poderia compartilhar a maneira que conseguiu importar as fotos.
CurtirCurtir
Insert into Pessoa values (
select * from openrowset (bulk ‘caminho das imagens\nome_da_imagem.jpg’,single_blob)load)
CurtirCurtir
É uma forma ruim por que tenho uma tabela com 80 imagens então teria que repetir esse código 80 vezes mas é melhor forma que já encontrei.
CurtirCurtir