Save SQL Server Filestream data to file - sql-server

I use SQL Server and enable FileStream on my database. In order to save my file to filestream table I use below code from SSMS :
INSERT INTO dbo.mytable( Data )
SELECT *
FROM OPENROWSET(BULK 'C:\Temp\image.png', SINGLE_BLOB) AS z
I look for a SQL query to save FileStream data from table to special path.
How can do this.
I look for SQL Server query and I don't want use tools application or programming in .Net, Delphi and etc.
thanks in advance

How about this? It's a pure SQL approach to writing a file to disk, but it does you the command shell, which opens up a security risk on the server.
declare #writetofile varchar(max)
select #writetofile = 'osql -U -P -S -Q"select ColumnName from yourtable" -o"c:\SomeFolder\MyFile.bin"
exec master..xp_cmdshell #writetofile
Update:
This is not the easiest thing to get running, but try running this in a powerscript or .bat file:
Rem CD command sets the execution folder
cd C:\Program Files\Microsoft SQL Server\90\Tools\binn
rem SQLCmd sets the command using SQLCmd.exe program
rem -S = server name, -d database name, -U is username, -P is password, -Q is query to run, -o is output to
SQLCMD -S ServerName\InstanceName -d DBName -U sa -P MyPassword -Q"select top 1 FieldName from TableName" -o"c:\temp\MyFile.txt"

This post may help you:
Script to save varbinary data to disk
DECLARE #SQLIMG VARCHAR(MAX),
#IMG_PATH VARBINARY(MAX),
#TIMESTAMP VARCHAR(MAX),
#ObjectToken INT
DECLARE IMGPATH CURSOR FAST_FORWARD FOR
SELECT csl_CompanyLogo from mlm_CSCompanySettingsLocalizations
OPEN IMGPATH
FETCH NEXT FROM IMGPATH INTO #IMG_PATH
WHILE ##FETCH_STATUS = 0
BEGIN
SET #TIMESTAMP = 'd:\' + replace(replace(replace(replace(convert(varchar,getdate(),121),'-',''),':',''),'.',''),' ','') + '.bmp'
PRINT #TIMESTAMP
PRINT #SQLIMG
EXEC sp_OACreate 'ADODB.Stream', #ObjectToken OUTPUT
EXEC sp_OASetProperty #ObjectToken, 'Type', 1
EXEC sp_OAMethod #ObjectToken, 'Open'
EXEC sp_OAMethod #ObjectToken, 'Write', NULL, #IMG_PATH
EXEC sp_OAMethod #ObjectToken, 'SaveToFile', NULL, #TIMESTAMP, 2
EXEC sp_OAMethod #ObjectToken, 'Close'
EXEC sp_OADestroy #ObjectToken
FETCH NEXT FROM IMGPATH INTO #IMG_PATH
END
CLOSE IMGPATH
DEALLOCATE IMGPATH

Related

How do I retreive a file from FILESTREAM?

I have installed SQL Server Express on my machine and enabled and configured FILESTREAM to store and retrieve pdf's from SQL Server. I have successfully uploaded files to my table as BLOB's, but I am having difficulty retrieving them. My approach is to use a temporary directory to create the files in so I can open them. I have the following code:
I have configured ole automation
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures', 1;
GO
RECONFIGURE;
GO
I have the following record in my table BusinessFiles:
FileID 415578C7-B058-49A5-A1E4-5A4E7218EA19
InvoiceID 99999
FileName file1
FileType pdf
ImageFile 0x255044462D312…
This next piece of code apparently will create the file from the filestream.
DECLARE
#FILE VARBINARY(MAX)
,#FILEPATH VARCHAR(MAX)
,#ObjectToken INT
,#FileType VARCHAR(MAX)
,#FILENAME VARCHAR(MAX)
Set #FILENAME = (SELECT [FileName] FROM BusinessFiles where FileID = '415578C7-B058-49A5-A1E4-5A4E7218EA19')
Set #FileType = (SELECT FileType FROM BusinessFiles where FileID = '415578C7-B058-49A5-A1E4-5A4E7218EA19')
SELECT #FILE = ImageFile FROM BusinessFiles where FileID = '415578C7-B058-49A5-A1E4-5A4E7218EA19'
Set #FILEPATH = CONCAT('C:\Users\user\Desktop\', #FILENAME,'.',#FileType)
EXEC sp_OACREATE 'ADODB.Stream', #ObjectToken OUTPUT
EXEC sp_OASetProperty #ObjectToken, 'Type', 1
EXEC sp_OAMethod #ObjectToken, 'Open'
EXEC sp_OAMethod #ObjectToken, 'Write', NULL, #FILE
EXEC sp_OAMethod #ObjectToken, 'SaveToFile', NULL, #FILEPATH, 2
EXEC sp_OAMethod #ObjectToken, 'Close'
EXEC sp_OADestroy #ObjectToken
Go
This code runs and I get the Commands Completed successfully message. However there is nothing in my folder C:\Users\user\Desktop. Is there something I'm missing? Thanks;
I've verified the file path is correct and all the set's are good.
Knowing the permissions of SQL Server will fix the SaveToFile Issue. In my case, I changed the SavetoFile Directory to C:\temp.

