Stored procedure are precompiled collections of SQL statements that can be called. The usual way for applications to interface with SQL Server is to either send SQL statements to SQL Server or to call stored procedures on SQL Server. Here are some basic benefits of stored procedures:
Stored procedures are available to MySQL 5.0+.
Here is the syntax to CREATE PROCEDURE.
CREATE PROC[EDURE] ProcedureName [ ;GroupNumber]
[{@parameter DataType} [VARYING] [= Default] [OUTPUT]][ ,...]
[WITH {RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION}]
[FOR REPLICATION]
AS SQLStatement
A stored procedure can be created for three contexts:
#Name.##Name.Here is some info regarding CREATE PROCEDURE:
;GroupNumber signifies a procedure in a collection of procedures with the same name. This is so DROP PROCEDURE can drop the whole group.@@NESTLEVEL global variable.This example outputs an output parameter, result set, and a return code.
USE Northwind
GO
IF EXISTS(SELECT name FROM sysobjects
WHERE name='OrderSummary' AND type='P')
DROP PROCEDURE OrderSummary
GO
CREATE PROCEDURE OrderSummary @MaxQuantity int OUTPUT
AS
--This SELECT makes a result set.
SELECT Ord.EmployeeID, SUMSales=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 @MaxQuantity = MAX(Quantity) FROM [Order Details] --The output parameter.
RETURN (SELECT SUM(Quantity) FROM [Order Details]) --The return code.
GO
See the results at EG EXECUTE.
This example takes an input and outputs a variable whose data type is cursor.
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name='titles_cursor' and type='P')
DROP PROCEDURE titles_cursor
GO
CREATE PROCEDURE titles_cursor
@SomeTitle as varchar(80) = 'The%',
@titles_cursor CURSOR VARYING OUTPUT
AS
SET @titles_cursor=CURSOR
FORWARD_ONLY STATIC FOR
SELECT title
FROM titles
WHERE title LIKE @SomeTitle
OPEN @titles_cursor
GO
See the results at EG EXEC with cursor.
Use default values to create stored procedures with default, optional, or invalid parameters. If a stored procedure provides no default value, and the procedure is called without providing all values, than a system error occurs.
CREATE PROCEDURE insMe @first int, --Required @second int = 2, --Default, ie optional @third int = 3 --Default, ie optional IF @first = 99 --Invalid value BEGIN PRINT 'ERROR: first cannot be 99' RETURN END INSERT INTO event (EventTypeID_FK, Name, UserID_FK, DateFired) VALUES (@EventTypeID_FK, @Name, @Category, @SubCategory, GETDATE()) --Note that 4th entry (DateFired) is not paramaterized.
See the results at EGEXECwithdefaultvalues.
Here is the syntax to EXECUTE a procedure:
[[EXEC[UTE]]
{[@return_status = ]
{procedure_name [;GroupNumber] | @procedure_name_var}
}
[[@parameter = ] {value | @variable [OUTPUT] | [DEFAULT]] [ ,...n ]
[WITH RECOMPILE]
Note that for output parameters, the assignment operator (=) actually passes values from left to right instead of the usual right to left.
Here is the syntax to EXECUTE a character string:
EXEC[UTE] ({@string_variable | [N]'tsql_string'} [+ ...])
A stored procedure is optimized under these conditions:
sp_recompile marks all stored procedures that use a particular table so that they will optimize upon their execution.Here are some notes regarding executing and using stored procedures:
@Parameter = Value syntax is used.ParameterA is used if @ParameterA = value is not listed or @ParameterA = DEFAULT is listed.This example assumes that EG CREATE PROCEDURE was run. This demonstrates receipt of an output parameter, result set, and a return code.
DECLARE @OrderSum INT --Receives the return code. DECLARE @LargestOrder INT --Receives the output parameter. EXEC @OrderSum = OrderSummary, @MaxQuantity = @LargestOrder OUTPUT --The result set outputed and is usually accepted by the DB API. PRINT 'The largest single order was: ' + CONVERT(CHAR(6), @LargestOrder) PRINT 'The sum of quantities ordered was: ' + CONVERT(CHAR(6), @OrderSum) GO
Here are the results:
EmployeeID SUMSales ----------- --------------------- 1 202143.7100 2 177749.2600 3 213051.3000 4 250187.4500 5 75567.7500 6 78198.1000 7 141295.9900 8 133301.0300 9 82964.0000 (9 row(s) affected) The largest single order was: 130 The sum of quantities ordered was: 51317
This example assumes that EG CREATE with cursor was run. This demonstrates the receipt of a cursor.
DECLARE @MyCursor cursor
DECLARE @TheTitle varchar(80)
EXEC titles_cursor
@SomeTitle = '%Cooking%',
@titles_cursor = @MyCursor OUTPUT
FETCH NEXT FROM @MyCursor
INTO @TheTitle
PRINT 'Title: ' + @TheTitle
WHILE (@@FETCH_STATUS = 0)
BEGIN
FETCH NEXT FROM @MyCursor
INTO @TheTitle
PRINT 'Title: ' + @TheTitle
END
CLOSE @MyCursor
DEALLOCATE @MyCursor
GO
Here are the results:
Title: Cooking with Computers: Surreptitious Balance Sheets Title: Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean Title: The Psychology of Computer Cooking Title: The Psychology of Computer Cooking
Of course, you can do all sorts of fancy coding to generate the string used by the EXEC statement.
EXEC ('SELECT title FROM titles')
--The line above is just like the line below.
SELECT title FROM titles
Here are the results:
title ---------------------------------------------------------------- But Is It User Friendly? Computer Phobic AND Non-Phobic Individuals: Behavior Variations Cooking with Computers: Surreptitious Balance Sheets Emotional Security: A New Algorithm Fifty Years in Buckingham Palace Kitchens Is Anger the Enemy? (6 row(s) affected)
This example assumes that EG CREATE with default values was used.
EXEC insMe
--Fails since 1st parameter was required
EXEC insMe 12, 61, 45
--All parameters provided
EXEC insMe 6, @third = 77
--1st and 3rd parameter provided
You will often have to SET NOCOUNT ON because some of the intermediate steps return silly lines like "13 rows affected" and a consumer of the stored procedure might not continue with the rest of the stored procedure.
CREATE PROCEDURE sp_updAppointment
@AppointmentID int,
@Completed varchar(3) = 'xxx',
@Note varchar(500)
AS
SET NOCOUNT ON
IF @Completed='xxx' --This 'breaks' cuz of the True or False returned.
BEGIN
UPDATE Appointment
SET Note=@Note
WHERE AppointmentID=@AppointmentID
END
ELSE
BEGIN
UPDATE Appointment
SET
Completed=@Completed,
Note=@Note
WHERE AppointmentID=@AppointmentID
END
SET NOCOUNT OFF
GO
Page Modified: (Hand noted: 2007-10-12 22:05:44Z) (Auto noted: 2007-11-17 06:44:27Z)