Em virtude de algumas perguntas realizadas pelos membros do site UsandoAccess com relação à utilização de imagens no MySQL, adiantei e resumi as informações neste artigo, visando o entendimento básico da inclusão de imagens no banco de dados.
Assim, irei demonstrar aqui, como anexar imagens a seu banco de dados e como recuperar essa informação.
Mais uma vez não vou levantar os prós e os contras de utilizar imagens anexadas a banco de dados. Cabe ao programador avaliar se vale à pena utilizar tal recurso. O objetivo dos artigos da série Acessando dados da Web é demonstrar a possibilidade de um Front-end Access conectar-se à uma base de dados em um servidor, coisa que até pouco tempo atrás, era tratada por muitos programadores, como mítica ou como "arquivos confidenciais".
No Microsoft Access, temos dois campos em que podemos anexar e gerenciar imagens: Objeto OLE e Anexo. Eles são responsáveis por receber dados binários: arquivos de sons, imagens, etc. O que difere um do outro é a forma com que os dados são armazenados e gerenciados.
No MySQL não é diferente! Nele, temos um conjunto de 04 campos responsáveis por receber informações binárias. São os campos do tipo blob.
Campo blob: afinal que bicho é esse?
Um BLOB (Binary Large OBject) é um grande objeto binário ou, dito de outra forma, uma coleção de dados binários, armazenados como uma entidade única, em um banco de dados. É usado para armazenar imagens, áudios, documentos, planilhas, arquivos compactados, arquivos executáveis e o que você mais desejar, para permitir que o arquivo em referência esteja ao alcance do usuário.
Tecnicamente, os blob's são equivalentes aos campos Objeto OLE e Anexo do nosso velho e bom Access!
Os blob's são divididos em quatro tipos (no MySQL), sendo que a diferença existente de um para o outro é unicamente a capacidade de armazenamento e trabalho do campo.
TINYBLOB: campo blob de armazenamento máximo igual a 255 caracteres (8 bits) mais 1 de controle;
BLOB: o mesmo que o Tinyblob, porém armazenando até 16535 caracteres (16 bits) mais 2 de controles;
MEDIUMBLOB: o mesmo que o tinyblob, porém armazenando até 16777216 caracteres (24 bits) mais 3 de controles;
LONGBLOB: o mesmo que o tinyblob, porém armazenando até 4294967295 caracteres (32 bits) mais 4 de controles.
1.	Não podem ser chaves primárias (excluindo Tinyblob);
2.	Não é possível usar os comandos GROUP e SORT com campos blob;
3.	São reconhecidos como um LONGVARCHAR para drivers ODBC.
Como não estamos trabalhando com um banco de dados com tabelas vinculadas, e sim ADO, temos que atentar para certos detalhes.
Se você espera "rodar" um Select em um campo blob e ver a imagem no seu controle, está enganado. Não funciona assim! Precisamos trabalhar com uma particularidade do ADO para poder visualizar o conteúdo do campo.
Outro detalhe muito importante é que os dados do campo blob, devem ser extraídos e salvos na forma do arquivo desejado, e finalmente, serem visualizados no seu controle.
Para isto, utilizamos um objeto do ADO: o objeto Stream
Falando rapidamente sobre ADO Stream Object
O objeto Stream do ADO é usado para ler, escrever e gerenciar um fluxo de dados binários ou de texto. É através dele que vamos recuperar os dados dos nossos campos blob.
Um objeto de fluxo pode ser obtido de três maneiras:
•	A partir de uma URL apontando para um documento, uma pasta ou um objeto de registro;
•	Ao instanciar um objeto Stream para armazenar dados para a sua aplicação;
•	Ao abrir o objeto Stream padrão, associado a um objeto de registro.
Como dito anteriormente, precisamos extrair o conteúdo de nosso campo blob para posteriormente carregar em nosso controle.
Para quem quiser se aprofundar no assunto, deixo o que considero os melhores links sobre a utilização do componente:
http://www.w3schools.com/asp/ado_ref_stream.asp
http://msdn.microsoft.com/en-us/library/windows/desktop/ms675032(v=vs.85).aspx
Criando o nosso campo blob, em nossa tabela
Como visto no último artigo, vamos recorrer ao nosso bom MySQl-Front para criar o nosso campo.
Vamos aproveitar a estrutura pronta da nossa tabela Contatos e adicionar os campos necessários para realizar a inclusão da nossa imagem.
Vamos incluir dois campos: um tipo longblob e outro varchar. O primeiro será responsável por receber os dados binários do nosso arquivo e o segundo, o nome do arquivo utilizado, para facilitar no momento da extração.
1.	Abra a conexão com seu banco de dados;
2.	Acesse o seu banco de dados de modo que visualize a estrutura de tabelas do mesmo;
3.	Selecione a tabela desejada (contatos);
4.	Clique na opção 'Add Field';
5. Em Name, dê um nome para o seu campo;
6. Em Type, escolha a opção LongBlob;
7. Realizada as configurações, clique em OK;
8. Repita a operação para o segundo campo e clique em OK.
Com esta operação, teremos dois campos:
•	Longblob, com o nome de anexo.
• Varchar, com o nome de anexo_name.
O campo anexo será responsável por receber os dados binários do nosso arquivo. O campo anexo_name receberá o nome original do arquivo para que possamos preservar o seu nome e no momento da extração, visualizá-lo em nosso formulário.
Agora que os nossos campos foram criados, vamos anexar e recuperar informações de um arquivo imagem. Lembrando que neste tipo de campo, poderemos armazenar outras informações, como um arquivo .PDF, por exemplo.
Anexando imagens em campos Blobs
A função Save_IMG é a responsável por salvar as informações dos campos anexo e anexo_name, em nossa base de dados MySQL.
Abaixo, preparei uma versão resumida da função para explicação do artigo. Ela está completa e funcional, no exemplo disponibilizado.
Private Sub Save_IMG()
Dim  mstream As New ADODB.Stream
mstream.LoadFromFile strfName
rs("anexo").Value = mstream.Read
strfName = Empty
Observem que instanciei o objeto Stream do ADO em mstream. Ele é o responsável por ler os dados binários do arquivo.
.Type: em 'adTypeBinary' informo como o ADO deverá tratar o arquivo em referência.
.Open: comando para que ADO abra o arquivo no modo informado.
.LoadFromFile: aqui, estou carregando o arquivo que desejo salvar no servidor.
.read: neste momento, ele lê o conteúdo binário de nosso arquivo, passando a seqüência de zeros e uns, para o nosso select, alimentando o respectivo campo anexo.
.close: fecho a Stream e realizo o update no nosso select.
Na nossa tabela, no MySQL, você verá o conteúdo salvo da seguinte forma:
No MySQL, você poderá visualizar o conteúdo do campo blob de duas maneiras: em modo Imagem e em modo Hexa Decimal, como mostra a imagem abaixo:
Recuperando imagens de campos Blobs
Agora, vamos fazer o processo inverso!
Como disse anteriormente, você não lerá o conteúdo de um campo blob através do seu select. Se você tentar visualizá-lo, em resposta ao código binário carregado, será exibido para você um conjunto de "??????".
Como o que eu tenho dentro do nosso campo é um conjunto de informação binária, preciso salvar seu conteúdo em um arquivo em seu disco rígido, e posteriormente visualizá-lo em nosso formulário.
Para isso, vamos utilizar a função 'Exporta_Imagem':
Private Sub Exporta_Imagem()
MySQL = "select * from contatos where Id=" & Me.Lista.Column(0)
Call Conexao_Open(MySQL)
MyFile = Application.CurrentProject.Path & "\img\" & Me.anexo_name
If Not IsNull(rs.Fields("anexo").Value) Then
mstream.Write rs.Fields("anexo").Value
mstream.SaveToFile MyFile, adSaveCreateOverWrite
Me.img.Picture = MyFile
Observe que estou lendo o conteúdo de nossa tabela através de um Select. Se tentarmos ler o conteúdo do campo anexo, tudo que teríamos seria uma série de caracteres inválidos. Precisamos pegar este conteúdo e gravá-lo em um arquivo!
Este processo novamente é feito pelo Stream, como demonstrado abaixo:
.Type: em 'adTypeBinary' inform como o ADO deverá tratar o arquivo em referência.
.Write: aqui, estou iniciando o processo de escrita dos dados carregados para um arquivo.
.SaveToFile: aqui, salvo os dados em um arquivo no disco rígido.
Com estas duas operações, temos a visualização, em tempo "real", em nosso formulário.
Segue o link para você baixar o arquivo exemplo.
AccessWeb3.zip
Espero que este artigo da série Acessando dados da Web também lhe seja útil, e que possa colocá-lo em contato, de uma forma simples e descomplicada na utilização de Access, com uma base de dados na Web.
Sandré Cardoso 06/05/2019 05:47:39
estou querendo pegar a imagem blog de um objeto ole no access para mostrar em pagina web atraves do mysql nele coloquei um campo foto do tipo longblob mas n'ao funcionou so aparece o codigo binario
ALYSON RONNAN MARTINS 03/05/2019 06:53:13
Bateu uma dúvida agora. Imagine que o anexo for alterado no servidor, como fazemos para saber se a imagem já carregada está atualizado para se for o caso carregar ela novamente ?
Roberto Pereira 21/11/2017 06:27:57
Otimo artigo, uma ajuda enorme aos desenvolvedores....
Marcos Medeiros 26/11/2015 18:01:11
Os 3 artigos sobre conexão MySQL e Access são ótimos, parabéns!
sidnei 14/07/2015 11:00:25
Estou começando agora a utilizar o access, mas estes artigos são awsome!!! Parabéns mestres Jedis!!!!
Flavio Nascimento 04/09/2014 10:22:50
Muito bom caro Jefferson.. Parabens....
nascimento_flavio@hotmail.com
011 99845-6262
Eloir Peretti 17/07/2014 09:54:10
Eu já tinha buscado no bom e velho Google, mas não havia conseguido resolver...
Por fim criei uma pasta dentro da pasta Img e funcionou... testei em casa e deu o mesmo problema e apliquei a mesma solução... vai saber porque....rsss
MyFile = Application.CurrentProject.Path & "\img\teste\" & Me.anexo_name
Avelino Sampaio 16/07/2014 06:32:05
em uma rápida pesquisa pelo google encontrei o seguinte sobre o erro 3004:
3004 Erro: Falha no ambiente de abrir banco de dados, caminho inválido especificado _ _.
"Se este erro ocorre após a instalação e iniciar o servidor de retransmissão, talvez você tenha especificado um caminho de banco de dados inválido depois que você modificou um caminho no registro do Windows (para mover um banco de dados de retransmissão, por exemplo). Desinstalar, reinstalar o Relay server e verifique se as informações de caminho. Se o erro persistir, entre em contato com o suporte da Microsoft para obter ajuda."
Farei uma consulta ao Jeferson se ele tem uma solução para este problema.
Eloir Peretti 15/07/2014 18:51:57
Eu baixei o exemplo apenas mudei a base de dados para minha base MySQL, porém chegou a rodar e depois começou a dar um erro:
Erro em tempo de Execução '3004': Falha ao gravar o arquivo!
JBSR 02/11/2013 11:10:41
Os campos blob armazenam dados binários. Qualquer arquivo a ser anexado, é um arquivo binário, seja ele texto, imagem, ou até mesmo um .mdb
Assim, o processo para inclusão de um arquivo em um campo blob, é o mesmo processo apresentado para o arquivo de imagem.
Você deve considerar apenas, os tipos de campo blob existentes, pois são três, e cada um deles armazena uma quantidade binária de dados diferente. Utilize o Blob long (se não me falha a memória)
madson braz 01/11/2013 18:03:27
Os passos deste processo é o mesmo para um BLOB do tipo texto?
Valdino 11/03/2013 22:05:19
Eu ainda não tinha testado o exemplo. Resolvi testá-lo agora e, após os devidos ajustes, funcionou bem no meu servidor online. Só deixaria como dica carregar todas as colunas na listbox e ao invés de fazer a consulta direta no servidor, usar as colunas da listbox já carregada e deixar o servidor apenas para atualizar a listbox de tempos em tempos. Dessa forma, caso o servidor fique fora do ar, os dados estão carregados na listbox. É só uma dica mesmo.
joão bola 10/03/2013 21:15:06
Olá to tentando alterar esse exemplo 3 para o meu caso mais nao to conseguindo. o exemplo funciona certim mais quando altero para os meus dados nao funciona. o pessoal do servidor do meu site falou que eu tinha que usar o ip no lugar do endereço mais mesmo assim nao da. tem que alterar mais algo na config ou so na tabela aonde tem o servidor e usuario e senha? eu tentei mudar o servidor e o login e o usuario e a tabela e senha essas coisas e tambem os campos da tabela claro.
Avelino Sampaio 03/08/2012 06:40:25
dos 30 usuários, quantos usam o BD intensamente ?
O volume de informações vem crescendo significativamente ? Quantos mega bytes por mês vem crescendo ?
Tem a pretenção de compartilhar os dados em rede externa ?
vinicios 02/08/2012 17:33:56
Boa tarde, tenhos alguns sistemas em ACCESS e agora preciso melhora-los, o correto e ir para o SQL 2008 express ou Mysql, qual seria o mais indicado, sistema em rede local com 30,usuarios aproximandamente.
Murilo Rosa 28/06/2012 11:00:49
JBSR, a nivel de consulta entre varias tabelas, como seria feito?
Para toda consulta eu abriria a tabela com o código e fechariam já que exite o time-up nativo?
Sempre desenvolvi aplicações com os BE vinculado, realmente perde-se um pouco de desempenho, mais facilita muito.
Outra dúvida, não seria mais viavel se trabalhar com imagens em Pastas\Subpastas ao inves de gravad no BD fisicamente?
JBSR 15/06/2012 09:49:53
Murilo, quando você trabalha com o MySQL e o Access o processo de vinculação de tabelas não funciona do mesmo jeito no Access.
O ODBC tem a configuração de time-up, que é de apenas 60 segundos. Apos esse intervalo, todas as conexões são interrompidas.
Para utilizar o processo de vinculação, você terá que alterar esse tempo, o que vai impactar no desempenho da conexão, da mesma forma que ocorre com o Access quanto há muitoso usuários logados no mesmo banco de dados.
Vale conferir a Parte 2, pois é o melhor processo de se trabalhar com o MySQL e o Access.
Murilo Rosa 14/06/2012 10:43:40
Como citado na Parte 1 desse Tutorial. Esse modelo utilizando o ODBC e ADO seria para poucas conexões.
Em casos de multiconexões o indicado seria o próprio vinculação via ODBC nativa do Access???
Avelino Sampaio 27/05/2012 12:25:35
veja se neste link abaixo tem a solução:
http://ajuda.maxrevenda.com.br/resolvendo-problemas-de-caracteres-acentuados-no-mysql/
Cristiano 17/05/2012 10:50:51
Tenho um banco de dados no accesss vinculado ao banco de dados externo.
Quando abro o access a formatação do texto esta desconfigurada por exemplo a palavra associação quando eu conecto apare assim: ASSOCIAÇÃO.
Jael 03/12/2011 13:37:33
Avelino, muito obrigado pela resposta. Alimentar uma tabela já criada resolveria meu problema. Mas a minha grande dificuldade é alimentar essa tabela a partir de um recordset ado aberto. Será q vc poderia pelo menos colocar um exemplo pra eu adpatar. Avelino muito obrigado!!
Avelino Sampaio 03/12/2011 05:53:19
não seria mais simples vc deixar a tabela já previamente criada e depois só ir alimentando os campos com os dados?
Lembrando que sempre for alimentar a tabela, faça uma limpeza antes. Exemplo:
Currentdb.execute "DELETE FROM NomeDaTabela;"
Jael 01/12/2011 22:13:34
Jefferson, muito obrigado pelos conteudos q vc disponibiliza pre gente, vc, avelino são muito gente boa. Mas pelo amor de Deus, estou sofrendo tentando criar uma tabela temporária a partir de um recordset ado. Será q vc Jefferson não poderia me dá uma luz e colocar aki pelo menos como eu consigo criar essa tabela temporária. Gostaria de criar essa tabela pra servir de fonte para meus relatórios. Todo o conteudo q vc disponibiliza aki, eu consegui botar em prática. Deus te ajude muito!!
GILAILSON - CE 17/11/2011 15:08:24
Gosto muito deste site... Um dia eu adquiro o monta Ribbons e Todos os artigos...Estou só juntando tutu.
GILAILSON - CE 17/11/2011 15:07:09
Seria muito legal se fosse feito um tutorial de como utilizar a API - AutoCompile do internet explorer no access, pois é um recurso muito útil para os usuários, evitando perca de tempo em pesquisa de produtos, fornecedores essas coisas.
MARCIO MELO - RJ 10/11/2011 19:53:59
Estou maravilhado com os artigos Acessando dados da Web, acabei adquirindo outro site na web e dessa vez na versão windows server só por causa desses artigos e outros que se faz necessário, pois o server linux é realmente superior. Estou me preparando para aprender mais na prátca montanrei em breve meu laboratório com todas essas aulas, já baixei e testei tudo e foi uma surpresa super satisfatória merece uma programação O.O. nessa interfase de forma a deixar as tabelas o máximo livres, garantido o desempenho, tudo que um dia sonhei... possibilidade de compartilhar tabelas online.
Muito agradecido ao Srº Jefferson Braz por compartilhar seu conhecimento com uma didática prática e ao Avelino por sua iniciativa e espaço.
JBSR 10/11/2011 14:11:22
avelino joao 09/11/2011 12:39:24
Avelino e Jeferson muito obrigado pelas aulas que estão passar no teu site, Jeferson gostei muito pela maneira como atribui o endereço da base de dado através de uma tabela, gostaria voces tambem falam um pouco sobre sql server.
Muito obrigado por tudo Avelino e Jeferson muito sucesso no vossos projectos.
Jorge Brito 08/11/2011 09:40:04
Muito bem Avelino e o Jeferson estão de parabéns.
Mas venho aqui deixar uma questão?
Eu necessito criar um servidor da minha rede INTERNA com o wampserver
e criar um código no meu Front End feito em Access para andar comigo na minha pen USB
pois assim posso actualizar a minha base de dados que se encontra no servidor que esta na Oficina.
Só não sei quais são as voltas a dar?
se poderem dar uma dica
Jossua Marshal 07/11/2011 20:23:12
O Avelino e o Jeferson estão tirando conteudo do forno igual a biscoito...
Muito bom o artigo. Quando vai ser o próximo?! Falar sobre consultas no MySQl e sobre Procedure seria bem interessante.