SQL Server 2008 R2: Export data using bcp command and store bcp output into variable

I want to export data using bcp command and the output of the bcp command should be stored in the variable.
My try:
DECLARE #Result varchar(max)
DECLARE #SQL nvarchar(max)
SET #SQL = N'Execute xp_cmdshell ''bcp "SELECT * FROM EMP" QueryOut "E:\BCP\Result.pec" -T -t#_# -c -o "E:\BCP\LogReport.txt"'''
EXEC sp_executesql #SQL, N'#Result nvarchar(75) OUTPUT', #Result =#Result output
PRINT(#Result)
But getting an error in the output:
output
------------------------------------------------------------------------------
bcp: Unable to open output file E:\BCP\LogReport.txt: No such file or directory
NULL
Questions:
1. How to store the above output result into the variable?
2. Given permission to the file and folder too, but still getting this error.
---------------------------------------- 1 -------------------------------------------
DECLARE #Result TABLE
(error_msg VARCHAR(800))
DECLARE
#SQL varchar(8000),
#Result_var VARCHAR(MAX)=''
SET #SQL = N'bcp "SELECT * FROM <MY_DATABASE>.<MY_SCHEMA>.<MY_TABLE>" QueryOut "E:\BCP\Result.pec" -T -t#_# -c -o "E:\BCP\LogReport.txt"'''
-- Insert the output from xp_cmdshell into the table #Result
INSERT INTO #Result (error_msg)
EXEC xp_cmdshell #SQL
-- Merge the rows
SELECT #Result_var = #Result_var + ' ' + ISNULL(error_msg,'') FROM #Result
-- Output in variable
PRINT #Result_var
--------------------------------------------------------------------------------------
2. For me, your command works, check access to folders and subfolders (for database user), check permissions on the sql server.

Microsoft SQL Server and varbinary data type conversion

I'm not familiar with Microsoft SQL Server and the varbinary(max) data type but the database which I need to use stores images as that.
My question is what do I need to do to read that data back and convert it back to readable image type?
So far I have done was
SELECT CONVERT(VARCHAR(max), [IMAGE], 2)
FROM [demo].[dbo].[DOCIMAGES]
WHERE [TITLE] = 'test.jpg'
but what I have got it was almost the same just removed 0x from the beginning of that data when
SELECT CONVERT(VARCHAR(max), [IMAGE], 0)
FROM [demo].[dbo].[DOCIMAGES]
WHERE [TITLE] = 'test.jpg'
returns value as Lead.
Then I have tried to do stored procedure which will save it to a file like:
DECLARE #ImageData VARBINARY (max);
DECLARE #Path2OutFile NVARCHAR (2000);
DECLARE #Obj INT
SET NOCOUNT ON
SELECT #ImageData = (
SELECT CONVERT(VARBINARY(max), [IMAGE], 1)
FROM [demo].[dbo].[DOCIMAGES]
WHERE [TITLE] = 'test.jpg'
);
SET #Path2OutFile = CONCAT (
'C:\Users\MyPC\Downloads'
,'\'
,'test.jpg'
);
BEGIN TRY
EXEC sp_OACreate 'ADODB.Stream' ,#Obj OUTPUT;
EXEC sp_OASetProperty #Obj ,'Type',1;
EXEC sp_OAMethod #Obj,'Open';
EXEC sp_OAMethod #Obj,'Write', NULL, #ImageData;
EXEC sp_OAMethod #Obj,'SaveToFile', NULL, #Path2OutFile, 2;
EXEC sp_OAMethod #Obj,'Close';
EXEC sp_OADestroy #Obj;
END TRY
BEGIN CATCH
EXEC sp_OADestroy #Obj;
END CATCH
SET NOCOUNT OFF
but that fails with an error:
SQL Server blocked access to procedure 'sys.sp_OADestroy' of component
'Ole Automation Procedures' because this component is turned off as
part of the security configuration for this server. A system
administrator can enable the use of 'Ole Automation Procedures' by
using sp_configure.
Problem is that I'm not the admin of that server.
In that case can I dump content of the [IMAGE] to a file and then use Java or PHP to stream that content and save it as an image file?

Save .zip file to BLOB in SQL Server

