Como exportar uma coluna de imagem para arquivos no SQL Server?

13

Vou migrar de um banco de dados. Há uma coluna do tipo imageque eu gostaria de exportar para arquivos binários no sistema de arquivos. Um arquivo para cada registro. Como posso fazer isso com o SQL Server?

Jonas
fonte
1
Uma boa postagem de Amna Asif sqlcache.blogspot.com/2014/09/…
aasim.abdullah
1
Provavelmente, eu ligaria um fluxo de dados simples do SSIS com uma transformação de coluna de exportação
Martin Smith

Respostas:

13

Esta é a solução que eu vim com:

  1. Ativar xp_cmdshellcom

    EXEC sp_configure 'show advanced options', 1
    GO
    RECONFIGURE
    GO
    EXEC sp_configure 'xp_cmdshell', 1
    GO
    RECONFIGURE
    GO
  2. Se necessário, crie um diretório com xp_cmdshellpara obter as permissões necessárias.

    EXEC master..xp_cmdshell 'mkdir C:\exportdir'
  3. Use BCP com queryout

    EXEC master..xp_cmdshell 'BCP "SELECT column_of_type_image FROM **your_db WHERE id = 1 " queryout "C:\exportdir\yourfile.pdf" -T -N'

** your_db deve ser o nome completo da tabela, ou seja, [Yourdb]. [YourSchema]. [YourTable]

Jonas
fonte
1
Eu tentei o código acima e realmente funcionou ... até certo ponto. Por algum motivo, a imagem JPG possui 4 caracteres anteriores que a tornam inválida. Eu os removi com um editor de texto e pronto ... JPG funcionou. Alguma idéia do que esses 4 caracteres poderiam ser e como se livrar deles na exportação? São eles:2B 90 01 00
Qual é o tipo da coluna da qual você exportou?
Max Vernon
10

Eu tive o mesmo problema com os 4 bytes extras sendo adicionados ao início de todos os meus arquivos também. Em vez de usar a opção -N no meu comando bcp, mudei para -C RAW. Quando você fizer isso, o bcp será solicitado com as seguintes perguntas:

Digite o tipo de armazenamento de arquivo do campo FileData [imagem]:
Digite o comprimento do prefixo do campo FileData [4]:
Digite o comprimento do campo FileData [0]:
Digite o terminador de campo [nenhum]: 
Deseja salvar essas informações de formato em um arquivo? [S / n]

Para corrigir isso, criei um arquivo de texto (i.txt) na raiz do meu servidor sql, que tinha as seguintes linhas para responder a cada um deles:

Eu
0 0
0 0

n

Então, minha linha EXEC bcp se tornou:

EXEC master..xp_cmdshell 'BCP "SELECT column_of_type_image FROM ** your_db WHERE id = 1" queryout "C: \ exportdir \ yourfile.pdf" -T -C RAW <C: \ i.txt'

Isso exportou meu arquivo sem nenhum dos caracteres extras.

Jacob Dababneh
fonte
2

Cheguei à procura de uma solução para exportar uma coluna IMAGE, tendo armazenado diferentes tipos de arquivos (pdf, xls, doc, xml ...) que desejo exportar.

A abordagem na resposta funcionou apenas para arquivos pdf. Para exportar todos os tipos de arquivos, tive que ajustar a solução da seguinte maneira:

(1.) Crie um arquivo de modelo de formato:

Declare @sql varchar(500); 
Declare @sql varchar(500); 
SET @sql = 'bcp db.dbo.ImgTable format nul -T -n -f C:\tmp\export.fmt -S ' + @@SERVERNAME; 
select @sql;  
EXEC master.dbo.xp_CmdShell @sql; 

(2.) Abra o arquivo de formato de exportação criado e edite-o dessa maneira:

10.0
1
1       SQLIMAGE            0       0       ""   1     img_col                                     ""

Em seguida, execute seu comando de exportação:

EXEC master..xp_cmdshell 'BCP "SELECT IMG_COL FROM db.dbo.ImgTable WHERE id = ''CAB240C0-0068-4041-AA34-0000ECB42DDD'' " queryout "C:\tmp\myFile.xml" -T -f C:\tmp\export.fmt -S '

