DATABASE

ADO.NET Programming : Microsoft SQL Server (part 2) - Using SQL Server Stored Procedures

5/22/2013 9:47:33 PM

3. Using SQL Server Stored Procedures

A stored procedure is a procedure that is written in SQL, stored in a SQL Server database, and executable by a client program. It can have input and output parameters and returns an integer value. A stored procedure can be as simple as a single SELECT statement or as complex as a multitable update with parameter checking and error handling. Stored procedures encapsulate functionality on the server side.

One benefit of stored procedures is that they execute much more quickly than the same logic would in a submitted batch of SQL statements. With a stored procedure, the database engine performs query analysis and optimization and caches the compiled query optimization plan when the stored procedure is first created. On subsequent executions of the stored procedure, the database engine can bypass the analysis, optimization, and compilation. To execute a submitted batch of SQL statements, on the other hand, the entire process must be performed each time a batch is submitted.

Listing 2 shows a stored procedure that updates name and price information for a specified product. We use this stored procedure, named procModifyProductInfo, during this discussion. It is not the most efficient code ever written, but it is straightforward and readable, and it adheres to the SQL Server convention that successfully executed procedures should return 0.

Listing 2. The procModifyProductInfo Stored Procedure
CREATE PROCEDURE procModifyProductInfo
   @ProductID int = null,
   @ProductName nvarchar(40) = null,
   @UnitPrice money = null
AS
BEGIN
   IF @ProductID is null
   BEGIN
      RAISERROR('Product ID not supplied.',10,1)
      RETURN 1
   END

   IF not exists (SELECT *
                    FROM Products
                   WHERE ProductID = @ProductID)
   BEGIN
      RAISERROR('Product ID not on file.',10,1)
      RETURN 1
   END

   BEGIN TRANSACTION

   IF @ProductName is not null
      UPDATE Products
         SET ProductName = @ProductName
         WHERE ProductID = @ProductID
   IF @@ERROR <> 0
   BEGIN
      ROLLBACK TRANSACTION
      RAISERROR('Unable to update Products table.',10,1)
      RETURN 1
   END

   IF @UnitPrice is not null
      UPDATE Products
         SET UnitPrice = @UnitPrice
         WHERE ProductID = @ProductID
   IF @@ERROR <> 0
   BEGIN
      ROLLBACK TRANSACTION
      RAISERROR('Unable to update Products table.',10,1)
      RETURN 1
   END

   COMMIT TRANSACTION
   RETURN 0
END

					  

Client programs execute the stored procedure by submitting the following SQL statement, for example, to the SQL Server. The sample statement shown here changes the name and price of product 18 to “Carnavon Tigers” and $987.65, respectively.

EXEC procModifyProductInfo 18, 'Carnavon Tigers', 987.65

To submit this SQL statement to the server, your application could set the statement into the CommandText property of a command object and then call the ExecuteNoResults method. But there is a better way, one that makes it easier to repetitively reexecute the same procedure with new parameter values each time and to access the return value. In your application, perform the following steps.

1.
Create the connection and command objects.

2.
Set the command object’s CommandType property to CommandType.StoredProcedure.

3.
Set the command object’s CommandText property to the name of the stored procedure.

4.
To the command object’s Parameters collection, add parameter objects for each parameter and for the return value.

5.
Set the input value for each parameter.

6.
Use the appropriate Execute method to cause the execution of the procedure at the server.

7.
Repeat steps 5 and 6 for each execution of the store procedure.

Step 4 is the most difficult of these steps. Once again, if your development environment can connect to a development SQL Server, Visual Studio .NET can generate the code for you, with some help from you in the form of a few drag-and-drop operations, as follows.

Once you have created a stored procedure on the development server, open a Windows Application project in Visual Studio .NET and navigate the Server Explorer window to your development SQL Server. Expand the server until you have reached the stored procedure; then drag and drop the stored procedure onto the form, as shown in Figure 5.

Figure 5. Adding a Stored Procedure Command to a Project

The resulting command object is added below the form, where you can select it and view its properties. When viewing the properties, you may note that the command object has a Parameters collection that displays itself graphically as shown in Figure 6.

Figure 6. Graphic Representation of a Parameters Collection


Getting back to our example, we do not want the graphical representation of the command; instead, we want the underlying code. So, we set a few final properties for the command object in the Properties window, such as the name (in this case cmndDB) and the connection, and then switch to Code View and expand the Windows Form Designer generated code region. As we proceed through the code, we come upon the generated code for our command, shown in Listing 3.

Listing 3. Designer-Generated Code to Create a Command Object
SqlCommand cmndDB = new SqlCommand();
        :
        :
//
// cmndDB
//
this.cmndDB.CommandText = "ModifyProductInfo";
this.cmndDB.CommandType = CommandType.StoredProcedure;
this.cmndDB.Connection = this.connNorthwind;
this.cmndDB.Parameters.Add(
   new SqlClient.SqlParameter(
      "@RETURN_VALUE", SqlDbType.Int, 4,
      ParameterDirection.ReturnValue, false,
      ((System.Byte)(0)), ((System.Byte)(0)),
      "", DataRowVersion.Current, null));
this.cmndDB.Parameters.Add(
   new SqlClient.SqlParameter(
      "@ProductID", SqlDbType.Int, 4));
