Jak wyeksportować kolumnę obrazu do plików w SQL Server?

14

Przeprowadzę migrację z bazy danych. Jest jedna kolumna typu image, którą chciałbym wyeksportować do plików binarnych w systemie plików. Jeden plik dla każdego rekordu. Jak mogę to zrobić za pomocą programu SQL Server?

Jonas
źródło
1
Dobry post Amny Asif sqlcache.blogspot.com/2014/09/…
aasim.abdullah
1
Prawdopodobnie wybiłbym prosty przepływ danych SSIS z transformacją kolumny eksportu
Martin Smith,

Odpowiedzi:

14

Oto rozwiązanie, które wymyśliłem:

  1. Włącz za xp_cmdshellpomocą

    EXEC sp_configure 'show advanced options', 1
    GO
    RECONFIGURE
    GO
    EXEC sp_configure 'xp_cmdshell', 1
    GO
    RECONFIGURE
    GO
  2. W razie potrzeby utwórz katalog z, xp_cmdshellaby uzyskać potrzebne uprawnienia.

    EXEC master..xp_cmdshell 'mkdir C:\exportdir'
  3. Użyj BCP z zapytaniem

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

** twoja_db musi być w pełni kwalifikowaną nazwą tabeli, tj. [Yourdb]. [YourSchema]. [YourTable]

Jonas
źródło
1
Wypróbowałem powyższy kod i rzeczywiście zadziałało ... do pewnego stopnia. Z jakiegoś powodu obraz JPG zawiera 4 poprzedzające znaki, które powodują, że staje się on nieprawidłowy. Usunąłem je za pomocą edytora tekstu i voila ... JPG działało. Masz pojęcie, czym mogą być te 4 postacie i jak się ich pozbyć w eksporcie? Są to:2B 90 01 00
Jaki typ kolumny wyeksportowałeś?
Max Vernon
10

Miałem ten sam problem z dodawaniem dodatkowych 4 bajtów na początku wszystkich moich plików. Zamiast używać opcji -N w mojej komendzie bcp, zmieniłem ją na -C RAW. Po wykonaniu tej czynności program bcp zostanie poproszony o następujące pytania:

Wpisz typ przechowywania plików w polu FileData [image]:
Podaj długość prefiksu pola FileData [4]:
Wpisz długość pola FileData [0]:
Wpisz terminator pola [brak]: 
Czy chcesz zapisać informacje o tym formacie w pliku? [T / n]

Aby to naprawić, utworzyłem plik tekstowy (i.txt) w katalogu głównym mojego serwera SQL, który zawierał następujące wiersze odpowiadające na każdy z nich:

ja
0
0

n

Następnie moja linia EXEC bcp stała się:

EXEC master..xp_cmdshell 'BCP' WYBIERZ kolumna_typu_obrazu OD ** twój_db GDZIE id = 1 „zapytanie” C: \ exportdir \ twój_plik.pdf "-T -C RAW <C: \ i.txt '

To wyeksportowało mój plik bez żadnych dodatkowych znaków.

Jacob Dababneh
źródło
2

Przyszedłem dookoła szukając rozwiązania do eksportu kolumny IMAGE, przechowującej różnego rodzaju pliki (pdf, xls, doc, xml ...), które chcę wyeksportować.

Podejście w odpowiedzi działało tylko w przypadku plików pdf. Aby wyeksportować wszystkie rodzaje plików musiałem dostosować rozwiązanie w następujący sposób:

(1.) Utwórz plik szablonu formatu:

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.) Otwórz utworzony plik formatu eksportu i edytuj go w ten sposób:

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

Następnie wykonaj polecenie eksportu:

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.) W przypadku napotkania tego błędu (tak jak ja):

„[Microsoft] [SQL Native Client] Kolumny pliku hosta można pominąć tylko podczas kopiowania na serwer”

upewnij się, że:

  • upewnij się, że nie zapomniałeś edytować drugiego wiersza i wprowadź tutaj liczbę wpisów (1 w tym scenariuszu)!
  • upewnij się, że masz CRLF na końcu ostatniej linii, bez tego nie działałoby!

Następnie eksport dowolnego słowa pliku kolumny IMAGE bez błędu.

Hołdy dla 1. i 2. przechodzą do odpowiedzi na następujące pytanie: /programming/1366544/how-to-export-image-field-to-file/24006947#24006947

Magier
źródło
1

Jeśli nie masz żadnego problemu z rozwiązaniem GUI, istnieje naprawdę świetny dodatek do SSMS SSMSBoost, który zapewnia wiele przydatnych funkcji i oczywiście najprostszy sposób podglądu obrazów przechowywanych w SQL (przynajmniej moim zdaniem)

UWAGA : Musisz ponownie uruchomić SSMS po zainstalowaniu tego dodatku.

Zainstaluj go i ciesz się podglądem obrazów za pomocą: RightClick> Visualize As> Picture

ABS
źródło
0
EXEC master..xp_cmdshell 'mkdir D:\Project\Member\Images'

Trzymaj polecenie na JEDNEJ LINII - POJEDYNCZEJ LINII !!!

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
źródło
Na niektórych serwerach xp_cmdshell jest wyłączony i dostajeszSQL 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
-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
źródło
Popraw swój post, wyjaśniając, co ten kod ma zrobić.
dezso
Dzięki Erax za skrypt zadziałał cudownie. PS: Skrypt nie może wyodrębnić pliku, jeśli został uruchomiony zdalnie przy użyciu SSMS. Musiał zostać uruchomiony bezpośrednio na SQLServer, aby mógł pobrać załącznik.
Vaas