DAL: Retrieve a DataTable using a Stored Procedure

Posted Tue, Jul 7 2009 15:08 by Deborah Kurata

This post provides an implementation of a method that retrieves a DataTable from a SQL Server database using a stored procedure. Your application can then use the DataTable to populate your business objects or to bind directly to a UI control such as a Combo Box or Grid (such as the DataGridView).

NOTE: This post assumes you already have a stored procedure defined to select the required data from your database. For more information on stored procedures, see this link.

The code is first shown in both VB and C#. It is then described in detail below.

In C#:

public static class Dac
{

public static DataTable ExecuteDataTable(string storedProcedureName, 
                                     params SqlParameter[] arrParam) 
{
    DataTable dt = new DataTable();

    // Open the connection
    using (SqlConnection cnn = new SqlConnection(
           "Data Source=.\sqlexpress;Initial Catalog=AcmeRentals;
                                    Integrated Security=True"))
    {
        cnn.Open();

        // Define the command
        using (SqlCommand cmd = new SqlCommand())
        {
            cmd.Connection = cnn;
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = storedProcedureName;

            // Handle the parameters
            if (arrParam != null)
            {
                foreach (SqlParameter param in arrParam)
                    cmd.Parameters.Add(param);
            }

            // Define the data adapter and fill the dataset
            using (SqlDataAdapter da = new SqlDataAdapter(cmd))
            {
                da.Fill(dt);
            }
        }
    }
    return dt;
}
}

In VB:

Public Class Dac

  Public Shared Function ExecuteDataTable(ByVal storedProcedureName _
        As String, _
        ByVal ParamArray arrParam() As SqlParameter) As DataTable
    Dim dt As DataTable

    ' Open the connection
    Using cnn As New SqlConnection(
           "Data Source=.\sqlexpress;Initial Catalog=AcmeRentals;
                                    Integrated Security=True;")
        cnn.Open()

        ' Define the command
        Using cmd As New SqlCommand
            cmd.Connection = cnn
            cmd.CommandType = CommandType.StoredProcedure
            cmd.CommandText = storedProcedureName

            ' Handle the parameters
            If arrParam IsNot Nothing Then
                For Each param As SqlParameter In arrParam
                    cmd.Parameters.Add(param)
                Next
            End If

            ' Define the data adapter and fill the dataset
            Using da As New SqlDataAdapter(cmd)
                dt = New DataTable
                da.Fill(dt)

            End Using
        End Using
    End Using

    Return dt
  End Function

End Class

The ExecuteDataTable function is in my Dac (data access component) class and defined to be public and static (shared in VB). It is public so it can be called from any other code. It is static/shared because it does not use or retain any state. That allows the function to be called without creating a instance of the class containing the function.

The function has two parameters. The first is the name of a stored procedure. Since this code returns a DataTable, it assumes that the stored procedure contains one Select statement. Here is an example:

CREATE PROCEDURE dbo.CustomerRetrieveAll
AS
    SELECT    
                CustomerId,
                LastName,
                FirstName
    FROM       
                Customer
    ORDER BY
                LastName + ', ' + FirstName

The second parameter is a parameter array that allows defining any parameters required by the stored procedure. In the CustomerRetrieveAll example, there are no parameters. But your stored procedure may have parameters to filter the data.

NOTE: A parameter array permits a variable number of arguments to be passed to a method. So this allows any number of parameters.

The first line of code defines a variable for the DataTable. It is used as the return value from the function.

The first Using statement defines the connection. You will need to replace the connection string in the example with a connection string appropriate for your database.

The connection is then opened.The connection is automatically closed at the end of the Using block.

The second Using statement defines the command. In this case, the command is a stored procedure and the CommandText property of the command defines the stored procedure name.

If parameters were passed in, the parameters are added to the command’s Parameters.

The third Using statement defines a DataAdapter. The Fill method of the DataAdapter fills the DataTable with the data returned from the stored procedure.

Since the code uses the Using statement, all of the objects are appropriately closed and disposed.

The resulting filled DataTable is then returned.

As an example, this is how you call this method.

In C#:

DataTable dt = Dac.ExecuteDataTable("CustomerRetrieveAll", null);

In VB:

Dim dt As DataTable = Dac.ExecuteDataTable("CustomerRetrieveAll", _
                                                          
nothing)

If the stored procedure had parameters, you would call it like this:

In C#:

DataTable dt = Dac.ExecuteDataTable("CustomerRetrieveById",
                         new SqlParameter("@CustomerID", custId));

In VB:

Dim dt As DataTable = Dac.ExecuteDataTable("CustomerRetrieveById", _ 
                        
new SqlParameter("@CustomerID", custId))

Enjoy!

P.S. (Edited 8/21/09)

In the interest of having code that any reader can copy/paste into their own application without much external setup, I have removed the code that uses an application setting to define the connection string.

The removed text is here: "The connection string itself is stored in the configuration file using the Settings feature in Visual Studio. (See this for information on settings in C# and this for information on settings in VB.)"

Instead, a connection string is hard-coded into the example. Though I don't recommend this approach, it will help readers use these examples more easily.

EDIT: (2/1/10)

The VB code was missing an End Using statement. The code is now corrected.

Filed under: , , , , ,

Comments

# DAL: Data Access Layer

Tuesday, July 07, 2009 5:11 PM by Deborah's Developer MindScape

One of the common ways to access data in a .NET application is to use the drag and drop TableAdapter

# re: DAL: Retrieve a DataTable using a Stored Procedure

Wednesday, July 08, 2009 7:14 AM by Jack Dolby

Deborah, could you do a post on creating/maintaining SPs, including when one should lean toward a SP versus a dotnet query?

TIA,

jack

# re: DAL: Retrieve a DataTable using a Stored Procedure

Wednesday, July 08, 2009 12:25 PM by Deborah Kurata

Hi Jack -

I just posted this:

msmvps.com/.../dal-using-stored-procedures.aspx

Hope it provides the information you are looking for.

# Populating a Business Object from a DataTable

Friday, July 10, 2009 4:12 PM by Deborah's Developer MindScape

Most business applications have business objects such as customer, order, or invoice. Often, the data

# re: DAL: Retrieve a DataTable using a Stored Procedure

Thursday, August 13, 2009 11:49 AM by JP

How are parameters passed in? Can you give me an example?

# re: DAL: Retrieve a DataTable using a Stored Procedure

Thursday, August 13, 2009 5:15 PM by Deborah Kurata

Hi JP -

Thank you for visiting my blog!

I added an example demonstrating how to pass parameters to the ExecuteDataTable method.

Thanks for your suggestion!

# re: DAL: Retrieve a DataTable using a Stored Procedure

Thursday, August 13, 2009 5:53 PM by JP

Very cool.  Multiple params go in as a comma separated list:

Dim dt As DataTable = Dac.ExecuteDataTable("CustomerRetrieveById", _

                        new SqlParameter("@CustomerID", custId), new SqlParameter("@UserID", userId), )

Thanks :)

# re: DAL: Retrieve a DataTable using a Stored Procedure

Thursday, August 13, 2009 5:56 PM by JP

On a side note, how are multiple connections handled?  Lets say a build a data grid, and on item databound I make another database call.

# re: DAL: Retrieve a DataTable using a Stored Procedure

Thursday, August 13, 2009 6:54 PM by Deborah Kurata

Hi JP -

The Using statement ensures that the connection is closed after every call to this function. SQL Server's connection pooling prevents performance issues.

Hope this helps.

# re: DAL: Retrieve a DataTable using a Stored Procedure

Wednesday, September 16, 2009 5:38 AM by Jim Hardwork

Can you post a soltion file with all code in the related Data Access examples.

# re: DAL: Retrieve a DataTable using a Stored Procedure

Wednesday, September 16, 2009 10:17 AM by Deborah Kurata

Hi Jim -

There are examples here:

www.insteptech.com/.../samplecode.htm

Hope this helps.

# re: DAL: Retrieve a DataTable using a Stored Procedure

Wednesday, September 23, 2009 8:51 PM by gamena

hi deborah,

just want to ask if you have a sample n-tier architecture, 5-tiers which includes entities, DAL, proxy, UI and data source-

im trying to make a system using this 5 tiers for the winforms application...

hope you can help me with this. a sample program could help. with add, delete, update and edit using stored procs.

many thanks. God bless.

# re: DAL: Retrieve a DataTable using a Stored Procedure

Friday, September 25, 2009 11:57 AM by Deborah Kurata

Hi Gamena -

The sample application I have is here:

www.insteptech.com/.../samplecode.htm

Enjoy!

# re: DAL: Retrieve a DataTable using a Stored Procedure

Sunday, February 07, 2010 9:21 AM by Deborah Kurata

 Hi Deborah?

I've read your article on your blog

msmvps.com/.../dal-retrieve-a-datatable-using-a-stored-procedure.aspx

on how to access Data from stored produres, in the paramters list of ExecuteDateTable(string SPName, param SQLParameter[] arrparam)

methods accepts a SQL parameter collection, to my knowledge that we dont create SQLParameters in the BLL that acess DAL..... have you given this as a snippet? If so disregard this....

If not, how im going to pass SQLparameter objects from BLL?

thanks

Indunil

# re: DAL: Retrieve a DataTable using a Stored Procedure

Sunday, February 07, 2010 9:23 AM by Deborah Kurata

Hi Indunil -

There are several options:

1) You can define your own name/value collection for the parameters in the BL and pass those to the DL. That way you don't have to have a reference to system.data in the BL.

2) You could build code that uses reflection to read your BL properties and builds the appropriate parameters for your stored procedures.

