Click here to Skip to main content
Email Password   helpLost your password?

Introduction

In order to provide your application with cool pictures, you can employ two techniques (at least). One of them is that you can save the pictures in a folder and store the path to each one in a database or file. The other one is to store the entire file into a database, along with its file name.

Each of them has its ups and downs:

Another idea is that you can save a thumbnail of the image on the database for quick access and save the actual picture on hard drive.

Of course, each application has its particularities, and you have to choose which one you will use.

OK. Enough of the philosophical talk! Let�s dive into the good stuff.

The application

The problem of uploading files to a database is not that difficult. You have to use, on the server, a certain data type when creating the table. This data type has to be capable of storing large amounts of binary data.

When using Microsoft SQL Server, this data type is called image.

For more information, see BLOB (Binary Large OBject) for a short definition, and Books Online for a complete reference.

The client has to obtain the data from the file in binary format � a byte array � and call a procedure on the server with that array as a parameter.

The SQL Server procedures

In this presentation, I assume that I have a database Pictures on the server with a table called Pictures. The structure of this table is as follows:

Field Name

Field Type

kFileName

Long

Picture

Image

FileName

Varchar(250)

I also have stored procedures for uploading, downloading, and retrieving the list of uploaded files. These are shown below.

For uploading a file: UploadFile:

CREATE PROCEDURE [dbo].[UploadFile]
(
 @Picture image,
 @FileName varchar(250),
 @kFileName bigint output
)
AS
insert into Pictures(Picture, FileName) values (@Picture,@FileName)
select @kFileName = SCOPE_IDENTITY()
GO

For downloading a file: DownloadFile:

CREATE PROCEDURE [dbo].[DownloadFile]
(
 @kFileName bigint,
 @FileName varchar(250) output
)
AS

select Picture, FileName
 from Pictures
 where kFileName=@kFileName
GO

For retrieving the list of uploaded files: getUploadedFiles:

CREATE PROCEDURE [dbo].[getUploadedFiles]AS
Select ltrim(str(kFileName)) + " - " + FileName as Name 
  from Pictures
GO

The C# Class - with comments

using System;
using System.IO;
using System.Data;
using System.Text;
using System.Data.SqlClient;
/*
 * Autor: Ghiondea Alexandru
 * Date: 08 october 2004
 * Description: Implements methods for uploading and downloading files 
 *  with MS SQL Server
 * */
namespace PicturesInSQLServer
{
 /// <SUMMARY>

 /// This class manages uploads and downloads to and from an SQL Server

 /// </SUMMARY>

 public class TransferPictures
 {
  /// <SUMMARY>

  /// Gets from the server a list of uploaded files into a dataSet

  /// </SUMMARY>

  /// <PARAM name="ds">The dataset</PARAM>

  /// <PARAM name="table">The table in the dataset</PARAM>

  public void GetUploadedFiles(ref DataSet ds, string table)
  {
   //

   // The variables required for connecting to the server.

   //

   SqlConnection conn =null;
   SqlCommand cmd = null;
   SqlDataAdapter da = null;
   // ----------------------------------------------


   try
   {
    //

    // If the table already exists, cleares its content. Else adds a new table.

    //

    if (ds.Tables.Contains(table))
     ds.Tables[table].Clear();
    else
     ds.Tables.Add(table);
    // ----------------------------------------------


    
    //

    // Creates a connection to the database and initilizes the command

    //

    conn = new SqlConnection(ConnectionString());
    cmd = new SqlCommand("getUploadedFiles",conn);
    cmd.CommandType = CommandType.StoredProcedure;
    // ----------------------------------------------


    //

    // Initializes the DataAdapter used for retrieving the data

    //

    da = new SqlDataAdapter(cmd);
    // ----------------------------------------------


    //

    // Opens the connection and populates the dataset

    //

    conn.Open();
    da.Fill(ds,table);
    conn.Close();
    // ----------------------------------------------

   }
   catch(Exception e)
   {
    //

    // If an error occurs, we assign null to the result

    // and display the error to the user,

    // with information about the StackTrace for debugging purposes.

    //

    Console.WriteLine(e.Message + " - " + e.StackTrace);
   }
  }

