SqlHelper 使用手册
目录一、核心方法概览二、ExecuteNonQuery - 增删改操作常用示例重载形式三、事务支持四、ExecuteDataset - 查询数据集五、ExecuteReader - 流式读取六、ExecuteScalar - 获取单值七、SqlHelperParameterCache - 参数缓存八、参数传递方式对比九、快速参考常用代码片段十、注意事项一、核心方法概览方法返回值用途适用场景ExecuteNonQueryint执行增删改返回受影响行数INSERT/UPDATE/DELETEExecuteDatasetDataSet执行查询返回数据集需要离线操作、多表结果ExecuteReaderSqlDataReader执行查询返回流式读取器大数据量、只进读取ExecuteScalarobject执行查询返回首行首列值聚合函数、获取单一值选择指南增删改 →ExecuteNonQuery查询多条数据且需离线操作 →ExecuteDataset查询大数据量且只需遍历一次 →ExecuteReader查询单个值如 COUNT →ExecuteScalar二、ExecuteNonQuery - 增删改操作功能执行 INSERT、UPDATE、DELETE 语句或存储过程返回受影响的行数。⚠️安全警告必须使用参数化查询禁止字符串拼接 SQL防止 SQL 注入攻击。// ❌ 错误字符串拼接存在 SQL 注入风险 string sql DELETE FROM Users WHERE Name userName ; // ✅ 正确使用参数化查询 int rows SqlHelper.ExecuteNonQuery( connString, CommandType.Text, DELETE FROM Users WHERE Status status, new SqlParameter(status, 0) );常用示例// 1. 执行 SQL 语句带参数 int rows SqlHelper.ExecuteNonQuery( connString, CommandType.Text, UPDATE Users SET Name name WHERE Id id, new SqlParameter(name, 张三), new SqlParameter(id, 1) ); // 2. 执行存储过程参数值方式 int rows SqlHelper.ExecuteNonQuery(connString, sp_UpdateUser, 1, 张三);重载形式重载参数说明ExecuteNonQuery(string, CommandType, string)连接字符串、命令类型、SQLExecuteNonQuery(string, CommandType, string, params SqlParameter[])以上 参数数组ExecuteNonQuery(string, string, params object[])连接字符串、存储过程名、参数值ExecuteNonQuery(SqlConnection, ...)使用已有连接对象ExecuteNonQuery(SqlTransaction, ...)在事务中执行三、事务支持功能确保一组数据库操作要么全部成功要么全部失败原子性。使用场景转账扣款入账、订单减库存创建订单等需要保证数据一致性的操作。using (SqlConnection conn new SqlConnection(connString)) { conn.Open(); using (SqlTransaction trans conn.BeginTransaction()) { try { // 扣减库存 SqlHelper.ExecuteNonQuery(trans, CommandType.Text, UPDATE Stock SET Count Count - num WHERE ProductId pid, new SqlParameter(num, 1), new SqlParameter(pid, 100)); // 创建订单 SqlHelper.ExecuteNonQuery(trans, CommandType.Text, INSERT INTO Orders (ProductId, Quantity) VALUES (pid, qty), new SqlParameter(pid, 100), new SqlParameter(qty, 1)); trans.Commit(); // 提交事务 } catch { trans.Rollback(); // 回滚事务 throw; } } // 事务自动释放 } // 连接自动关闭要点事务中的多个操作使用同一trans对象Commit()提交后不可回滚Rollback()后数据恢复到事务开始前状态四、ExecuteDataset - 查询数据集功能执行查询返回DataSet适合获取多张表或需要离线操作的数据。vs ExecuteReaderExecuteDatasetExecuteReader数据加载全部加载到内存逐行读取连接状态读取完立即关闭读取期间保持连接适用场景数据量小、需随机访问数据量大、只需遍历内存占用高低// 1. 查询单表 DataSet ds SqlHelper.ExecuteDataset( connString, CommandType.Text, SELECT * FROM Users WHERE Age age, new SqlParameter(age, 18) ); DataTable dt ds.Tables[0]; // 2. 执行存储过程 DataSet ds SqlHelper.ExecuteDataset(connString, sp_GetUserOrders, 123); // 3. 多结果集查询一次查询返回多个表 DataSet ds SqlHelper.ExecuteDataset( connString, CommandType.Text, SELECT * FROM Users; SELECT * FROM Orders ); // ds.Tables[0] Users // ds.Tables[1] Orders五、ExecuteReader - 流式读取功能返回SqlDataReader适合大数据量、只进读取的场景内存占用低。方法签名ExecuteReader(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)// 使用连接字符串自动关闭连接 using (SqlDataReader reader SqlHelper.ExecuteReader( connString, CommandType.Text, SELECT Id, Name FROM Users )) { while (reader.Read()) { int id reader.GetInt32(0); string name reader.GetString(1); } } // Reader 和连接自动关闭 // 使用外部连接连接生命周期由外部控制 SqlConnection conn new SqlConnection(connString); conn.Open(); SqlDataReader reader SqlHelper.ExecuteReader( conn, CommandType.Text, SELECT * FROM Users ); while (reader.Read()) { /* ... */ } reader.Close(); // 必须手动关闭 Reader conn.Close(); // 必须手动关闭连接⚠️注意使用连接字符串方式时Reader 关闭会自动关闭连接使用外部连接方式时连接和 Reader 都需要手动关闭。六、ExecuteScalar - 获取单值功能返回结果集第一行第一列的值常用于获取聚合结果或单个字段。// 获取记录数 object result SqlHelper.ExecuteScalar( connString, CommandType.Text, SELECT COUNT(*) FROM Users ); int count Convert.ToInt32(result); // 获取最大值/最新ID object maxId SqlHelper.ExecuteScalar( connString, CommandType.Text, SELECT MAX(Id) FROM Orders ); // 判断记录是否存在 object exists SqlHelper.ExecuteScalar( connString, CommandType.Text, SELECT 1 FROM Users WHERE Name name, new SqlParameter(name, admin) ); bool hasUser (exists ! null exists ! DBNull.Value);七、SqlHelperParameterCache - 参数缓存功能自动缓存存储过程参数信息避免重复查询数据库获取参数定义提升性能。工作原理首次调用存储过程时通过SqlCommandBuilder.DeriveParameters从数据库获取参数信息将参数信息存入Hashtable缓存键格式连接字符串:存储过程名后续调用直接从缓存获取避免重复查询系统表// 获取记录数 object result SqlHelper.ExecuteScalar( connString, CommandType.Text, SELECT COUNT(*) FROM Users ); int count Convert.ToInt32(result); // 获取最大值/最新ID object maxId SqlHelper.ExecuteScalar( connString, CommandType.Text, SELECT MAX(Id) FROM Orders ); // 判断记录是否存在 object exists SqlHelper.ExecuteScalar( connString, CommandType.Text, SELECT 1 FROM Users WHERE Name name, new SqlParameter(name, admin) ); bool hasUser (exists ! null exists ! DBNull.Value);提示使用SqlHelper.ExecuteXxx(connString, sp_Name, paramValues)形式时参数缓存自动生效。⚠️注意修改存储过程参数后需要重启应用或清除缓存才能生效。八、参数传递方式对比方式示例适用场景显式参数new SqlParameter(name, value)需要精确控制参数类型、方向参数值数组ExecuteXxx(connString, sp_Name, 1, abc)快速调用参数类型自动推断DataRowExecuteXxxTypedParams(connString, sp_Name, dataRow)数据来自 DataRow九、快速参考常用代码片段// 插入数据并获取自增ID SqlHelper.ExecuteNonQuery(connString, CommandType.Text, INSERT INTO Users (Name) VALUES (name), new SqlParameter(name, 张三)); int newId Convert.ToInt32(SqlHelper.ExecuteScalar(connString, CommandType.Text, SELECT SCOPE_IDENTITY())); // 批量查询 DataSet ds SqlHelper.ExecuteDataset(connString, CommandType.Text, SELECT * FROM Users; SELECT * FROM Products); // 检查记录是否存在 object result SqlHelper.ExecuteScalar(connString, CommandType.Text, SELECT 1 FROM Users WHERE Id id, new SqlParameter(id, 1)); bool exists (result ! null result ! DBNull.Value); // 使用存储过程输出参数 SqlParameter[] outputParams new SqlParameter[] { new SqlParameter(Input, value), new SqlParameter(Output, SqlDbType.Int) { Direction ParameterDirection.Output } }; SqlHelper.ExecuteNonQuery(connString, CommandType.StoredProcedure, sp_Test, outputParams); int outputValue (int)outputParams[1].Value;十、注意事项连接管理使用连接字符串方式会自动管理连接using确保释放使用连接对象方式需自行管理。空值处理参数值为null时自动转为DBNull.Value。参数缓存存储过程参数信息会自动缓存提升重复调用性能。异常处理所有方法遇错误会抛出异常常见异常包括ArgumentNullException连接字符串或命令文本为空SqlExceptionSQL 执行错误语法错误、约束冲突等InvalidOperationException连接状态异常 建议调用方使用try-catch处理并记录日志。文档基于 SqlHelper 标准实现整理适用于 .NET Framework SQL Server 环境。