this.cmndDB.Parameters.Add(
   new SqlClient.SqlParameter(
      "@ProductName", SqlDbType.NVarChar, 40));
this.cmndDB.Parameters.Add(
   new SqlClient.SqlParameter(
"@UnitPrice", SqlDbType.Money, 4));

					  

This is exactly what we want and exactly what we did not want to write. So, we cut and paste this code to move it from the Windows Application project into our Smart Device Application project, pasting it into the UpdateSelectedRow routine. We remove some of the code that was in the previous version of our application, change all occurrences of SqlCe to Sql, and add code to move values from the controls into the parameters and to execute the command. Along the way we remove a few superfluous references to this and add some minimal error handling. Listing 4 shows the resulting code.

Listing 4. Stored Procedure Version of the UpdateSelectedRow Routine
private void UpdateSelectedRow(int intProductID,
                               string strProductName)
{
   //  A connection and a command
   SqlConnection connDB = new SqlConnection(strConn);
   SqlCommand cmndDB = new SqlCommand();

   try
   {
      //  Open the connection.
      connDB.Open();

      //  Initialize the command (including
      //    creating the parameters).
      cmndDB.CommandText = "procModifyProductInfo";
      cmndDB.CommandType = CommandType.StoredProcedure;
      cmndDB.Connection = connDB;
      cmndDB.Parameters.Add(
         new SqlParameter(
         "@RETURN_VALUE", SqlDbType.Int, 4,
         ParameterDirection.ReturnValue, false,
         ((System.Byte)(0)), ((System.Byte)(0)),
         "", DataRowVersion.Current, null));
      cmndDB.Parameters.Add(
         new SqlParameter(
         "@ProductID", SqlDbType.Int, 4));
      cmndDB.Parameters.Add(
         new SqlParameter(
         "@ProductName", SqlDbType.NVarChar, 40));
      cmndDB.Parameters.Add(
         new SqlParameter(
         "@UnitPrice", SqlDbType.Money, 4));

      //  Assign values to the parameters.
      cmndDB.Parameters["@ProductID"].Value =
         int.Parse(comboKeys.SelectedItem.ToString());
      cmndDB.Parameters["@ProductName"].Value =
         textProductName.Text;
      cmndDB.Parameters["@UnitPrice"].Value = 123.45;

      //  Execute the stored procedure.
      cmndDB.ExecuteNonQuery();

      //  Check the SQL Server return value.
      if((int)cmndDB.Parameters["@RETURN_VALUE"].Value != 0)
      {
         MessageBox.Show(
            "You should have already caught a SqlException."
            );
      }
   }

   catch( SqlException exSQL )
   {
      foreach( SqlError errSQL in exSQL.Errors )
      {
         MessageBox.Show(errSQL.Message);
      }
   }

   finally
   {
      //  Close the connection.
      connDB.Close();
   }
}

					  

We placed all the code in one routine to make it more readable. In reality, we would move any code that needed to be executed only once, such as initializing the command and creating the parameters, into a separate routine. What would remain is the code that had to be executed every time, such as assigning values to the parameters, executing the procedure, and examining the return value.

Other  
  •  SQL Server 2008 R2 : Database Maintenance - Executing a Maintenance Plan
  •  SQL Server 2008 R2 : Database Maintenance - Managing Maintenance Plans Without the Wizard
  •  SQL Server 2008 R2 : The Maintenance Plan Wizard (part 2)
  •  SQL Server 2008 R2 : The Maintenance Plan Wizard (part 1)
  •  SQL Server 2008 : Common performance problems (part 2)
  •  SQL Server 2008 : Common performance problems (part 1) - Procedure cache bloating
  •  SQL Server 2008 : SQLOS schedulers, Wait analysis
  •  MySQL for Python : Creating Users and Granting Access - Removing privileges in MySQL, Using REVOKE in Python
  •  MySQL for Python : Creating Users and Granting Access - GRANT access in MySQL
  •  MySQL for Python : Creating Users and Granting Access - Removing users in MySQL, DROPping users in Python, Granting access in Python
  •  
    Video
    Top 10
    SG50 Ferrari F12berlinetta : Prancing Horse for Lion City's 50th
    The latest Audi TT : New angles for TT
    Era of million-dollar luxury cars
    Game Review : Hearthstone - Blackrock Mountain
    Game Review : Battlefield Hardline
    Google Chromecast
    Keyboards for Apple iPad Air 2 (part 3) - Logitech Ultrathin Keyboard Cover for iPad Air 2
    Keyboards for Apple iPad Air 2 (part 2) - Zagg Slim Book for iPad Air 2
    Keyboards for Apple iPad Air 2 (part 1) - Belkin Qode Ultimate Pro Keyboard Case for iPad Air 2
    Michael Kors Designs Stylish Tech Products for Women
    REVIEW
    - First look: Apple Watch

    - 3 Tips for Maintaining Your Cell Phone Battery (part 1)

    - 3 Tips for Maintaining Your Cell Phone Battery (part 2)
    Popular Tags
    Video Tutorail Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Exchange Server Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe Photoshop CorelDRAW X5 CorelDraw 10 windows Phone 7 windows Phone 8 Iphone