22

I am using Microsoft SQL Server Management Studio to connect to a database. In it I've got a table, one column of which is an Image column containing file data. Another column is a string containing the file name.

Is there some way I can write some sql script that will allow me to select a record and write this data to a file? Or if this isn't possible, what's a simple way for achieving this?

I've seen this related question, but it doesn't seem quite the same: Save image column to file in sql-server 2000

4 Answers 4

44
-- Write all database images (jpg) to file.
--------- --------- --------- --------- --------- --------- --------- 
DECLARE CURSOR_ProductIds CURSOR FOR (SELECT ImgImagesId FROM ImgProductSample)

DECLARE @ProductId INT;

OPEN CURSOR_ProductIds

FETCH NEXT FROM CURSOR_ProductIds INTO @ProductId
WHILE (@@FETCH_STATUS <> -1)
BEGIN
  DECLARE @ImageData varbinary(max);
  SELECT @ImageData = (SELECT convert(varbinary(max), ImageData, 1) FROM ProductImages WHERE Id = @ProductId);

  DECLARE @Path nvarchar(1024);
  SELECT @Path = 'C:\MyImages\Output';

  DECLARE @Filename NVARCHAR(1024);
  SELECT @Filename = (SELECT ImageFilename FROM ProductImages WHERE id = @ProductId);

  DECLARE @FullPathToOutputFile NVARCHAR(2048);
  SELECT @FullPathToOutputFile = @Path + '\' + @Filename;

  DECLARE @ObjectToken INT
  EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT;
  EXEC sp_OASetProperty @ObjectToken, 'Type', 1;
  EXEC sp_OAMethod @ObjectToken, 'Open';
  EXEC sp_OAMethod @ObjectToken, 'Write', NULL, @ImageData;
  EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL, @FullPathToOutputFile, 2;
  EXEC sp_OAMethod @ObjectToken, 'Close';
  EXEC sp_OADestroy @ObjectToken;

  FETCH NEXT FROM CURSOR_ProductIds INTO @ProductId
END
CLOSE CURSOR_ProductIds
DEALLOCATE CURSOR_ProductIds

-- Make sure the following statement is executed to enable file IO
-- From http://msdn.microsoft.com/en-us/library/ms191188.aspx
--------- --------- --------- --------- --------- --------- --------- 
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures', 1;
GO
RECONFIGURE;
GO
3
  • Msg 8152, Level 16, State 10, Line 7 String or binary data would be truncated.
    – Roxy'Pro
    Commented Oct 23, 2016 at 12:37
  • 2
    @Roxy'Pro That error likely indicates that whatever column you selected is the wrong data type for ProductID, which is declared as an INT. You need to ensure that the data type is correct for the column you're querying. Commented Feb 25, 2020 at 8:04
  • Amazing! Thank you! I had to do a complex query, so I edited the declare statement to DECLARE CURSOR_ProductIds CURSOR FOR (MY complex Query), then adjusted the various names of the columns to match my database structure.
    – Xebozone
    Commented Dec 29, 2020 at 7:39
7

From mkader at codeproject:

EXEC sp_configure 'show advanced options', 1;  
GO  
RECONFIGURE;  
GO
EXEC sp_configure 'xp_cmdshell',1  
GO  
RECONFIGURE;  
GO

Then dump a format file:

Declare @sql varchar(500)
SET @sql = 'bcp DBName.dbo.tblTableName format nul -T -n -f C:\testblob.fmt -S ' + @@SERVERNAME
select @sql 
EXEC master.dbo.xp_CmdShell @sql 

My format file looked like this:

