C# ADO.NET执行SQL方法 C#如何使用ADO.NET

2次阅读

sqlconnection打开前须校验连接字符串有效性,executenonquery()返回受影响行数而非布尔值,datareader必须用using确保关闭,参数化查询需避免addwithvalue隐式类型推断风险。

C# ADO.NET执行SQL方法 C#如何使用ADO.NET

SqlConnection 打开前必须检查连接字符串是否有效

很多运行时异常其实源于 connectionString 格式错误或权限不足,但 new SqlConnection(...) 不会报错,直到调用 Open() 才抛出 SqlException。建议在打开前做最小验证:

  • SqlConnectionStringBuilder 构建并校验关键字段(DataSourceInitialCatalogUserID/integratedSecurity
  • 避免硬编码连接字符串;若从配置读取,先确认 ConfigurationManager.ConnectionStrings["xxx"] 不为 NULL
  • 开发阶段可加一层 try-catch 捕获 SqlException 并输出 number(如 18456 表示登录失败,4060 表示数据库不存在)

SqlCommand.ExecuteNonQuery() 适合 INSERT/UPDATE/delete,但要注意返回值含义

ExecuteNonQuery() 返回的是“受影响的行数”,不是成功与否的布尔值。它对 INSERTUPDATEDELETE 有效,但对 CREATE tableSET NOCOUNT ON 后的语句可能返回 -1。

  • 执行单条 INSERT 后返回 1,批量插入返回实际插入行数
  • 如果 SQL 中含多个语句(如 UPDATE; select @@ROWCOUNT;),默认只取第一个语句影响行数
  • 使用 SET NOCOUNT OFF(SQL Server 默认)才能确保返回正确计数;生产环境若开启 NOCOUNT,需显式关闭或改用 ExecuteScalar() 获取 @@ROWCOUNT
using (var cmd = new SqlCommand("UPDATE Users SET Name = @name WHERE Id = @id", conn)) {     cmd.Parameters.AddWithValue("@name", "Alice");     cmd.Parameters.AddWithValue("@id", 123);     int rows = cmd.ExecuteNonQuery(); // rows == 1 表示更新成功,0 表示没匹配到记录 }

DataReader 未关闭会导致连接无法释放,必须用 using 或 try-finally

SqlDataReader 是前向只读流,底层绑定着活动的 SqlConnection。只要它没关闭,连接就一直被占用,极易引发“超时”或“连接池已满”错误。

  • 永远不要写 reader.Read() 后直接 return,必须保证 reader.Close()Dispose()
  • 推荐用 using 块包裹:它会在作用域结束时自动调用 Dispose(),即使发生异常
  • 注意:不能在 using (var reader = cmd.ExecuteReader()) 外部访问 reader,也不能把它 return 出去——它生命周期只限于该块内
using (var cmd = new SqlCommand("SELECT Name FROM Users WHERE Active = 1", conn)) {     using (var reader = cmd.ExecuteReader()) // 自动关闭 reader 和关联连接(如果 connection 也在此 using 中)     {         while (reader.Read())         {             Console.WriteLine(reader.GetString(0));         }     } // reader.Dispose() 在这里隐式调用 }

参数化查询防注入是必须的,但 AddWithValue 有隐式类型推断风险

AddWithValue 看似方便,但 SQL Server 可能将 null 推断为 int 而非 varchar,导致索引失效或隐式转换。尤其在 WHERE 条件中传 null 时,执行计划可能变差。

  • 明确指定类型:用 Parameters.Add("@name", SqlDbType.NVarChar).Value = "Alice"
  • 对可能为 null 的值,显式赋 DBNull.Value,而非 null
  • 避免在 LIKE 参数中直接拼接 %:应写成 cmd.Parameters.Add("@term", SqlDbType.NVarChar).Value = "%" + userInput + "%",而不是在 SQL 字符串里拼

真正容易被忽略的是:即使用了参数化,如果业务逻辑仍把用户输入拼进 SQL 字符串(比如动态表名、列名、排序字段),照样存在注入风险——这些无法参数化,必须白名单校验。

text=ZqhQzanResources