| Lesson 12 | Testing stored procedures |
| Objective | Describe how to test your stored procedure. |
The legacy version of this page mixed several unrelated topics (XML datatypes, SSMS object explorer descriptions, and a long INSERT...EXEC example) without clearly connecting them to the lesson objective. This rewrite focuses on a practical testing workflow for SQL Server 2022: run repeatable tests, validate outputs and side effects, verify error handling, and (when needed) capture stored procedure result sets into tables for assertions.
Always test stored procedures in a development or test database that mirrors production as closely as possible. You want to validate correctness and performance without risking live data or disrupting users.
When testing a stored procedure, you are validating three things: (1) the returned result set(s), (2) any output parameters or return codes, and (3) any side effects (inserts, updates, deletes, or transaction behavior).
TRY...CATCH and THROW).
SQL Server Management Studio (SSMS) is the most common place to test procedures interactively. A best practice is to write a repeatable test script that you can run multiple times without manual cleanup.
-- Example test harness
DECLARE @EmployeeStatus int;
EXEC dbo.usp_GetLastName
@EmployeeID = 101,
@EmployeeStatus = @EmployeeStatus OUTPUT;
SELECT @EmployeeStatus AS EmployeeStatus;
In this example, you validate that the procedure (1) returns the expected last name result set and (2) sets the
@EmployeeStatus output parameter correctly.
Sometimes you want to test a procedure by capturing its result set into a table so you can run assertions with standard
queries. In SQL Server, you can do this with INSERT...EXEC. This technique is useful when you want to compare
expected versus actual results, or when you need to store a test run for later review.
INSERT INTO schema.TableName (Col1, Col2, Col3)
EXEC schema.ProcedureName @Param1 = ..., @Param2 = ...;
Important rule: the table’s column list must match the stored procedure’s result set column order and datatypes.
If the procedure returns multiple result sets, INSERT...EXEC becomes difficult to use because the insert expects
a single result set shape.
The following self-contained example uses SQL Server 2022-friendly patterns (CREATE OR ALTER, schema-qualified
names) to:
(1) create a procedure that returns a predictable result set,
(2) capture the result set into a table, and
(3) verify the inserted rows.
-- 1) Create a procedure that returns a single, consistent result set
CREATE OR ALTER PROCEDURE dbo.ListAZAddresses
AS
BEGIN
SET NOCOUNT ON;
SELECT TOP (10)
a.AddressLine1,
a.City,
sp.StateProvinceCode,
CAST('Sunshine' AS varchar(20)) AS County,
a.PostalCode
FROM Person.Address AS a
INNER JOIN Person.StateProvince AS sp
ON a.StateProvinceID = sp.StateProvinceID
WHERE sp.Name = 'Arizona'
ORDER BY a.AddressID;
END;
-- 2) Create a staging table that matches the result set
IF OBJECT_ID('tempdb..#AZAddresses') IS NOT NULL
DROP TABLE #AZAddresses;
CREATE TABLE #AZAddresses
(
AddressLine1 nvarchar(60) NOT NULL,
City nvarchar(30) NOT NULL,
StateProvinceCode nchar(2) NOT NULL,
County varchar(20) NOT NULL,
PostalCode nvarchar(15) NOT NULL
);
-- 3) Insert the procedure output into the table
INSERT INTO #AZAddresses (AddressLine1, City, StateProvinceCode, County, PostalCode)
EXEC dbo.ListAZAddresses;
-- 4) Verify the inserted rows
SELECT *
FROM #AZAddresses;
This pattern gives you a repeatable way to test the shape and contents of a stored procedure result set without modifying production tables.
| AddressLine1 | City | StateProvinceCode | County | PostalCode | | ------------------------- | ----------- | ----------------- | -------- | ---------- | | 137 Lancelot Dr | Phoenix | AZ | Sunshine | 85004 | | 25250 N 90th St | Scottsdale | AZ | Sunshine | 85257 | | 253731 West Bell Road | Surprise | AZ | Sunshine | 85374 | | 2551 East Warner Road | Gilbert | AZ | Sunshine | 85233 | | 3294 Buena Vista | Lemon Grove | AZ | Sunshine | 85284 | | 4584 Hamilton Ave. | Chandler | AZ | Sunshine | 85225 | | 6441 Co Road | Lemon Grove | AZ | Sunshine | 85252 | | 6500 East Grant Road | Tucson | AZ | Sunshine | 85701 | | 7656 Ramsey Circle | Chandler | AZ | Sunshine | 85225 | | 7709 West Virginia Avenue | Phoenix | AZ | Sunshine | 85004 | | 7750 E Marching Rd | Scottsdale | AZ | Sunshine | 85257 | | 870 N. 54th Ave. | Chandler | AZ | Sunshine | 85225 | | 9228 Via Del Sol | Phoenix | AZ | Sunshine | 85004 | | 9980 S Alma School Road | Chandler | AZ | Sunshine | 85225 |
Once your procedure passes functional tests (correct results, correct output parameters, correct rollback behavior), re-run your test harness using multiple input values. Then, if performance matters, capture an execution plan and measure runtime in your test environment before deploying to production.
In the next lesson, we will review the information covered in this module.