  /// <SUMMARY>

  /// Uploads a file to the database server.

  /// </SUMMARY>

  /// <PARAM name="fileName">The filename of the picture to be uploaded</PARAM>

  /// <RETURNS>The id of the file on the server.</RETURNS>

  public long UploadFile(string FileName)
  {
   if (!File.Exists(FileName))
   {
    return -1;
   }

   FileStream fs=null;
   try
   {
    #region Reading file

    fs = new FileStream(FileName,FileMode.Open);

    //

    // Finding out the size of the file to be uploaded

    //

    FileInfo fi = new FileInfo(FileName);
    long temp = fi.Length;
    int lung = Convert.ToInt32(temp);
    // ------------------------------------------


    //

    // Reading the content of the file into an array of bytes.

    //

    byte[] picture=new byte[lung];
    fs.Read(picture,0,lung);
    fs.Close();
    // ------------------------------------------

    #endregion
    long result = uploadFileToDatabase(picture,fi.Name);

    return result;
   }
   catch(Exception e)
   {
    Console.WriteLine(e.Message + " - " + e.StackTrace);
    return -1;
   }
  }

  /// <SUMMARY>

  /// Wrapper for downloading a file from a database.

  /// </SUMMARY>

  /// <PARAM name="kFileName">The Unique ID of the file in database</PARAM>

  /// <PARAM name="fileName">The file name as it was stored

  ///                              in the database.</PARAM>

  /// <RETURNS>The byte array required OR null if the ID is not found</RETURNS>

  public byte[] DownloadFile(long kFileName, ref string fileName)
  {
   byte[] result = downloadFileFromDatabase(kFileName, ref fileName);
   return result;
  }

  /// <SUMMARY>

  /// Returns the connection string for connecting to the database

  /// </SUMMARY>

  /// <RETURNS>The Connection string.</RETURNS>

  public static string ConnectionString()
  {
   //

   // We consider that the database is situated

   // on the same computer that runs the program.

   // To connect to a remote server, replace 'Data Source'

   // with the name of that server.

   //

   return "Connect Timeout=600;Integrated Security=SSPI;" + 
          "Persist Security Info=False;Initial Catalog=Pictures;" + 
          "Packet Size=4096;Data Source=" + 
          System.Environment.MachineName.Trim();
  }

  /// <SUMMARY>

  /// Uploades a file to an SQL Server.

  /// </SUMMARY>

  /// <PARAM name="picture">A byte array that contains

  ///        the information to be uploaded.</PARAM>

  /// <PARAM name="fileName">The file name asociated

  ///                  with that byte array.</PARAM>

  /// <RETURNS>The unique ID of the file on the server

  ///              OR -1 if an error occurs.</RETURNS>

  private long uploadFileToDatabase(byte[] picture, string fileName)
  {
   //

   // Defining the variables required for accesing the database server.

   //

   SqlConnection conn = null;
   SqlCommand cmd =null;
   SqlParameter kFileName =null;
   SqlParameter FileName =null;
   SqlParameter pic =null;
   // By default, we assume we have an error. If we succed in uploading

   // the file, we'll change this 

   // to the unique id of the file

   long result=-1; 
    
   try
   {
    //

    // Connecting to database.

    //

    conn = new SqlConnection(ConnectionString());
    cmd = new SqlCommand("UploadFile",conn);
    // We assume there is a stored procedure called UploadFile


    cmd.CommandType = System.Data.CommandType.StoredProcedure;
    // ----------------------------------------------


    //

    // Initializing parameters and assigning

    // the values to be sent to the server

    //

    kFileName = new SqlParameter("@kFileName", 
                    System.Data.SqlDbType.BigInt,8);
    kFileName.Direction = ParameterDirection.Output;
    // This parameter does not have a size because

    // we do not know what the size is going to be.

    pic = new SqlParameter("@picture",SqlDbType.Image); 
    pic.Value = picture; 
    
    FileName = new SqlParameter("@FileName",SqlDbType.VarChar,250);
    FileName.Value = fileName;
    // ----------------------------------------------

   
    //

    // Adding the parameters to the database.

    // Remember that the order in which the parameters 

    //  are added is VERY important!

    //

    cmd.Parameters.Add(pic);
    cmd.Parameters.Add(FileName);
    cmd.Parameters.Add(kFileName);
    // ----------------------------------------------


    //

    // Opening the connection and executing the command.

    //

    conn.Open();
    cmd.ExecuteNonQuery();
    conn.Close();
    // ----------------------------------------------


    //

    // The result is the unique identifier created on the database.

    //

    result = (long)kFileName.Value;
    // ----------------------------------------------


    //

    // Disposing of the objects so we don't occupy memory.

    //

    conn.Dispose();
    cmd.Dispose();
    // ----------------------------------------------

   }
   catch(Exception e)
   {
    //

    // If an error occurs, we report it to the user,

    // with StackTrace for debugging purposes

    //

    Console.WriteLine(e.Message + " - " + e.StackTrace);
    result = -1;
    // ----------------------------------------------

   }

   return result; 
  }


