You’ll call the sp_Orders_By_EmployeeId2stored procedure, supplying the employee ID as an input parameter and displaying the result set, the output parameter, and the return value.
1. Add a new C# Console Application project named CallSp2to your Chapter12solu- tion. Rename Program.csto CallSp2.cs.
2. Replace the code in CallSp2.cswith the code in Listing 12-2.
Figure 12-12.Running a stored procedure with C#
Listing 12-2.CallSp2.cs using System;
using System.Data;
using System.Data.SqlClient;
namespace Chapter12 {
class CallSp2 {
static void Main() {
// create connection
SqlConnection conn = new SqlConnection(@"
server = .\sqlexpress;
integrated security = true;
database = northwind
");
try {
// open connection conn.Open();
// create command
SqlCommand cmd = conn.CreateCommand();
// specify stored procedure to execute
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "sp_orders_by_employeeid2";
// create input parameter
SqlParameter inparm = cmd.Parameters.Add(
"@employeeid"
, SqlDbType.Int );
inparm.Direction = ParameterDirection.Input;
inparm.Value = 2;
// create output parameter
SqlParameter ouparm = cmd.Parameters.Add(
"@ordercount"
, SqlDbType.Int );
ouparm.Direction = ParameterDirection.Output;
// create return value parameter
SqlParameter retval = cmd.Parameters.Add(
"return_value"
, SqlDbType.Int );
retval.Direction = ParameterDirection.ReturnValue;
// execute command
SqlDataReader rdr = cmd.ExecuteReader();
// Process the result set while (rdr.Read()) {
Console.WriteLine(
"{0} {1}"
, rdr[0].ToString().PadRight(5) , rdr[1].ToString()
);
}
rdr.Close();
// display output parameter value Console.WriteLine(
"The output parameter value is {0}"
, cmd.Parameters["@ordercount"].Value );
// display return value Console.WriteLine(
"The return value is {0}"
, cmd.Parameters["return_value"].Value );
}
catch (SqlException ex) {
Console.WriteLine(ex.ToString());
} finally {
conn.Close();
} } } }
3. Make this the startup project and run it by pressing Ctrl+F5. You should see the result in Figure 12-13.
How It Works
This is very much like the previous example. The main difference was that you added three command parameters, specifying the kind of parameter with the Direction property:
Figure 12-13.Using parameters and the return value with C#
// create input parameter
SqlParameter inparm = cmd.Parameters.Add(
"@employeeid"
, SqlDbType.Int );
inparm.Direction = ParameterDirection.Input;
inparm.Value = 2;
// create output parameter
SqlParameter ouparm = cmd.Parameters.Add(
"@ordercount"
, SqlDbType.Int );
ouparm.Direction = ParameterDirection.Output;
// create return value parameter
SqlParameter retval = cmd.Parameters.Add(
"return_value"
, SqlDbType.Int );
retval.Direction = ParameterDirection.ReturnValue;
You set the input parameter value to 2 before the call inparm.Value = 2;
and retrieved the values for the output parameter and return value by indexing into the command’s parameters collection after the stored procedure returned:
// display output parameter value Console.WriteLine(
"The output parameter value is {0}"
, cmd.Parameters["@ordercount"].Value );
// display return value Console.WriteLine(
"The return value is {0}"
, cmd.Parameters["return_value"].Value );
You can create as many input and output parameters as you need. You must provide command parameters for all input parameters that don’t have default values. You don’t
have to provide command parameters for any output parameters you don’t need to use.
Input and output parameter names must agree with the parameter names in the stored procedure, except for case (remember that T-SQL is not case sensitive).
Though it’s handled in ADO.NET as a command parameter, there is always only one return value. As with output parameters, you don’t need to create a command parameter for the return value unless you intend to use it. But unlike with input and output parame- ters, you can give it whatever parameter name you choose.
Summary
In this chapter you created simple stored procedures to get a feel for the kind of input and output they provide, as a basis for understanding what’s involved in calling stored procedures from C#. You saw that calling stored procedures isn’t inherently different from executing queries and statements. You simply create appropriate command parameters for the stored procedure parameters you need to use.
You applied the same techniques that you practiced in earlier chapters. We didn’t cover handling multiple result sets from stored procedures, because you use the same technique as for queries, which you used in Chapter 7.
Now you’ll extend your database programming skills to handle ADO.NET and data- base exceptions.
Handling Exceptions
Up to now, we’ve been rather relaxed in our handling of database exceptions. Robust database applications demand more careful attention to this important issue. Structured exception handling is both elegant and robust. In database programming, errors come from three sources: application programs, ADO.NET, and database servers. We assume you’re familiar with handling application exceptions in C# with trystatements, so we’ll focus on the last two sources.
In this chapter, we’ll cover: