ExecuteNonQuery
ExecuteNonQuery runs SQL that changes data and tells you how many rows were affected — perfect for checking whether an update actually happened.
On this page · 5 min · Beginner
On this page
- In simple words
- Learning objectives
- Explanation
- 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
- Beginner
- Updated
- Oct 29, 2026
In simple words#
You give an instruction (“update these fees”) and only want to know “how many rows did you change?” — that is ExecuteNonQuery.
- ExecuteNonQuery
- Runs INSERT/UPDATE/DELETE.
- Return value
- Rows affected.
- 0 rows
- Usually means “not found”.
Learning objectives#
- Insert, update and delete with ExecuteNonQuery
- Use the rows-affected result
- Get a new identity value
- Understand when -1 is returned
Explanation#
For INSERT, UPDATE and DELETE, ExecuteNonQuery returns the number of rows affected. 0 often means “not found”.
For other statements (CREATE TABLE, or when SET NOCOUNT ON is in effect for the whole batch), it returns -1.
To get the new Id of an inserted row, use OUTPUT INSERTED.Id with ExecuteScalar, or SCOPE_IDENTITY().
Code example: Create, update and delete a product#
await using var conn = new SqlConnection(cs);
await conn.OpenAsync();
// INSERT and get the new Id
await using var insert = new SqlCommand(
"INSERT INTO Products (Name, Price, Stock) OUTPUT INSERTED.Id VALUES (@name, @price, @stock)", conn);
insert.Parameters.Add("@name", SqlDbType.NVarChar, 100).Value = "Webcam";
insert.Parameters.Add("@price", SqlDbType.Decimal).Value = 3200m;
insert.Parameters.Add("@stock", SqlDbType.Int).Value = 15;
int newId = (int)(await insert.ExecuteScalarAsync())!;
// UPDATE → check rows affected
await using var update = new SqlCommand("UPDATE Products SET Stock = Stock - 1 WHERE Id = @id AND Stock > 0", conn);
update.Parameters.Add("@id", SqlDbType.Int).Value = newId;
int updated = await update.ExecuteNonQueryAsync();
// DELETE
await using var delete = new SqlCommand("DELETE FROM Products WHERE Id = @id", conn);
delete.Parameters.Add("@id", SqlDbType.Int).Value = 999;
int deleted = await delete.ExecuteNonQueryAsync();
Console.WriteLine(quot;New Id: {newId}, updated: {updated}, deleted: {deleted}");
New Id: 4, updated: 1, deleted: 0
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#
- OUTPUT INSERTED.Id returns the generated identity, so ExecuteScalar is used for the insert.
- The UPDATE only succeeds when stock is available; 1 row affected confirms it.
- Deleting Id 999 affects 0 rows — the product does not exist, so the API can return 404.
Real-world use case#
An order API decrements stock with “WHERE Stock > 0”. If ExecuteNonQuery returns 0, the item is out of stock and the order is rejected — no race condition.
Common mistakes#
An UPDATE that matched 0 rows silently “succeeds”. Check the count.
Another user may insert at the same time. Use OUTPUT INSERTED.Id or SCOPE_IDENTITY().
Best practices#
- Check rows affected for updates and deletes
- Use OUTPUT INSERTED for new keys
- Put conditions in the WHERE clause to avoid race conditions
- Use transactions for multi-statement changes
Remember this#
ExecuteNonQuery → rows affected.
0 rows = not found (or condition failed).
New Id: OUTPUT INSERTED.Id + ExecuteScalar.
Practice exercise#
Your task: Write an UPDATE that changes a product’s price and returns false when the product does not exist.
Show solution
static async Task<bool> UpdatePriceAsync(SqlConnection conn, int id, decimal price)
{
await using var cmd = new SqlCommand("UPDATE Products SET Price = @price WHERE Id = @id", conn);
cmd.Parameters.Add("@price", SqlDbType.Decimal).Value = price;
cmd.Parameters.Add("@id", SqlDbType.Int).Value = id;
return await cmd.ExecuteNonQueryAsync() == 1;
}
Mini quiz#
What does ExecuteNonQuery return for a CREATE TABLE statement?
Want more? Practise all ADO.NET MCQs · ADO.NET interview questions
My notes#
Saved in this browser.