  /// <SUMMARY>

  /// Downloades a file from a database according

  // to the unique id in that database.

  /// </SUMMARY>

  /// <PARAM name="kFile">The ID of the file in the database</PARAM>

  /// <PARAM name="FileName">The filename of the file

  ///                         as it was stored in the database.</PARAM>

  /// <RETURNS>A byte array containing

  ///                            the information required.</RETURNS>

  private byte[] downloadFileFromDatabase(long kFile, ref string FileName)
  {
   SqlConnection conn =null;
   SqlCommand cmd = null;
   SqlParameter kFileName = null;
   SqlParameter fileName = null;
   SqlDataReader dr=null;
   byte[] result=null;

   try
   {
    //

    // Connecting to database.

    //

    conn = new SqlConnection(ConnectionString());
    cmd = new SqlCommand("DownloadFile",conn);
    cmd.CommandType = System.Data.CommandType.StoredProcedure;
    // ----------------------------------------------


    //

    // Initializing parameters and assigning the values to be sent to the server

    //

    kFileName= new SqlParameter("@kFileName",System.Data.SqlDbType.BigInt,8);
    kFileName.Value = kFile;
    fileName = new SqlParameter("@FileName",SqlDbType.VarChar,250);
    fileName.Direction = ParameterDirection.Output;
    // ----------------------------------------------

   
    //

    // Adding the parameters to the database.

    // Remember that the order in which the parameters 

    // are added is VERY important!

    //

    cmd.Parameters.Add(kFileName);
    cmd.Parameters.Add(fileName);
    // ----------------------------------------------


    //

    // Opening the connection and executing the command.

    // The idea behind using a dataReader is that,

    // on the SQL Server, we cannot assign to a

    // variable the value of an image field.

    // So, we use a querry to select the record we want 

    // and we use a datareader to read that query.

    // Because we are returnig information based

    // on a primary key, we are always returning

    // only one row of data.

    //

    conn.Open();
    dr = cmd.ExecuteReader();
    dr.Read();
    //

    // We are casting the value returned

    // by the datareader to the byte[] data type.

    //

    result = (byte[])dr.GetValue(0);
    //

    // We are also returning the filename associated with the byte array.

    //

    FileName = (string)dr.GetValue(1);

    //

    // Closing the datareader and the connection

    //

    dr.Close();
    conn.Close();
    // ------------------------------------------


    //

    // Disposing of the objects so we don't occupy memory.

    //

    conn.Dispose();
    cmd.Dispose();
    // ------------------------------------------

   }
   catch(Exception e)
   {
    //

    // If an error occurs, we assign null

    // to the result and display the error to the user,

    // with information about the StackTrace for debugging purposes.

    //

    Console.WriteLine(e.Message + " - " + e.StackTrace);
    result = null;
   }
   return result;    
  }
 }
}

A sample application

I have also written a small application to demonstrate how to use these methods. A screenshot of it is shown below:

Application Screeshot

The application uploads a file to the server and displays a list of files on the server. When double-click-ing on the filename in the list, the file is downloaded and displayed in the picture box.

Below are some snippets of relevant code:

