上一篇
如何在C中正确编写数据库插入语句?
- 行业动态
- 2025-05-13
- 7
在C#中使用ADO.NET的SqlConnection和SqlCommand对象执行数据库插入操作,需编写参数化SQL语句(如INSERT INTO)防止注入攻击,通过Parameters添加值后调用ExecuteNonQuery方法提交到数据库。
基础方法:使用ADO.NET的SqlCommand
通过SqlCommand
直接操作数据库是C#最传统的交互方式,适合需要精细控制SQL的场景。
using System.Data.SqlClient; // 示例代码 string connectionString = "Server=myServer;Database=myDB;User Id=myUser;Password=myPass;"; string insertQuery = "INSERT INTO Users (Name, Email, CreatedAt) VALUES (@Name, @Email, @CreatedAt)"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); using (SqlCommand command = new SqlCommand(insertQuery, connection)) { command.Parameters.AddWithValue("@Name", "John Doe"); command.Parameters.AddWithValue("@Email", "john@example.com"); command.Parameters.AddWithValue("@CreatedAt", DateTime.Now); int rowsAffected = command.ExecuteNonQuery(); Console.WriteLine($"插入了 {rowsAffected} 行数据"); } }
关键点:
- 使用
using
语句管理连接和命令对象,确保资源释放。 - 参数化查询(
@Name
等占位符)避免SQL注入攻击。 ExecuteNonQuery()
返回受影响的行数,用于验证操作结果。
进阶实践:封装通用插入方法
为提升代码复用性,可封装一个通用插入函数:
public static int InsertData(string tableName, Dictionary<string, object> columns) { string connectionString = "YourConnectionString"; var columnNames = string.Join(", ", columns.Keys); var parameterNames = string.Join(", ", columns.Keys.Select(k => "@" + k)); string query = $"INSERT INTO {tableName} ({columnNames}) VALUES ({parameterNames})"; using (SqlConnection conn = new SqlConnection(connectionString)) { conn.Open(); using (SqlCommand cmd = new SqlCommand(query, conn)) { foreach (var pair in columns) { cmd.Parameters.AddWithValue("@" + pair.Key, pair.Value); } return cmd.ExecuteNonQuery(); } } } // 调用示例 var data = new Dictionary<string, object> { { "Name", "Alice" }, { "Age", 30 }, { "RegistrationDate", DateTime.Now } }; int result = InsertData("Customers", data);
优势:
- 动态生成SQL语句,适应不同表结构。
- 减少重复代码量,提升开发效率。
现代方案:使用Entity Framework Core
对于大型项目,推荐通过ORM框架(如EF Core)操作数据库,降低SQL耦合度。
定义数据模型
public class User { public int Id { get; set; } public string Name { get; set; } public string Email { get; set; } public DateTime CreatedAt { get; set; } }
插入数据
using (var context = new MyDbContext()) { var newUser = new User { Name = "Emma", Email = "emma@example.com", CreatedAt = DateTime.Now }; context.Users.Add(newUser); int changes = context.SaveChanges(); Console.WriteLine($"已保存 {changes} 条变更"); }
EF Core特性:
- 自动生成SQL语句,无需手动编写。
- 支持事务管理、并发控制等高级功能。
- 提供LINQ语法,增强代码可读性。
安全与性能优化
防御SQL注入
- 禁止使用字符串拼接:
// 高风险示例(绝对避免!) string unsafeQuery = $"INSERT INTO Users (Name) VALUES ('{userInput}')";
- 必须使用参数化查询或ORM框架。
批量插入优化
当需插入大量数据时,原生ADO.NET的SqlBulkCopy
性能更优:
DataTable dataTable = new DataTable(); // 构建DataTable数据... using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString)) { bulkCopy.DestinationTableName = "Users"; bulkCopy.WriteToServer(dataTable); }
异步操作
使用异步方法避免阻塞主线程:
await command.ExecuteNonQueryAsync(); await context.SaveChangesAsync();
常见问题解答
Q1:插入后如何获取自增ID?
- ADO.NET:在SQL语句末尾添加
SELECT SCOPE_IDENTITY()
,通过ExecuteScalar()
获取。 - EF Core:实体对象的ID属性会自动填充。
Q2:插入时间字段时出现格式错误?
- 始终使用参数化查询传递
DateTime
类型,而非字符串格式化。
Q3:如何处理特殊字符(如单引号)?
- 参数化查询会自动转义,无需手动处理。
引用说明
- ADO.NET官方文档:Microsoft SQL Server Data Access
- EF Core教程:Entity Framework Core Getting Started