Na tuto otázku odpovídám, protože jsem našel způsob, jak to udělat rychleji.
Použití nástroje bcp (program pro hromadné kopírování) z příkazového řádku zachovává nativní formát souboru a je velmi rychlé. Výstupní soubory lze také zapsat do místního adresáře. V případě potřeby lze také upravit formáty souborů.
Edit:Přidání podrobnější verze odpovědi s kódem, který jsem použil.
1) Nastavte požadovaná oprávnění ke spuštění xp_cmdshell
.
EXEC sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
EXEC sp_configure 'xp_cmdshell',1
GO
RECONFIGURE;
GO
2) Exportujte soubor formátu tabulky pomocí bcp
bcp schemaname.tablename format nul -T -n -f format_file_tablename.fmt
Nahraďte -T
s -S servername -d databasename -U username -P password
pokud se nepřipojíte k databázi pomocí integrovaného zabezpečení.
3) Po úspěšném exportu souboru formátu jej upravte tak, aby byly odstraněny všechny ostatní sloupce kromě image
nebo varbinary
sloupec.
Soubor formátu zpočátku vypadal takto.
11.0
17
1 SQLNCHAR 2 200 "" 1 Name SQL_Latin1_General_CP1_CI_AS
2 SQLNCHAR 2 1000 "" 2 Description SQL_Latin1_General_CP1_CI_AS
3 SQLUNIQUEID 1 16 "" 3 GUID ""
4 SQLBIT 1 1 "" 4 Enabled ""
5 SQLNCHAR 2 600 "" 5 ClassType SQL_Latin1_General_CP1_CI_AS
6 SQLINT 0 4 "" 6 PartitionID ""
7 SQLBIT 1 1 "" 7 Protected ""
8 SQLDATETIME 1 8 "" 8 LastModifiedTime ""
9 SQLINT 0 4 "" 9 LastModifiedByID ""
10 SQLINT 0 4 "" 10 ImageType ""
11 SQLBIT 1 1 "" 11 Template ""
12 SQLINT 0 4 "" 12 ObjectID ""
13 SQLBINARY 8 0 "" 13 Image --column of interest ""
14 SQLINT 0 4 "" 14 ParentId ""
15 SQLNCHAR 2 600 "" 15 ParentClassType SQL_Latin1_General_CP1_CI_AS
16 SQLBIT 1 1 "" 16 IsPrimary ""
17 SQLDATETIME 1 8 "" 17 ImageCaptureDate ""
Upravil jsem soubor, jak je uvedeno níže.
11.0
1
1 SQLBINARY 0 0 "" 1 Image ""
4) Potom jsem musel procházet řádky v tabulce a extrahovat sloupec obrázku v každém řádku jako soubor. Použil jsem temp table
pro tento účel.
IF OBJECT_ID('dbo.tmp_for_picture', 'U') IS NOT NULL
DROP TABLE tmp_for_picture
GO
select
row_number() over(order by parentid) as rownum
,i.image as image_column
,i.parentid
,replace(p.name,',','') as picture_file_name
,i.name
into tmp_for_picture
from Images i
join personnel p on p.ObjectID = i.ParentId
GO
declare @cnt int
declare @i int
declare @filename varchar(512)
declare @extension varchar(20)
declare @sql varchar(4000)
set @cnt = (select count(*) from Images i join personnel p on p.ObjectID = i.ParentId)
set @i = 1
set @extension = '.jpeg' --or extract the extension from a column in the table if available
while @i <= @cnt
begin
--print @i
set @filename = (select picture_file_name from tmp_for_picture where rownum = @i)
set @sql = 'bcp "select image_column from tmp_for_picture where rownum = '+str(@i)+'" queryout "F:\pictures\'[email protected][email protected]+'" -f formatfile.fmt -S servername -d databasename -T'
--print @sql
exec xp_cmdshell @sql
set @i = @i+1
end
GO
Výše popsané kroky lze použít k extrahování jakéhokoli typu obrazových/varbinárních souborů (uložených jako pdf, docx atd.) z databáze.