private void UploadedFiles_DoubleClick(object sender, System.EventArgs e)
  {
   //

   // Finds the unique id of the file.

   //

   DataRowView drv = (DataRowView) UploadedFiles.SelectedItem;
   string selectedText = drv.Row["Name"].ToString();
   long id=-1;
   id = long.Parse(selectedText.Substring(0,selectedText.IndexOf(" - ",0)).Trim());

   string filename=null;
   TransferPictures up = new TransferPictures();
   byte[] result = up.DownloadFile(id,ref filename);
   up = null;
   try
   {
    //

    // We cannot assign a byte array directly to an image. 

    // We use MemoryStream, an object that creates a file in memory

    //  and than we pass this to create the image object.

    //

    MemoryStream ms= new MemoryStream(result,0,result.Length);
    Image im = Image.FromStream(ms);
    Picture.Image = im;
   }
   catch(Exception ee)
   {
    MessageBox.Show("An error has occured.\n" + ee.Message);
   }
  }
  private void UploadFile_Click(object sender, System.EventArgs e)
  {
   //

   // Gets the file to be uploaded

   //

   OpenFileDialog ofd = new OpenFileDialog();
   ofd.ShowDialog();
   if (ofd.FileName=="" || !File.Exists(ofd.FileName))
   {
    //

    // If the requested file is not ok...

    //

    return;
   }

   TransferPictures up = new TransferPictures();
   long id =up.UploadFile(ofd.FileName);
   string msg=null;
   if (id >0)
   {
    msg = "Upload succesful";
    LoadInformationFromDataBase();
   }
   else
   { 
    msg = "An error has occured";
   }
   MessageBox.Show(msg);
  }

  private void LoadInformationFromDataBase()
  {
   TransferPictures up = new TransferPictures();
   up.GetUploadedFiles(ref ds,"Pictures");
 
   UploadedFiles.DataSource = ds.Tables["Pictures"];
   UploadedFiles.DisplayMember = "Name";
  }

  private void frmMain_Load(object sender, System.EventArgs e)
  {
   LoadInformationFromDataBase();
  }

Conclusion

Well, choosing which type of image � file � storage technique to use is up to the person designing a specific application. I have tried here to show you how you can store them in a database. Happy coding!

Bibliography

  1. Books Online
  2. MSDN
You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
Questionneed help to retrive picture
sudan prajapati
15:02 13 Jan '09  
i am using path to store picture in database but i am not baling to retrive and store the picture from database please help me in the code of c#.net in sql server i have used id as int and path varchar in table tb
insert into tb values(1,'c\pictur\sud.jpg'). please reply me as soon as possible. :

from
sudon
rolleyes:
QuestionNeed you help [modified]
Member 4227473
23:07 20 Nov '08  
Dear Dir/Madam

i would like you to help me to convert the project" Uploading / Downloading Pictures to / from a SQL Server" from C# to VB.net or can you give me the example for insert/update/delete/display student information with picture from SQL Server 2000 Database using VB.net.

I am looking forward from you.

thanks
Best Regard

Kosal
modified on Friday, November 21, 2008 4:16 AM

AnswerRe: Need you help
michie123
17:05 23 Dec '08  
hi. if possible email me i would like a this working example of uploading/downloading pictures from database in VB.net for my project if u have. please help!


best regards,
michelle
GeneralWOrking Example
mayurmv
18:20 5 Sep '08  
Visit http://developmentzone.blogspot.com/2008/09/store-and-retrieve-image-in-sql-server.html[^]
GeneralRe: WOrking Example
michie123
17:00 23 Dec '08  
hi. if possible email me i would like a this working example in VB.net for my project if u have. please help!


best regards,
michelle
QuestionError:while uploading or downloading bigger picture
m_salman
22:16 25 Sep '07  
Hi,
I am getting error while uploading and downloading a bigger image file that is of few MB's on to the server.
i am using the web service to upload and download data to/from server and the webservice give error when we are uploading/downloading larger data
so can any1 help me in this regard
thanks in advance
Salman
AnswerRe: Error:while uploading or downloading bigger picture
Alexandru Ghiondea
22:29 25 Sep '07  
The problem is in web.config. There is a setting that states the MaxRequestSize. This number states what is the maximum number of bytes the IIS will accept before timing out.