Hope this helps.

# re: DAL: Retrieve a DataTable using a Stored Procedure

Wednesday, February 24, 2010 5:58 AM by Byambaa

hi it is very helpful article. i have a question. If the stored procedure had parameters with value and multiple parameters, what would i call it?

i wrote:

           DataTable dt = ExecuteDataTable("ProcedureName",

                        new SqlParameter("@prog", 1),

                        new SqlParameter("@Sur", "C"));

it is incorrect.

# re: DAL: Retrieve a DataTable using a Stored Procedure

Wednesday, February 24, 2010 10:16 AM by Deborah Kurata

Hi Byambaa -

Yes, you would separate the parameters with commas. The code you posted looks correct.

# re: DAL: Retrieve a DataTable using a Stored Procedure

Monday, March 22, 2010 3:16 PM by Joseph Davis

Thanks for this piece of code it really helped.  

# re: DAL: Retrieve a DataTable using a Stored Procedure

Thursday, April 01, 2010 1:48 AM by Matt

You saved me!  I was going crazy trying to figure this out.  Thanks very much!

# re: DAL: Retrieve a DataTable using a Stored Procedure

Friday, April 09, 2010 5:44 AM by MarkP

Hi Deborah,

Many thanks for that, it is a simple elegant solution to what I was looking for.

