ADO.NET · Executing Commands

SqlCommand

SqlCommand is the object that carries your SQL to the server. Picking the right Execute method makes code simpler and faster.

Beginner 5 min Lesson 7 of 32Examples use Microsoft.Data.SqlClient on .NET 9 with SQL Server 2022.
Before you start:SqlConnection
0/32 in ADO.NET
On this page · 5 min · Beginner

In simple words#

SqlCommand is the message you speak over the line: the SQL text plus the values (parameters) to use.

CommandText
The SQL or procedure name.
Parameters
Safe values for the SQL.
Execute methods
NonQuery, Scalar, Reader.

Learning objectives#

  • Create commands with SQL text or procedure names
  • Choose the right Execute method
  • Set CommandTimeout
  • Reuse a command with different parameter values

Explanation#

CommandText holds the SQL (or a stored procedure name); Connection is where it runs; CommandType is Text (default) or StoredProcedure.

ExecuteNonQuery for INSERT, UPDATE, DELETE and DDL. ExecuteScalar for a single value. ExecuteReader for rows. Each has an Async version.

CommandTimeout (default 30 seconds) limits how long a command waits for SQL Server; 0 means wait forever and should be avoided.

Commands can be reused: change parameter values and execute again — useful in loops.

Code example: The three Execute methods#

C#Commands.cs Illustrative
await using var conn = new SqlConnection(cs);
await conn.OpenAsync();


// 1. ExecuteNonQuery → rows affected
await using var update = new SqlCommand("UPDATE Products SET Price = Price * 1.05 WHERE CategoryId = @cat", conn);
update.Parameters.Add("@cat", SqlDbType.Int).Value = 1;
int changed = await update.ExecuteNonQueryAsync();


// 2. ExecuteScalar → one value
await using var count = new SqlCommand("SELECT COUNT(*) FROM Products", conn);
int total = (int)(await count.ExecuteScalarAsync())!;


// 3. ExecuteReader → rows
await using var list = new SqlCommand("SELECT TOP (2) Name FROM Products ORDER BY Price DESC", conn) { CommandTimeout = 10 };
await using var r = await list.ExecuteReaderAsync();
while (await r.ReadAsync()) Console.WriteLine(r.GetString(0));


Console.WriteLine(
quot;
{changed} prices updated, {total} products in total");
Expected output
Laptop
Keyboard
2 prices updated, 3 products in total

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#

  1. The UPDATE returns how many rows it changed.
  2. COUNT(*) returns an int boxed as object, so it is cast.
  3. The reader streams the two most expensive product names; CommandTimeout is set to 10 seconds.

Real-world use case#

A price-update tool runs one UPDATE per category in a loop, reusing a single command and changing only the @cat value.

Common mistakes#

Using ExecuteReader for a single value

ExecuteScalar is simpler and avoids reader handling.

Setting CommandTimeout = 0

A stuck query then hangs forever. Choose a realistic limit.

Best practices#

  • Match the Execute method to the result
  • Use async methods in web apps
  • Always use parameters for values
  • Set timeouts deliberately for long reports

Remember this#

NonQuery = changes. Scalar = one value. Reader = rows.

Default CommandTimeout = 30 s.

Reuse a command by changing parameter values.

Practice exercise#

Your task: Use one command in a loop to set Stock = 0 for product Ids 4, 5 and 6.

Show solution
C# Illustrative
await using var cmd = new SqlCommand("UPDATE Products SET Stock = 0 WHERE Id = @id", conn);
var id = cmd.Parameters.Add("@id", SqlDbType.Int);
foreach (var value in new[] { 4, 5, 6 })
{
    id.Value = value;
    await cmd.ExecuteNonQueryAsync();
}

Mini quiz#

SqlCommand quizMultiple choice Question 1 of 1

What is the default CommandTimeout?

Score so far: 0/0

Want more? Practise all ADO.NET MCQs · ADO.NET interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.