Alexandru Ghiondea
MCP
http://weblogs.studentclub.ro/aghiondea

GeneralUpload/Download Progress
Kerem Kat
2:58 26 Jun '07  
Hi, storage space is cheap here so we store 3 to 10 MB data in SQL from many low-bandwidth clients. Is there a way that we can see how much of the SqlCommand is send to the database? We only see now is Done or Error. tx.
GeneralRe: Upload/Download Progress
Alexandru Ghiondea
18:09 27 Jun '07  
Hi. .NET 2.0 Fx introduces the RetrieveStatistics method for a SqlConnection. You can use those statistics to see what is going on.

More details and an example you can find here: http://codebetter.com/blogs/david.hayden/archive/2005/11/02/134145.aspx[^]

Alexandru Ghiondea
MCP
http://weblogs.studentclub.ro/aghiondea

GeneralRe: Upload/Download Progress
Kerem Kat
1:21 3 Jul '07  
I've heard it but never used and thought of. But when I search MSDN and google, I have found that it show total bytes i.e. I want to see only one parameter's status in an INSERT INTO statement. It shows total bytes with network and SQL TDS overhead. It may be useful for seeing if any data is being sent at a moment which is not as useful to me. But I will use it in other projects. Thanks for your interest.
GeneralRe: Upload/Download Progress
Alexandru Ghiondea
20:41 3 Jul '07  
Well, you still can use this method. You can calculate! You know what is the size of the parameter that you want to sent to SQL Server and you can use this thing to get the data at one moment and extrapolate as to how much data has been transfered and how many you still have to transmit.

If you find a better solution I would appreciate it if you would post the solution here as well.

Thank you,

Alexandru Ghiondea
MCP
http://weblogs.studentclub.ro/aghiondea

GeneralImage storage
samshah512
7:09 19 May '07  
Hi

I am in a process of storing image in the database in binary and then retriveing the image from the database in orignal form.

I would appreciate if someone could help.

Thanks,
Ali

Life is too short to be counted ,enjoy life.
GeneralRe: Image storage
Alexandru Ghiondea
20:12 25 May '07  
Hi - how can I help you? The article should be enough for what you where trying to do.

Let me know!

Alexandru Ghiondea
MCP
http://weblogs.studentclub.ro/aghiondea

GeneralCan this be used to view PDF Files
mgardiner1
9:11 26 Mar '07  
How can I use this process to view PDF Files single page and Multiple Page files?

mgardiner1
GeneralRe: Can this be used to view PDF Files
Alexandru Ghiondea
20:11 25 May '07  
Well, you can store any kind of file in the database... it depends on you to retrieve the data and display it to the user. In your case, you could launch Adobe when you get the file from the database.

Let me kwno if I can help you further!

Alexandru Ghiondea
MCP
http://weblogs.studentclub.ro/aghiondea

GeneralRe: Can this be used to view PDF Files
Alexandru Ghiondea
1:00 26 Sep '07  
I don't think you can use this process for that Smile .

Alexandru Ghiondea
MCP
http://weblogs.studentclub.ro/aghiondea

GeneralInserting Images in Database
tonyg2smith
4:34 6 Oct '06  

Hi All,

I am brand new to .NET / SQL Server technologies etc and am just coming to terms with it, so apologies if I'm missing something basic here.

I am using SQL Server 2005.

I have created a database with a VARBINARY(MAX) column, into which I want to store images.

NOTE:I am using this data type as opposed to the imaga data type as I've read in a few places that the image data type is being phased out, see link below...

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=622943&SiteID=1

Maybe someone could advise if this is correct? Opinions....

Anyhow, back to my question, I am using Visual Web Developer in my project. I already have 100+ images which I want to store in my database, along with other columns for text. It's easy to populate the database with textual data, using the show table data option in Database Explorer. Is there not a similar way of populating the VARBINARY(MAX) / IMAGE column, without coding. There doesn't seem to be which I find surprising. Maybe someone could clarify this for me.

