Stored Procedures
Many company databases expose their logic as stored procedures. ADO.NET calls them with just one extra line.
On this page · 5 min · Intermediate
On this page
- In simple words
- Learning objectives
- Explanation
- Syntax
- Code example
- Step by step
- Real-world use
- Common mistakes
- Best practices
- Remember this
- Practice exercise
- Mini quiz
- Related topics
- My notes
- Reading time
- 5 min
- Difficulty
- Intermediate
- Updated
- Oct 29, 2026
Related tutorials
In simple words#
Instead of reading out the whole recipe over the phone, you say “make dish #7” — call the stored procedure by name with its parameters.
- CommandType.StoredProcedure
- Call a procedure by name.
- Parameter names
- Must match the procedure’s.
- SET NOCOUNT ON
- Fewer messages; NonQuery returns -1.
Learning objectives#
- Create a simple stored procedure
- Call it with CommandType.StoredProcedure
- Read the rows it returns
- Understand SET NOCOUNT ON
Explanation#
Set CommandText to the procedure name and CommandType to CommandType.StoredProcedure. Parameter names must match the procedure’s parameters.
A procedure that ends with SELECT returns rows: use ExecuteReader. One that only changes data uses ExecuteNonQuery.
SET NOCOUNT ON stops “n rows affected” messages, reducing network chatter — but then ExecuteNonQuery returns -1, so use output parameters for counts.
Syntax#
CREATE OR ALTER PROCEDURE dbo.GetProductsByCategory
@CategoryId INT,
@MinStock INT = 0
AS
BEGIN
SET NOCOUNT ON;
SELECT Id, Name, Price, Stock
FROM Products
WHERE CategoryId = @CategoryId AND Stock >= @MinStock
ORDER BY Name;
END
Code example: Calling the procedure#
await using var conn = new SqlConnection(cs);
await conn.OpenAsync();
await using var cmd = new SqlCommand("dbo.GetProductsByCategory", conn)
{
CommandType = CommandType.StoredProcedure,
};
cmd.Parameters.Add("@CategoryId", SqlDbType.Int).Value = 1;
// @MinStock is optional — its default (0) is used when we don't add it
await using var r = await cmd.ExecuteReaderAsync();
while (await r.ReadAsync())
Console.WriteLine(quot;{r.GetString(1)}: ₹{r.GetDecimal(2)} ({r.GetInt32(3)} in stock)");
Keyboard: ₹2200.00 (40 in stock) Laptop: ₹55000.00 (8 in stock) Mouse: ₹1400.00 (120 in stock)
This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.
Step-by-step explanation#
- The procedure filters products by category and minimum stock.
- CommandType.StoredProcedure tells SqlClient to call it as a procedure (an RPC call).
- Only the required parameter is supplied; the optional one uses its default.
- The SELECT inside the procedure is read with a normal reader.
Real-world use case#
A bank’s database team owns the procedures and their permissions; application developers get EXECUTE rights only, never direct table access.
Common mistakes#
Works, but CommandType.StoredProcedure is clearer and avoids parsing.
You get “Procedure expects parameter '@CategoryId', which was not supplied”. Names must match.
Best practices#
- Use CommandType.StoredProcedure
- Schema-qualify names (dbo.)
- Use SET NOCOUNT ON in procedures
- Grant EXECUTE instead of table permissions
Remember this#
Name in CommandText + CommandType.StoredProcedure.
Parameter names must match.
NOCOUNT ON → ExecuteNonQuery returns -1.
Practice exercise#
Your task: Call dbo.GetProductsByCategory for category 2 with @MinStock = 10.
Show solution
cmd.Parameters.Add("@CategoryId", SqlDbType.Int).Value = 2;
cmd.Parameters.Add("@MinStock", SqlDbType.Int).Value = 10;
Mini quiz#
Which property must be set to call a procedure by name?
Want more? Practise all ADO.NET MCQs · ADO.NET interview questions
My notes#
Saved in this browser.