Thursday, April 22, 2010

SQL Stored Procedures

SQL Server 2000 also supports temporary stored procedures that, like temporary tables, are dropped automatically when you disconnect. Temporary stored procedures are stored in tempdb and are useful when connected to earlier versions of SQL Server. Temporary stored procedures can be used when an application builds dynamic Transact-SQL statements that are executed several times. Rather than have the Transact-SQL statements recompiled each time, you can create a temporary stored procedure that is compiled on the first execution, and then execute the precompiled plan multiple times. Heavy use of temporary stored procedures, however, can lead to contention on the system tables in tempdb.

Two features of SQL Server 2000 and SQL Server 7.0 eliminate the need for using temporary stored procedures:

  • Execution plans from prior SQL statements can be reused. This is especially powerful when coupled with the use of the new sp_executesql system stored procedure.

  • Natively support for the prepare/execute model of OLE DB and ODBC without using any stored procedures.

For more information about alternatives to using temporary stored procedures, see Execution Plan Caching and Reuse.

Stored Procedure Example

This simple stored procedure example illustrates three ways stored procedures can return data:

  1. It first issues a SELECT statement that returns a result set summarizing the order activity for the stores in the sales table.

  2. It then issues a SELECT statement that fills an output parameter.

  3. Finally, it has a RETURN statement with a SELECT statement that returns an integer. Return codes are generally used to pass back error checking information. This procedure runs without errors, so it returns another value to illustrate how returned codes are filled.
USE Northwind GO DROP PROCEDURE OrderSummary GO CREATE PROCEDURE OrderSummary @MaxQuantity INT OUTPUT AS -- SELECT to return a result set summarizing -- employee sales. SELECT Ord.EmployeeID, SummSales = SUM(OrDet.UnitPrice * OrDet.Quantity) FROM Orders AS Ord      JOIN [Order Details] AS OrDet ON (Ord.OrderID = OrDet.OrderID) GROUP BY Ord.EmployeeID ORDER BY Ord.EmployeeID  -- SELECT to fill the output parameter with the -- maximum quantity from Order Details. SELECT @MaxQuantity = MAX(Quantity) FROM [Order Details]  -- Return the number of all items ordered. RETURN (SELECT SUM(Quantity) FROM [Order Details]) GO  -- Test the stored procedure.  -- DECLARE variables to hold the return code -- and output parameter. DECLARE @OrderSum INT DECLARE @LargestOrder INT  -- Execute the procedure, which returns -- the result set from the first SELECT. EXEC @OrderSum = OrderSummary @MaxQuantity = @LargestOrder OUTPUT  -- Use the return code and output parameter. PRINT 'The size of the largest single order was: ' +                  CONVERT(CHAR(6), @LargestOrder) PRINT 'The sum of the quantities ordered was: ' +                  CONVERT(CHAR(6), @OrderSum) GO 

The output from running this sample is:

EmployeeID  SummSales                   ----------- --------------------------  1           202,143.71                  2           177,749.26                  3           213,051.30                  4           250,187.45                  5           75,567.75                   6           78,198.10                   7           141,295.99                  8           133,301.03                  9           82,964.00                   The size of the largest single order was: 130  The sum of the quantities ordered was: 51317