Stored Procedures
sp_help, sp_helptext, sp_who2, sp_lock, sp_rename, sp_configure, sp_spaceused, sp_executesql, sp_depends (deprecated; use sys.dm_sql_referencing_entities), sp_describe_first_result_set, sp_recompile, sp_procoption (startup procs).
19.1 Creating and Executing
CREATE OR ALTER PROCEDURE Sales.usp_GetCustomerOrders
@CustomerID INT,
@FromDate DATE = NULL, -- optional parameter
@OrderCount INT OUTPUT -- output parameter
AS
BEGIN
SET NOCOUNT ON;
SELECT o.OrderID, o.OrderDate, o.Status
FROM dbo.Orders o
WHERE o.CustomerID = @CustomerID
AND (@FromDate IS NULL OR o.OrderDate >= @FromDate);
SET @OrderCount = @@ROWCOUNT;
RETURN 0; -- return code (INT only, status)
END
GO
DECLARE @cnt INT, @rc INT;
EXEC @rc = Sales.usp_GetCustomerOrders @CustomerID = 1, @OrderCount = @cnt OUTPUT;
SELECT @cnt AS Orders, @rc AS ReturnCode;19.2 Benefits
Plan reuse, reduced network traffic, security (permission on the procedure, not the tables), encapsulation, and protection from SQL injection when parameterized.
19.3 Procedure Options
WITH RECOMPILE: new plan every execution WITH ENCRYPTION
WITH EXECUTE AS OWNER | CALLER | SELF | 'user' WITH NATIVE_COMPILATION, SCHEMABINDING: In-Memory OLTP
OPTION (RECOMPILE) at statement level (usually better than procedure-level recompile)
19.4 Table-Valued Parameters (TVP)
CREATE TYPE dbo.OrderItemType AS TABLE (ProductID INT, Quantity INT, UnitPrice DECIMAL(10,2));
GO
CREATE OR ALTER PROCEDURE dbo.usp_CreateOrder
@CustomerID INT, @Items dbo.OrderItemType READONLY
AS
BEGIN
SET NOCOUNT, XACT_ABORT ON;
BEGIN TRAN;
DECLARE @OrderID INT;
INSERT dbo.Orders (CustomerID) VALUES (@CustomerID);
SET @OrderID = SCOPE_IDENTITY();
INSERT dbo.OrderItems (OrderID, ProductID, Quantity, UnitPrice)
SELECT @OrderID, ProductID, Quantity, UnitPrice FROM @Items;
COMMIT;
SELECT @OrderID AS NewOrderID;
END
GO
DECLARE @i dbo.OrderItemType;
INSERT @i VALUES (1, 2, 499.00), (3, 1, 1299.00);
EXEC dbo.usp_CreateOrder @CustomerID = 1, @Items = @i;19.5 Useful System Stored Procedures
sp_help, sp_helptext, sp_who2, sp_lock, sp_rename, sp_configure, sp_spaceused, sp_executesql, sp_depends (deprecated; use sys.dm_sql_referencing_entities), sp_describe_first_result_set, sp_recompile, sp_procoption (startup procs).
19.6 Procedure Best Practices
Prefix with a schema. Don't use the sp_ prefix (it searches master first).
Use SET NOCOUNT ON and SET XACT_ABORT ON.
Handle errors with TRY/CATCH.
Beware parameter sniffing (Module 35).
Avoid "catch-all" queries (@p IS NULL OR col = @p), or use OPTION (RECOMPILE) or dynamic SQL.