How To Store Any File into SQL Database Introduction This is just a simple article to store any file format into a SQL server database. Background Recently I completed a project where I need to store various files, i.e. Microsoft Office file formats, PDF, Images, etc.). When I started writing code, I wrote a function to store binary, after that I thought why not use direct bulk insert from a StoredProcedure. Using the Code I am going to discuss the ways in which you can directly store binary data into a SQL table by using a simple stored procedure as given below: Collapse set ANSI_NULLS ON set QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: Author,,Md. Marufuzzaman -- Create date: -- Description: Description,, Insert the Binary data -- ============================================= -- EXEC dbo.spStoreBinaryFiles 'C:\eFaxFiles\eFaxPromo.pdf;D:\eFaxFiles\eFaxPromo.pdf;' CREATE PROCEDURE [dbo].[spStoreBinaryFiles] @FILE_PATH VARCHAR(MAX) AS BEGIN SET NOCOUNT ON; DECLARE @FILE_LENGTH BIGINT DECLARE @FILE_DATA VARBINARY(MAX) DECLARE @FILE_NAME VARCHAR(100) DECLARE @DOCUMENT_NAME VARCHAR(100) DECLARE @DOCUMENT_NATURE VARCHAR(5) DECLARE @VAL1 VARCHAR(100) DECLARE @VAL2 VARCHAR(100) DECLARE curDOCUMENTS CURSOR FOR SELECT * OPEN curDOCUMENTS FETCH NEXT FROM curDOCUMENTS INTO @VAL1,@VAL2 WHILE @@FETCH_STATUS = 0 BEGIN FROM dbo.SPLIT ( ';', @FILE_PATH ) IF OBJECT_ID('#ORStable') IS NULL BEGIN CREATE TABLE #ORStable _ (Length BIGINT, vDocument VARBINARY(MAX)) DECLARE @SQL_QUERY NVARCHAR(1000) SET @SQL_QUERY= ' INSERT INTO #ORStable SELECT len(bulkcolumn), * FROM OPENROWSET(BULK '''+@VAL2+''', _ SINGLE_BLOB) AS BinaryData' exec SP_executesql @SQL_QUERY END EXEC dbo.spGetDocumentNature @VAL2, @DOCUMENT_NATURE OUTPUT EXEC dbo.spGetDocumentName @VAL2, @DOCUMENT_NAME OUTPUT SELECT TOP 1 @FILE_LENGTH = Length, @FILE_DATA = vDocument FROM #ORStable INSERT INTO dbo.tblBinaryFiles ( [File] ,[Path] ,[Ext] ,[Size] ,[Binary] ) VALUES( @DOCUMENT_NAME ,@VAL2 ,@DOCUMENT_NATURE ,@FILE_LENGTH ,@FILE_DATA ) DROP TABLE dbo.#ORStable FETCH NEXT FROM curDOCUMENTS INTO @VAL1,@VAL2 END CLOSE curDOCUMENTS DEALLOCATE curDOCUMENTS END OPENROWSET: Includes all connection information necessary to access remote data from an OLE DB data source. This method is an alternative to accessing tables in a linked server and is a onetime, ad hoc method of connecting and accessing remote data using OLE DB. The OPENROWSET function can be referenced in the FROM clause of a query as though it is a table name. The OPENROWSET function can also be referenced as the target table of an INSERT, UPDATE, or DELETE statement, subject to the capabilities of the OLE DB provider. Although the query may return multiple result sets, OPENROWSET returns only the first one. Binary Large Objects (BLOBs): BLOB data type to store any data that a program can generate: graphic images, satellite images, video clips, audio clips, ... BulkColumn: The BulkColumn referenced in the query represents the varbinary value to be inserted. Sample Bulk Insert SQL Statement Collapse DECLARE @SQL_QUERY NVARCHAR(1000) SET @SQL_QUERY= ' INSERT INTO #ORStable SELECT len(bulkcolumn), * FROM OPENROWSET(BULK '''+@VAL2+''', _ SINGLE_BLOB) AS BinaryData' exec SP_executesql @SQL_QUERY --Here variable VAL2 contains the single file path information. --Example VAL2 = "\\192.168.1.1\myFiles\myFile.pdf" -VAL2 = "C:\myFiles\myFile.pdf" Storing and Retrieving doc/pdf/xls files in SQL Server August 31, 2007 by chiragrdarji I have explained how to store and retrieve image file in SQL Server in my previous post. I received many comments mentioning that how can we store and retrieve doc or pdf or excel (or any type of file) in SQL Server. Few friends (developers) have also posted comment that they receive only 13 byte when they retrieve stored image or doc or xls or pdf or rtf file. So I thought let be write another blog for them. Sorry friends I am bit late in writing this article and mean while you also have solved your issues. However this may help some new friends. In this example I have used a table which has four fields. Below is the script for table, CREATE TABLE [TestTable] ( [ID] [int] IDENTITY(1,1) NOT NULL, [FileName] [nvarchar](15) NOT NULL, [Extension] [nvarchar](5) NOT NULL, [Content] [image] NULL ) Fig – (1) Scrpit for Table In my demo project I have used one file Upload control (to upload the file), one Textbox (where user can enter ID for uploaded file to retrieve it) and 2 buttons (one for uploading file and other for retrieving). When user select the file and click on Upload button the code stores the selected file in database. Below is the code for that, using (SqlConnection cnn = new SqlConnection(“Connection String”)) { cnn.Open(); SqlCommand cmd = new SqlCommand(“InsertFile”, cnn); cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add(new SqlParameter(“@FileName”, “Name of Uploaded File”)); cmd.Parameters.Add(new SqlParameter(“@Extension”, “Extension of Uploaded File”)); cmd.Parameters.Add(new SqlParameter(“@Content”, “byte array (byte[]) of uploaded file”)); cnn.Close() } Fig – (2) Code for inserting selected file in database. Now when user enter FileID for uploaded file in textbox and click on retrieve button we will get the Content and extension field from database for that file id. You can use FillDataSet method to retrieve the byte array. Below code shows how to send retrieved file to user depending on the extension. string strExtenstion = “extension of retrieved file”; byte[] bytFile = “Byte array retrieved from database”; Response.Clear(); Response.Buffer = true; if (strExtenstion == “.doc” || strExtenstion == “.docx”) { Response.ContentType = “application/vnd.ms-word”; Response.AddHeader(“content-disposition”, “attachment;filename=Tr.doc”); } else if (strExtenstion == “.xls” || strExtenstion == “.xlsx”) { Response.ContentType = “application/vnd.ms-excel”; Response.AddHeader(“content-disposition”, “attachment;filename=Tr.xls”); } else if (strExtenstion == “.pdf”) { Response.ContentType = “application/pdf”; Response.AddHeader(“content-disposition”, “attachment;filename=Tr.pdf”); } Response.Charset = “”; Response.Cache.SetCacheability(HttpCacheability.NoCache); // If you write, // Response.Write(bytFile1); // then you will get only 13 byte in bytFile. Response.BinaryWrite(bytFile); Response.End(); Fig – (3) Code to retrieve the file from database. 1. Happy Programming !!! Get List Of Files From a Windows Directory to SQL Server In SQL Server, we read data from single text file; excel file…etc. However we can extend this to read all the files in a particular directory. This post demonstrates a part of this scenario. Here we will discuss how to get the list of files from a particular directory, then can be extended to load them into SQL Server, which is not the scope of this post. So in order to use xp_cmdshell, we need to enable it as it is disabled by default. Here is the way to enable: --allow advanced options to be changed. EXEC sp_configure 'show advanced options', 1 GO --Update the currently configured value for advanced options. RECONFIGURE GO --Enable XP_CMDSHELL EXEC sp_configure 'xp_cmdshell', 1 GO --Update the currently configured value for this feature. RECONFIGURE GO Refer Image-1 for the list of files in the directory. Now create a table and load the file list into it: --Create the table to store file list CREATE TABLE myFileList (FileNumber INT IDENTITY,FileName VARCHAR(256)) --Insert file list from directory to SQL Server DECLARE @Path varchar(256) = 'dir C:\Import\' DECLARE @Command varchar(1024) = @Path + ' /A-D /B' INSERT INTO myFileList EXEC MASTER.dbo.xp_cmdshell @Command --Check the list SELECT * FROM myFileList GO --Clean up DROP TABLE myFileList GO Here is the result in the table. This can be extendable to other file operations too. Leave your valuable comments and sug This tutorial shows you how to store raw binary data in a SQL Database using VB.NET and ASP.NET 3.5 In this tutorial, we will be looking at how to upload and store binary data in a SQL database. Probably the most popular way to store uploaded files is within the file system of the server, but storing files in a database does have its advantages. Using a database to store the raw binary data of files will help with backing up, as all the data is encapsulated within the database - no need to worry about any files that the database will be linking to. Using the SQL data type varbinary, we can store files upto 2GB in size. In this example, we will create a simple upload form and demonstrate how to upload a GIF or JPEG and store it within the database. Doing it this way, we will need to record the MIME data type of the uploaded file, also, as it will be stored in raw binary form. The first thing we should do is design our database. Let's create a table with the following columns (and data types): - ID (bigint); - FileName (varchar(50)); - DateTimeUploaded (datetime); - MIME (varchar(50)); - BinaryData (varbinary(MAX)). Now we have our table designed, let's move on to creating our upload form. We will require a textbox for the name of the file, a file upload control as well as a button: <form id="form1" runat="server"> Please upload either a JPEG or a GIF:<br /> <asp:Literal ID="lit_Status" runat="server" /><br /> <b>Name:</b> <asp:TextBox ID="FileName" runat="server" /> <br /> <b>File:</b> <asp:FileUpload ID="FileToUpload" runat="server" /> <br /> <asp:Button ID="btn_Upload" runat="server" Text="Upload" /> </form> We moved our web sites to Server Intellect and have found them to be incredibly professional. Their setup is very easy and we were up and running in no time. We will also use a Literal control to display status messages to the user. Now we will need to connect to our database, so make sure we have our connection string in the Web.config: <connectionStrings> <add name="ConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient" /> </connectionStrings> If you do not, a quick way to add the connection string is to drag a SqlDataSource control from the toolbox onto the page and configure it using the Smart Tag in design view. This will set the DataSource to the database we created earlier and input the connection string in the Web.config, and once you are done configuring, you can simply delete the SqlDataSource. Next up, we will create a handler for the Submit button. A quick way to do this is to enter design view of the ASPX page and double-click the Submit button: Imports System.Data.SqlClient Imports System.IO Partial Class _Default Inherits System.Web.UI.Page Protected Sub btn_Upload_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn_Upload.Click End Sub End Class I just signed up at Server Intellect and couldn't be more pleased with my Windows Server! Check it out and see for yourself. The first thing we want to do is to check if the file uploaded successfully: If FileToUpload.PostedFile Is Nothing OrElse String.IsNullOrEmpty(FileToUpload.PostedFile.FileName) OrElse FileToUpload.PostedFile.InputStream Is Nothing Then lit_Status.Text = "<br />Error - unable to upload file. Please try again.<br />" Exit Sub End If If the file is not uploaded, or there is no file to upload, we want to tell the user and break out of the Sub. The next thing to do is to find out the file extension of the file: Dim extension As String = Path.GetExtension(FileToUpload.PostedFile.FileName).ToLower() Dim fileType As String = Nothing Select Case extension Case ".gif" fileType = "image/gif" Case ".jpg", ".jpeg", ".jpe" fileType = "image/jpeg" Case ".png" fileType = "image/png" Case Else lit_Status.Text = "<br />Error - invalid file type.<br />" Exit Sub End Select Server Intellect assists companies of all sizes with their hosting needs by offering fully configured server solutions coupled with proactive server management services. Server Intellect specializes in providing complete internet-ready server solutions backed by their expert 24/365 proactive support team. Finally, we use our connection to insert into the database: Using Conn As New SqlConnection(ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString ) Try Const SQL As String = "INSERT INTO [BinaryTable] ([FileName], [DateTimeUploaded], [MIME], [BinaryData]) VALUES (@FileName, @DateTimeUploaded, @MIME, @BinaryData)" Dim cmd As New SqlCommand(SQL, Conn) cmd.Parameters.AddWithValue("@FileName", FileName.Text.Trim()) cmd.Parameters.AddWithValue("@MIME", fileType) Dim imageBytes(FileToUpload.PostedFile.InputStream.Length) As Byte FileToUpload.PostedFile.InputStream.Read(imageBytes, 0, imageBytes.Length) cmd.Parameters.AddWithValue("@BinaryData", imageBytes) cmd.Parameters.AddWithValue("@DateTimeUploaded", DateTime.Now) lit_Status.Text = "<br />File successfully uploaded - thank you.<br />" Conn.Open() cmd.ExecuteNonQuery() Conn.Close() Catch ex As Exception Conn.Close() End Try End Using We use a regular SQL Statement to insert the data into the database, and use SQL Parameters to pass the data from our form to the database. The entire code-behind looks like this: Imports System.Data.SqlClient Imports System.IO Partial Class _Default Inherits System.Web.UI.Page Protected Sub btn_Upload_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn_Upload.Click If FileToUpload.PostedFile Is Nothing OrElse String.IsNullOrEmpty(FileToUpload.PostedFile.FileName) OrElse FileToUpload.PostedFile.InputStream Is Nothing Then lit_Status.Text = "<br />Error - unable to upload file. Please try again.<br />" Exit Sub End If Dim extension As String = Path.GetExtension(FileToUpload.PostedFile.FileName).ToLower() Dim fileType As String = Nothing Select Case extension Case ".gif" fileType = "image/gif" Case ".jpg", ".jpeg", ".jpe" fileType = "image/jpeg" Case ".png" fileType = "image/png" Case Else lit_Status.Text = "<br />Error - invalid file type.<br />" Exit Sub End Select Using Conn As New SqlConnection(ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString ) Try Const SQL As String = "INSERT INTO [BinaryTable] ([FileName], [DateTimeUploaded], [MIME], [BinaryData]) VALUES (@FileName, @DateTimeUploaded, @MIME, @BinaryData)" Dim cmd As New SqlCommand(SQL, Conn) cmd.Parameters.AddWithValue("@FileName", FileName.Text.Trim()) cmd.Parameters.AddWithValue("@MIME", fileType) Dim imageBytes(FileToUpload.PostedFile.InputStream.Length) As Byte FileToUpload.PostedFile.InputStream.Read(imageBytes, 0, imageBytes.Length) cmd.Parameters.AddWithValue("@BinaryData", imageBytes) cmd.Parameters.AddWithValue("@DateTimeUploaded", DateTime.Now) lit_Status.Text = "<br />File successfully uploaded - thank you.<br />" Conn.Open() cmd.ExecuteNonQuery() Conn.Close() Catch ex As Exception Conn.Close() End Try End Using End Sub End Class Retrieving Binary Data from SQL Database with VB.NET This tutorial shows you how to retrieve raw binary data from a SQL Database using VB.NET and ASP.NET 3.5 In this tutorial, we will be following on from our earlier tutorial, Storing Binary Data in SQL Database with VB.NET, and see how we can take it a step further and display the JPEG or GIF image directly from the database. We will be building upon the existing code in the earlier project, so if you want to go through that tutorial first, the link is above. The only thing we need to add to the existing page is to display a link to view the recently uploaded image. To do this, we will change the way we execute the inserting of the file. Below is what we used in the first example: Using Conn As New SqlConnection(ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString ) Try Const SQL As String = "INSERT INTO [BinaryTable] ([FileName], [DateTimeUploaded], [MIME], [BinaryData]) VALUES (@FileName, @DateTimeUploaded, @MIME, @BinaryData)" Dim cmd As New SqlCommand(SQL, Conn) cmd.Parameters.AddWithValue("@FileName", FileName.Text.Trim()) cmd.Parameters.AddWithValue("@MIME", fileType) Dim imageBytes(FileToUpload.PostedFile.InputStream.Length) As Byte FileToUpload.PostedFile.InputStream.Read(imageBytes, 0, imageBytes.Length) cmd.Parameters.AddWithValue("@BinaryData", imageBytes) cmd.Parameters.AddWithValue("@DateTimeUploaded", DateTime.Now) Conn.Open() cmd.ExecuteNonQuery() lit_Status.Text = "<br />File successfully uploaded - thank you.<br />" Conn.Close() Catch ex As Exception Conn.Close() End Try End Using I just signed up at Server Intellect and couldn't be more pleased with my Windows Server! Check it out and see for yourself. Instead of calling the ExecuteNonQuery method, we will call the ExecuteScalar method and change the SQL statement to return the new ID that has just been inserted: Using Conn As New SqlConnection(ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString ) Try Const SQL As String = "INSERT INTO [BinaryTable] ([FileName], [DateTimeUploaded], [MIME], [BinaryData]) VALUES (@FileName, @DateTimeUploaded, @MIME, @BinaryData) SELECT SCOPE_IDENTITY()" Dim cmd As New SqlCommand(SQL, Conn) cmd.Parameters.AddWithValue("@FileName", FileName.Text.Trim()) cmd.Parameters.AddWithValue("@MIME", fileType) Dim imageBytes(FileToUpload.PostedFile.InputStream.Length) As Byte FileToUpload.PostedFile.InputStream.Read(imageBytes, 0, imageBytes.Length) cmd.Parameters.AddWithValue("@BinaryData", imageBytes) cmd.Parameters.AddWithValue("@DateTimeUploaded", DateTime.Now) Conn.Open() Dim theInt As Integer = Convert.ToInt32(cmd.ExecuteScalar()) lit_Status.Text = "<br />File successfully uploaded - thank you.<br />" lnk_Picture.NavigateUrl = "~/ShowImage.aspx?ID=" & theInt.ToString() Conn.Close() Catch ex As Exception Conn.Close() End Try End Using We use the SQL Method SELECT SCOPE_IDENTITY() to return the ID of the record that has just been inserted. We then utilize this ID with the ExecuteScalar method and put the ID into the NavigateUrl of a HyperLink control we added to the form to utilize a querystring. Our form now looks like this: <form id="form1" runat="server"> Please upload either a JPEG or a GIF:<br /> <asp:Literal ID="lit_Status" runat="server" /><br /> <asp:HyperLink ID="lnk_Picture" runat="server" text="Click Here" /> <b>Name:</b> <asp:TextBox ID="FileName" runat="server" /> <br /> <b>File:</b> <asp:FileUpload ID="FileToUpload" runat="server" /> <br /> <asp:Button ID="btn_Upload" runat="server" Text="Upload" /> </form> We migrated our web sites to Server Intellect over one weekend and the setup was so smooth that we were up and running right away. They assisted us with everything we needed to do for all of our applications. With Server Intellect's help, we were able to avoid any headaches! Just the one change on the form - the addition of the HyperLink. We are going to use a new page to display the image, so add a new WebForm to your project named ShowImage.aspx First, we need to add the following assembly reference for this new page: Imports System.Data.SqlClient Next, add the following to the Page Load event: Try Dim PictureID As Integer = Convert.ToInt32(Request.QueryString("ID")) Using myConnection As New SqlConnection(ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString ) Const SQL As String = "SELECT [MIME], [BinaryData] FROM [BinaryTable] WHERE [ID] = @ID" Dim myCommand As New SqlCommand(SQL, myConnection) myCommand.Parameters.AddWithValue("@ID", PictureID) myConnection.Open() Dim myReader As SqlDataReader = myCommand.ExecuteReader() If myReader.Read Then Response.ContentType = myReader("MIME").ToString() Response.BinaryWrite(myReader("BinaryData")) End If myReader.Close() myConnection.Close() End Using Catch ex As Exception Response.Write(ex.ToString()) End Try We chose Server Intellect for its dedicated servers, for our web hosting. They have managed to handle virtually everything for us, from start to finish. And their customer service is stellar. Here, we are simply using the querystring to locate the image in the database, and then displaying it with the SqlDataReader and BinaryWrite. The entire code-behind of the new page should look something like this: Imports System.Data.SqlClient Partial Class ShowImage Inherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Try Dim PictureID As Integer = Convert.ToInt32(Request.QueryString("ID")) Using myConnection As New SqlConnection(ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString ) Const SQL As String = "SELECT [MIME], [BinaryData] FROM [BinaryTable] WHERE [ID] = @ID" Dim myCommand As New SqlCommand(SQL, myConnection) myCommand.Parameters.AddWithValue("@ID", PictureID) myConnection.Open() Dim myReader As SqlDataReader = myCommand.ExecuteReader() If myReader.Read Then Response.ContentType = myReader("MIME").ToString() Response.BinaryWrite(myReader("BinaryData")) End If myReader.Close() myConnection.Close() End Using Catch ex As Exception Response.Write(ex.ToString()) End Try End Sub End Class