Click here to Skip to main content
15,897,187 members
Articles / Programming Languages / C#
Article

Executing Stored Procedure with Data Reader

Rate me:
Please Sign up or sign in to vote.
1.33/5 (6 votes)
31 May 2007CDDL6 min read 103.7K   14   6
Data Reader use to read data from Sql server stored procedure
Screenshot - dotnet_stored_procedure.gif

Introduction

This example shows how to execute a stored procedure. We will be using the CustOrdersDetail stored procedure that comes with the SQL Server Northwind database. The stored procedure is shown below; it takes an OrderID and returns the details for that order. The example shows the following core features:

Background

The GetOrdinal method of the DataReader provides a way to access data in a type-safe manner. GetOrdinal takes the column name as a parameter, and returns that column's ordinal position.

iOrderID = reader.GetOrdinal("OrderID");
orderIDsList.Items.Add (reader.GetInt32(iOrderID));

The command object does most of the work when executing stored procedures. We still use the DataReader in exactly the same way we normally would:

SqlCommand storedProcCommand =
new SqlCommand ("CustOrdersDetail", con);
storedProcCommand.CommandType = CommandType.StoredProcedure;
storedProcCommand.Parameters.Add("@OrderID",orderID);

The first line constructs the SqlCommand object with the name of the stored procedure as the first argument. The second argument is the connection object.

The second line line tells the command object that a stored procedure is going to be executed.

The third line adds parameters to the command object. Note the use of the @ symbol, all the information in the command object is constructed to make a SQL statement. The @ symbol in a SQL statement us used to denote a parameter.

It is quite often useful to get the result set's schema. The DataReader provides a message that does just this. It's called GetSchemaTable. GetSchemaTable returns a DataTable that describes the column metadata of the DataReader. ColumnName is the name of the column; this might not be unique. If this cannot be determined, a null value is returned. This name always reflects the most recent renaming of the column in the current view or command text.

DataTable schema = reader.GetSchemaTable();
orderDetailsList.Columns.Add((string)row["ColumnName"],50,
HorizontalAlignment.Left);

First we create an array of objects. Each object in the array represents a column in the DataReader. We know how many columns are in the DataReader by using the FieldCount property. Now we have the array of objects we need to get some values. If we wanted, we could get each value individually and add it to the array; another way is to use the GetValues method. This method will populate our object array with the column values currently in the DataReader.

ArrayList rowList = new ArrayList();
SqlDataReader reader = storedProcCommand.ExecuteReader();
while (reader.Read())
{
object[] values = new object[reader.FieldCount];
reader.GetValues(values);
rowList.Add(values);
}

The first thing we have to do is to clear the ListView. Now we need to add the column values for each row into the ListView. We will do this by creating a ListViewItem object and adding that to the Items collection of the ListView. In order to create a ListViewItem we want to create an array of strings, where each string in the array corresponds to a column in the ListView. Using the Length property of the "row" in the ArrayList we are able to allocate enough strings in the string array to hold each column that exits in the row. Once we have built the string array, we create a new ListViewItem and add it to the ListView.

orderDetailsList.Items.Clear();

foreach (object[] row in rowList)
{
string[] orderDetails = new string[row.Length];
int columnIndex = 0;

foreach (object column in row)
{
orderDetails[columnIndex++] = Convert.ToString(column);
}

ListViewItem newItem = new ListViewItem (orderDetails);
orderDetailsList.Items.Add (newItem);
}

Stored Procedure Code

CREATE PROCEDURE CustOrdersDetail @OrderID int
AS
SELECT ProductName,
UnitPrice=ROUND(Od.UnitPrice, 2),
Quantity,
Discount=CONVERT(int, Discount * 100),
ExtendedPrice=ROUND(CONVERT(money,
Quantity * (1 - Discount) * Od.UnitPrice), 2)
FROM Products P, [Order Details] Od
WHERE Od.ProductID = P.ProductID and Od.OrderID = @OrderID

Code Behind File

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;