MarkP

# re: DAL: Retrieve a DataTable using a Stored Procedure

Tuesday, May 25, 2010 4:08 PM by Paul G

Thanks Deborah for the code, this really helped.

A couple quick alterations and you can avoid referencing SqlClient in your business logic, using ListItemCollection instead of SqlParameters. I'm not sure if this is efficient or not.

maybe somebody else will improve this...

(I removed "shared" from the declaration. Still playing with this)

----------

Public Function ExecuteDataTable(ByVal storedProcedureName _

         As String, _

         ByVal spParams As ListItemCollection) As DataTable

       Dim dt As DataTable

       Dim sqlParam As New SqlParameter

----------

               ' Handle the parameters

               If spParams IsNot Nothing Then

                   For Each param As ListItem In spParams

                       sqlParam = New SqlParameter(param.Text, param.Value)

                       cmd.Parameters.Add(sqlParam)

                   Next

               End If

----------

       Dim spParams = New ListItemCollection

       spParams.Add(New ListItem("@param1", "foo"))

       spParams.Add(New ListItem("@param2", "bar"))

       Dim dataRes As DataAccess

       dataRes = New DataAccess

       Dim dtMyData As DataTable = dataRes.ExecuteDataTable("sp_myStoredProc", spParams)

# re: DAL: Retrieve a DataTable using a Stored Procedure

Tuesday, May 25, 2010 4:12 PM by Deborah Kurata

Hi Paul -

Thanks for the info.

In my "real" applications, I often create my own parameter class in the DAL that creates the actual SQL parameters. This then allows me to use my own class and not reference the SQLClient in my business objects.

Thanks again!

# re: DAL: Retrieve a Data setusing a Stored Procedure

Thursday, May 12, 2011 5:53 AM by manu

---------

# re: DAL: Retrieve a DataTable using a Stored Procedure

Wednesday, April 11, 2012 6:51 PM by salimi

very good tanx

Leave a Comment

(required) 
(required) 
(optional)
(required) 
If you can't read this number refresh your screen
Enter the numbers above: