必须用 sqlcommand.executenonquery() 执行更新操作,它返回受影响行数;须参数化防止 sql 注入,null 值传 dbnull.value;连接需显式打开并用 using 确保释放。

直接用 SqlCommand.ExecuteNonQuery() 就能执行 SQL 更新,但写错连接状态、漏关资源、参数没处理好,分分钟报错或数据不生效。
更新语句必须用 ExecuteNonQuery(),不是 ExecuteReader() 或 ExecuteScalar()
更新、插入、删除这类不返回结果集的操作,只能用 ExecuteNonQuery()。它返回受影响的行数(int),不是结果集也不是单个值。
-
ExecuteReader()会卡住,抛出InvalidOperationException: "The connection is closed."或类似提示——因为底层尝试读取不存在的结果集 -
ExecuteScalar()返回null或报错,它只适合SELECT TOP 1这类场景 - 哪怕 SQL 里写了
SELECT @@ROWCOUNT,也不能靠ExecuteScalar()混着用;要获取影响行数,直接看ExecuteNonQuery()的返回值就行
参数化是硬性要求,别拼接字符串
用字符串拼接 string.Format 或 $"" 构造 SQL,等于主动打开 SQL 注入大门,而且日期、单引号、空值都会出问题。
- 正确写法:SQL 中用
@name、@id占位,再用cmd.Parameters.AddWithValue("@name", value)绑定 - 特别注意
null值:不能传null给AddWithValue,得用DBNull.Value,例如cmd.Parameters.AddWithValue("@email", user.Email ?? (object)DBNull.Value) - 类型要对得上:比如数据库字段是
datetime2,就别传字符串;传DateTime.Now最稳
连接必须显式打开,且推荐用 using 管理生命周期
忘了 Open(),会直接报 "Connection must be open and available";忘了 Close() 或没用 using,连接可能堆积、超时、连不上新请求。
- 不要手动调
conn.Close()后再用conn.Open()——using块自动处理释放 - 连接字符串里的
Pooling=true(默认开启)依赖正确释放,否则连接池会慢慢耗尽 - 示例结构:
using (var conn = new SqlConnection(connStr)) { conn.Open(); using (var cmd = new SqlCommand("UPDATE Users SET Name = @name WHERE Id = @id", conn)) { cmd.Parameters.AddWithValue("@name", newName); cmd.Parameters.AddWithValue("@id", userId); int rows = cmd.ExecuteNonQuery(); // 返回 0 表示没匹配到记录 } }
最常被忽略的是:返回值 rows 为 0 不代表失败,只是没数据被改——业务上该提示“用户不存在”还是“无需更新”,得你自己判断。