namespace Akadia
{
public class SqlBrowser : System.Windows.Forms.Form
{
private System.Windows.Forms.ListBox orderIDsList;
private System.Windows.Forms.ListView orderDetailsList;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.ComponentModel.Container components = null;
private System.Data.SqlClient.SqlConnection con;
private System.Windows.Forms.Button btnStart;
private bool _columnsSet = false;

public SqlBrowser()
{
// Create Controls
InitializeComponent();

// Setup Connection
string strCon = "server=xeon;uid=sa;" +
"pwd=manager; database=northwind";
con = new SqlConnection(strCon);
}

.....
.....

// The main entry point for the application.
static void Main()
{
Application.Run(new SqlBrowser());
}

// Fill orderIDsList with OrderID's
private void btnStart_Click(object sender, System.EventArgs e)
{
int iOrderID;

// Create a command to select the Order IDs from the ORDERS table
SqlCommand command = new SqlCommand
("SELECT OrderID from ORDERS", con);

// Open the connection
con.Open();

// Get the data reader
SqlDataReader reader = command.ExecuteReader();

// Process each result
while (reader.Read())
{
// Add each order ID in the result to the list
// view containing the orders IDs. We have only
// selected a single column in this code so we
// can be pretty save in using reader.GetInit32(0)
// there are no more columns in the data reader.
iOrderID = reader.GetOrdinal("OrderID");
orderIDsList.Items.Add (reader.GetInt32(iOrderID));

}

// Close the reader and the connection
reader.Close();
this.con.Close();
}

// Populate the list view with the order details
//
// Used Stored Procedure:
// ----------------------
// CREATE PROCEDURE CustOrdersDetail @OrderID int
// AS
// SELECT ProductName,
// UnitPrice=ROUND(Od.UnitPrice, 2),
// Quantity,
// Discount=CONVERT(int, Discount * 100),
// ExtendedPrice=ROUND(CONVERT(money, Quantity *
// (1 - Discount) * Od.UnitPrice), 2)
// FROM Products P, [Order Details] Od
// WHERE Od.ProductID = P.ProductID and Od.OrderID = @OrderID
//
private void orderIDsList_SelectedIndexChanged
(object sender, System.EventArgs e)
{
// Get the selected item and convert it to the correct order ID
int orderID = Convert.ToInt32(orderIDsList.SelectedItem);

// Create a command to execute a stored procedure
SqlCommand storedProcCommand =
new SqlCommand ("CustOrdersDetail", con);

// Let the command know it will be executed a stored procedure
storedProcCommand.CommandType = CommandType.StoredProcedure;

// Add a parameter that's passed to the stored proc,
// this is the order ID we selected
storedProcCommand.Parameters.Add("@OrderID",orderID);

// Open the connection
con.Open ();

// Create an ArrayList to hold the results
ArrayList rowList = new ArrayList();

// Get the reader
SqlDataReader reader = storedProcCommand.ExecuteReader();

// Process each result in the result set
while (reader.Read())
{
// Create an array big enough to hold the column values
object[] values = new object[reader.FieldCount];

// Get the column values into the array
reader.GetValues(values);

// Add the array to the ArrayList
rowList.Add(values);
}

// Have the columns already being added to the list view?
if (_columnsSet == false)
{
// No, so get the schema for this result set
DataTable schema = reader.GetSchemaTable();

// And set the list view to reflect the
// contents of the schema
SetColumnHeaders(schema);
}

// Close the reader and the connection
reader.Close ();
con.Close ();

// Now populate the list view with the order details
PopulateOrderDetails(rowList);
}

// Populate the list view with the order details
private void PopulateOrderDetails (ArrayList rowList)
{
// Clear any exsisting items from the orders view
orderDetailsList.Items.Clear();

// Now process each array in the arraylist
foreach (object[] row in rowList)
{
// Create a string array large enough to hold all
// the column values in this array
string[] orderDetails = new string[row.Length];

// Create a column index into the array
int columnIndex = 0;

// Now process each column value
foreach (object column in row)
{
// Convert the value to a string and stick
// it in the string array
orderDetails[columnIndex++] = Convert.ToString (column);
}

// Now use the string array to create a new item
// to go in the list view
ListViewItem newItem = new ListViewItem (orderDetails);

// Finally add the new item to the view
orderDetailsList.Items.Add (newItem);
}
}

// Set the list view to reflect the contents of the schema
private void SetColumnHeaders (DataTable schema)
{
// Process each row in the schema table
foreach (DataRow row in schema.Rows)
{
// For each column add a new column to the list view
orderDetailsList.Columns.Add((string)row["ColumnName"],
50, HorizontalAlignment.Left);

}

// Set this flag to stop the method being called again
_columnsSet = true;
}
}
}

Enjoy!!!!!!!!!!!!!

Screenshot - tariq.jpg

License

This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)


Written By
Web Developer
Pakistan Pakistan
Always make your absence felt in such a way that someone misses you but dont let your absense be so long that someone starts learning to live without you.

Comments and Discussions

 
PraiseNice article Pin
José Carvalho 20218-May-21 12:23
José Carvalho 20218-May-21 12:23 
GeneralMy vote of 1 Pin
Aamer Alduais8-May-12 1:57
Aamer Alduais8-May-12 1:57 
GeneralMy vote of 1 Pin
Sharad Mishra12-Sep-10 19:57
Sharad Mishra12-Sep-10 19:57 
GeneralRetrieve data and put it in textbox Pin
danielwinata6-Jun-07 21:27
professionaldanielwinata6-Jun-07 21:27 
GeneralRe: Retrieve data and put it in textbox Pin
JoeSharp6-Jun-07 21:47
JoeSharp6-Jun-07 21:47 
GeneralRe: Retrieve data and put it in textbox Pin
danielwinata6-Jun-07 23:32
professionaldanielwinata6-Jun-07 23:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.