ADO.NET · Executing Commands

ExecuteNonQuery

ExecuteNonQuery runs SQL that changes data and tells you how many rows were affected — perfect for checking whether an update actually happened.

Beginner 5 min Lesson 8 of 32Examples use Microsoft.Data.SqlClient on .NET 9 with SQL Server 2022.
0/32 in ADO.NET
On this page · 5 min · Beginner

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#

C#ProductWrites.cs Illustrative
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}");
Expected output
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#

  1. OUTPUT INSERTED.Id returns the generated identity, so ExecuteScalar is used for the insert.
  2. The UPDATE only succeeds when stock is available; 1 row affected confirms it.
  3. 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#

Ignoring the return value

An UPDATE that matched 0 rows silently “succeeds”. Check the count.

SELECT MAX(Id) after insert

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
C# Illustrative
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#

ExecuteNonQuery quizMultiple choice Question 1 of 2

What does ExecuteNonQuery return for a CREATE TABLE statement?

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.