(3.) Caso você encontre esse erro (como eu fiz):

"As colunas do arquivo host [Microsoft] [SQL Native Client] podem ser ignoradas apenas ao copiar no servidor"

verifique o seguinte:

  • não se esqueça de editar a segunda linha e inserir o número de entradas aqui (1 neste cenário)!
  • verifique se você tem um CRLF no final da última linha, sem isso não funcionou!

Após isso, a exportação de qualquer palavra do arquivo IMAGE Column sem erro.

Tributos para 1. e 2. tudo vai para a resposta da seguinte pergunta: /programming/1366544/how-to-export-image-field-to-file/24006947#24006947

Magier
fonte
1

Se você não tiver nenhum problema com uma solução GUI, existe um ótimo complemento para o SSMS SSMSBoost, que oferece muitos recursos úteis e, é claro, a maneira mais simples de visualizar imagens armazenadas em SQL (pelo menos na minha opinião)

NOTA : Você deve reiniciar o SSMS após instalar este suplemento.

Instale-o e aproveite a visualização de imagens apenas com: Clique com o botão direito> Visualizar como> Foto

abdômen
fonte
0
EXEC master..xp_cmdshell 'mkdir D:\Project\Member\Images'

Mantenha o comando em UMA LINHA - ÚNICA LINHA !!!

SET @Command = 'bcp "SELECT Member_Picture FROM dbserver.[Member_Image] WHERE memberId = 1 " queryout "D:\Project\Member\Images\member1.jpg" -T -N ' 
PRINT @Command -- debugging
EXEC xp_cmdshell   @Command
GO
ARYA
fonte
Em alguns servidores, o xp_cmdshell está desativado e você recebe #SQL Server blocked access to procedure 'sys.xp_cmdshell' of component 'xp_cmdshell' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'xp_cmdshell' by using sp_configure. For more information about enabling 'xp_cmdshell', search for 'xp_cmdshell' in SQL Server Books Online.
JustAMartin 16/10/19
-2
USE [POC]
DECLARE @outPutPath varchar(50) = 'C:\Extract_Photos'
, @i bigint
, @init int
, @data varbinary(max)
, @fPath varchar(max)
, @folderPath  varchar(max)

--Get Data into temp Table variable so that we can iterate over it
DECLARE @Doctable TABLE (id int identity(1,1), [Doc_Num]  varchar(100) , [FileName]  varchar(100), [Doc_Content] varBinary(max) )

INSERT INTO @Doctable([Doc_Num] , [FileName],[Doc_Content])
Select [STUDENTNO] , [STUDENTNAME],[STUDENTPHOTO] FROM  [dbo].[STUDENTPHOTOS]

--SELECT * FROM @table

SELECT @i = COUNT(1) FROM @Doctable

WHILE @i >= 1
BEGIN

    SELECT
     @data = [Doc_Content],
     @fPath = @outPutPath + '\'+ [Doc_Num] + '\' +[FileName],
     @folderPath = @outPutPath + '\'+ [Doc_Num]
    FROM @Doctable WHERE id = @i

  --Create folder first
  EXEC  [dbo].[CreateFolder]  @folderPath

  EXEC sp_OACreate 'ADODB.Stream', @init OUTPUT; -- An instace created
  EXEC sp_OASetProperty @init, 'Type', 1;
  EXEC sp_OAMethod @init, 'Open'; -- Calling a method
  EXEC sp_OAMethod @init, 'Write', NULL, @data; -- Calling a method
  EXEC sp_OAMethod @init, 'SaveToFile', NULL, @fPath, 2; -- Calling a method
  EXEC sp_OAMethod @init, 'Close'; -- Calling a method
  EXEC sp_OADestroy @init; -- Closed the resources

  print 'Document Generated at - '+  @fPath

--Reset the variables for next use
SELECT @data = NULL
, @init = NULL
, @fPath = NULL
, @folderPath = NULL
SET @i -= 1
END
erax
fonte
Altere sua postagem explicando o que esse código deve fazer.
Dez15
Obrigado Erax pelo script que funcionou maravilhosamente. PS: O script falha ao extrair o arquivo se executado remotamente usando o SSMS. Ele precisava ser executado no SQLServer diretamente para obter o anexo.
Vaas