I have to do this:
Take this #HTML and save to file example.txt
example.txt save to .zip with password
.zip file convert to blob and stored into table
Do you know how to do it only in T-SQL? Is it possible?
DECLARE #HTML varchar(200)
SET #HTML = '<html>
<META http-equiv=Content-Language content=pl>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-2">
<body style="color:black; font-family: verdana, arial, helvetica, sans-serif; font-size:11px;">
TEST</body></html>'
SELECT #HTML
Using something like this?
EXEC sp_OACreate 'ADODB.Stream', #ObjectToken OUTPUT
EXEC sp_OASetProperty #ObjectToken, 'Type', 1
EXEC sp_OAMethod #ObjectToken, 'Open'
EXEC sp_OAMethod #ObjectToken, 'Write', NULL, #IMG_PATH
EXEC sp_OAMethod #ObjectToken, 'SaveToFile', NULL, #TIMESTAMP, 2
EXEC sp_OAMethod #ObjectToken, 'Close'
EXEC sp_OADestroy #ObjectToken
OK I created this:
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
using Microsoft.SqlServer.Server;
namespace SaveBlobData
{
class SaveHTML
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void SaveBlob(out SqlInt32 value, int idZak)
{
value = 3 + idZak;
}
}
}
I add .dll but I get error when I select this. Where is problem?
Take This #HTML and save to file example.txt
For this part you can use OLE Automation Object
DECLARE #FSO int,
#oFile int,
#filename nvarchar(max) = 'c:\Folder\example.txt'
-- Create OLE Automation Object
EXEC sp_OACreate 'Scripting.FileSystemObject', #FSO OUT
-- Create file
EXEC sp_OAMethod #FSO, 'CreateTextFile', #oFile OUT, #filename, 8 , True
-- Write data
EXEC sp_OAMethod #oFile, 'Write', NULL, #HTML
-- Clear used objects
EXEC sp_OADestroy #FSO
EXEC sp_OADestroy #oFile
example.txt save to .zip with Password
Don't know how this could be done with t-sql, for that purpose we use powershell (or cmd):
# path to 7-zip
$zip = "C:\Program Files\7-Zip\7z.exe"
# file
$FilesArh = "c:\Folder\example.zip"
$Dir = "c:\Folder\example.txt"
&$zip a "$FilesArh" "$Dir"
Create file Test1.ps1 with this inside:
param
(
[String] $FilesArh,
[String] $Dir
)
# path to 7-zip
$zip = "C:\Program Files\7-Zip\7z.exe"
&$zip a "$FilesArh" "$Dir"
Launch it from SQL Server:
EXEC xp_cmdshell 'powershell C:\Folder\Test.ps1 "c:\Folder\example.zip" "c:\Folder\example.txt"'
.zip file convert to blob and put to table:
With OPENROWSET you can get BLOB data and INSERT it into table.
INSERT INTO your_table (BLOB_field)
SELECT *
FROM OPENROWSET(BULK 'c:\Folder\example.zip', SINGLE_BLOB) AS BLOB
You can achive this by using CLR Stored Procedure that allows you to access resources being out of SQL Server control. You can write this procedure in .NET (you can do anything you want in this procedure as for example read file, compress it, etc). Then you have to prepare a DLL assembly and connect it with SQL Server. Here you are an example from MSDN how to create a procedure from external assembly:
CREATE ASSEMBLY MyFirstUdp FROM 'C:\Programming\MyFirstUdp.dll';
CREATE PROCEDURE HelloWorld
AS EXTERNAL NAME MyFirstUdp.StoredProcedures.HelloWorld;
EXEC HelloWorld;
More information about CLR Stored Procedures (and presented example) you can find on https://msdn.microsoft.com/pl-pl/library/ms131094(v=sql.110).aspx
Until you have your CLR proceure available in SQL Server then you can call it just from the batch.

Using bcp utility from within a stored procedure to output records to a text file

I have been using the bcp utility from the command line to save the result of a query to a text file e.g.
C:> bcp "SELECT Name FROM [DatabaseName].[dbo].[Employees]" queryout "filepath.txt" -c -T
I am currently trying to find away to execute this and similar bcp commands from a stored procedure.
Research for solution
Investigated xp_cmdshell stored procedure (Disabled for security reasons)
Use SQL Server agent and use job steps to invoke the command shell
Post from mssqltips
.
Attempt at a solution (Code below lies within stored procedure)
DECLARE #job NVARCHAR(100)
SET #job ='execute_bcp'
EXEC msdb..sp_add_job #job_name = #job,
#description = 'Execute bcp command',
#owner_login_name = 'sa',
#delete_level = 1
EXEC msdb..sp_add_jobstep #job_name = #job,
#step_id = 1,
#step_name ='Command Shell Execution', #subsystem = 'CMDEXEC',
#command = 'bcp "SELECT Name FROM [DatabaseName].[dbo].[Employees]" queryout "filepath.txt" -c -T',
#on_success_action =1
EXEC msdb..sp_add_jobserver #job_name =#job
EXEC msdb..sp_start_job #job_name = #job
The outcome of running this stored procedure is
'execute_bcp' has started.
However, when I check the file path location specified above the file has not been created.
Thanks in advance for any help and advice.

Resources