10.0
12
1       SQLINT              0       4       ""   1     my_tablecol_id                                  ""
2       SQLINT              1       4       ""   2     my_tablecol0                                   ""
3       SQLCHAR             2       256     ""   3     my_tablecol1                                SQL_Latin1_General_CP1_CI_AS
4       SQLCHAR             2       256     ""   4     my_tablecol2                                SQL_Latin1_General_CP1_CI_AS
5       SQLCHAR             2       256     ""   5     my_tablecol3                         SQL_Latin1_General_CP1_CI_AS
6       SQLCHAR             2       2048    ""   6     my_tablecol4                                SQL_Latin1_General_CP1_CI_AS
7       SQLIMAGE            4       0       ""   7     my_imagecol                                     ""
8       SQLCHAR             2       2048    ""   8     my_tablecol6                            SQL_Latin1_General_CP1_CI_AS
9       SQLINT              1       4       ""   9     my_tablecol7                                      ""
10      SQLINT              1       4       ""   10    my_tablecol8                                    ""
11      SQLINT              1       4       ""   11    my_tablecol9                               ""
12      SQLBIT              1       1       ""   12    my_tablecol10                             ""

I then edited the format file like so:

10.0
1
1       SQLIMAGE            0       0       ""   1     my_imagecol                                     ""

And then ran this SQL in SSMS:

Declare @mynum int
Declare @sql varchar(500)
SET @mynum = 49 -- something meaningful only to me
SET @sql = 'BCP "SELECT my_imagecol FROM DBName.dbo.tblTableName where my_tablecol_id=@mynum" QUERYOUT C:\myfilename.docx -T -fC:\testblob.fmt -S ' + @@SERVERNAME
EXEC master.dbo.xp_CmdShell @sql

This worked really well, any kind of data in the image column works.

1
  • Thanks! The format file was what I needed to get this working. Commented Mar 3, 2017 at 23:45
2
-- Write database image (jpg) to file
-- http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=101754
--------- --------- --------- --------- --------- --------- --------- 
DECLARE @ImageData varbinary(max);
SELECT @ImageData = (SELECT convert(varbinary(max), ImageData, 1) FROM ProductImages WHERE Id = 1);

DECLARE @Path nvarchar(1024);
SELECT @Path = 'C:\MyImages\Output';

DECLARE @Filename NVARCHAR(1024);
SELECT @Filename = (SELECT ImageFilename FROM ProductImages WHERE id = 1);

DECLARE @FullPathToOutputFile NVARCHAR(2048);
SELECT @FullPathToOutputFile = @Path + '\' + @Filename;

DECLARE @ObjectToken INT
EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT;
EXEC sp_OASetProperty @ObjectToken, 'Type', 1;
EXEC sp_OAMethod @ObjectToken, 'Open';
EXEC sp_OAMethod @ObjectToken, 'Write', NULL, @ImageData;
EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL, @FullPathToOutputFile, 2;
EXEC sp_OAMethod @ObjectToken, 'Close';
EXEC sp_OADestroy @ObjectToken;

-- Make sure the following statement is executed to enable file IO
-- From http://msdn.microsoft.com/en-us/library/ms191188.aspx
--------- --------- --------- --------- --------- --------- --------- 
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures', 1;
GO
RECONFIGURE;
GO

PS - The link to article 'Reading and Writing Files in SQL Server using T-SQL' was useful but I after I got the piece of code working it produced an invalid image file.

1
  • @mathijusuitmegan I am facing this issue :Msg 8152, Level 16, State 10, Line 7 String or binary data would be truncated.
    – Roxy'Pro
    Commented Oct 23, 2016 at 12:33
1

I know this is above 2 year old thread, still wanted to post, because it could help someone. If we want to export images along with the other columns (which includes symbols) from a database table to a file, so that they can be imported into another SQL Server, this comes in very handy.

The below code will export the specified database table to the file path of choice.

Declare @sql varchar(500)
SET @sql = 'bcp Your_db.Your_table out Your_File_Path(eg: C:\ImagesNames.Dat) -w -T -S ' + @@SERVERNAME
EXEC @sql

The -w switch is for a Unicode format data file and the delimiter will be the default tab delimiter if we don't specify a delimiter. In this case, the data file is saved with a dat extension. Maybe it could be saved in other formats as well, but I haven't tested it, whereas this one works perfectly.

https://msdn.microsoft.com/en-gb/library/ms188289(v=sql.110).aspx

Then for the import:

BULK INSERT Your_db.Your_table
   FROM 'Your_File_Path'
with (DATAFILETYPE='widechar')

This imports the data file very efficiently into the specified database table.

Not the answer you're looking for? Browse other questions tagged or ask your own question.