Your help would be much appreciated!

Thanks in advance,

Tony
AnswerRe: Inserting Images in Database
Alexandru Ghiondea
5:33 20 Oct '06  
Hi Tony

I don't think that there is a way to add data to a Varbinary column. You could try SQL Server Management Studio Express Edition (which is free) - but its a long shot.

I think its simpler to just upload the data using a small sized application.

Alex.
GeneralRe: Inserting Images in Database
tonyg2smith
5:51 20 Oct '06  
Hey Alex,

Thank you for the reply. I've actually since solved the problem and am saving images to the database as bytes. I eventually got the code working to save the uploaded image to the database.

I am stuck on another similar problem though so maybe you could advise me on my current problem.

I am using the response.writebinary method to retrieve the image from the database, and this works fine. However, I want to display the image on my page along with some text and other images, and this is where my problem lies...

When I leave in the line response.writebinary, only the image is displayed. When commented out the page displays the other information I need on the page. Is there something wrong with using the response.writebinary line?? Any know anything of this, or can suggest a possible workaround??

Any advice would be VERY welcome Big Grin

Thanks in advance,

Tony
GeneralRe: Inserting Images in Database
Alexandru Ghiondea
7:40 20 Oct '06  
Hi Tony.

Can you please be more specific? From what you said, I understood the fact that you are using a web application, and retrieving the pictures from the database and then using the WriteBinary method to disply the image in a file. Is that correct?

Are you using a .NET function called WriteBinary?

Alex
GeneralRe: Inserting Images in Database
tonyg2smith
0:31 21 Oct '06  
Hi Alex,

Yes your understanding is correct. I'm using the ASP.NET 2 function writebinary

Here are the specifics....

I have one page (StaffListing.aspx) which has a gridview, showing all employee details. When the user selects one record a popup window (ViewEmployee.aspx) appears which should show that employees full details i.e. id, name, photo and signature. I am passing the employee's ID through the address bar i.e. ViewEmployee.aspx?empID=7 etc

The popup window is taking this ID and retrieving the details for that employee. This is all working well for me so far. However, my problem is that I cant get the image and text displayed side by side in the popup. If I display the image using the writebinary method the image is displayed, but no text. When I comment out the writebinary method the text is there.

Thanks for your help Alex,

I can post my code if you need to see it on Monday when back in the office.

Tony
AnswerRe: Inserting Images in Database
Alexandru Ghiondea
1:47 21 Oct '06  
Hi Tony.

The .NET Framework does not define a WriteBinary method. You only get a Write method. Are you sure that the method is not something you, or someone else, wrote?

If the method was written by someone else, check to see if the method calls the Response.End(). What this method (End()) does is that it finishes with creating the response and sends it to the user. This means that the rest of the details are not visible. This explains the behaviour you described.

Try putting the WriteBinary call at the end of the function that displays the text, or modify the WriteBinary function so it does not call Response.End().

Alex


GeneralRe: Inserting Images in Database
tonyg2smith
7:58 21 Oct '06  
Hi Alex,

Apologies, its Response.WriteBinary I'm using. I'm sure it wasn't written by someone else.

I've tried a few things, moving code around etc but still no change.

Any ideas on this??

Thanks for the help as always.

Tony
GeneralRe: Inserting Images in Database
Alexandru Ghiondea
9:08 21 Oct '06  
Hi Tony.

I just can't find the method WriteBinary in any documentation. Do you have a link to a msdn description? Also, can you provide some code samples?

Best,
Alex
GeneralRe: Inserting Images in Database
tonyg2smith
13:00 21 Oct '06  
Hey Alex,

Here's a link from msdn for you...seems to be the only information available on MSDN regarding the response.writebinary method.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/comsrv2k/htm/cs_sp_genpurposeobj_bfiq.asp

I'll post my code on Monday when I'm back in the office for you.

In meantime, pseudo code is:

1 - get ID from URL
2 - Run query getting all details from table where id = the id passed through URL
3 - Assign returned values from DB to txtName.Text etc
4 - use response.writebinary method to display the picture

Let me know how you get on with that

Tony


Last Updated 29 Oct 2004 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010