跳转到内容

C Sharp 执行sql 命令

来自代码酷

C#执行SQL命令[编辑 | 编辑源代码]

介绍[编辑 | 编辑源代码]

C#执行SQL命令是数据库编程中的核心操作,指通过C#代码向数据库发送SQL语句并处理返回结果的过程。这一技术广泛应用于数据查询、插入、更新和删除等操作,是连接应用程序与数据库的关键桥梁。

在.NET框架中,主要通过System.Data.SqlClient命名空间(或.NET Core中的Microsoft.Data.SqlClient)实现与SQL Server的交互。其他数据库(如MySQL、PostgreSQL)也有对应的提供程序,但核心概念相似。

核心类[编辑 | 编辑源代码]

C#执行SQL命令涉及以下关键类:

  • SqlConnection - 管理与数据库的连接
  • SqlCommand - 表示要执行的SQL语句或存储过程
  • SqlDataReader - 提供对查询结果的只进只读访问
  • SqlDataAdapter - 用于填充DataSet和更新数据库

classDiagram class SqlConnection{ +Open() +Close() } class SqlCommand{ +ExecuteNonQuery() +ExecuteReader() +ExecuteScalar() } class SqlDataReader{ +Read() +GetString() } SqlConnection --> SqlCommand SqlCommand --> SqlDataReader

基本操作[编辑 | 编辑源代码]

执行非查询命令[编辑 | 编辑源代码]

用于INSERT、UPDATE、DELETE等不返回结果集的操作:

using (SqlConnection connection = new SqlConnection("Server=myServer;Database=myDB;User Id=myUser;Password=myPassword;"))
{
    string sql = "INSERT INTO Customers (Name, Email) VALUES (@Name, @Email)";
    SqlCommand command = new SqlCommand(sql, connection);
    
    command.Parameters.AddWithValue("@Name", "John Doe");
    command.Parameters.AddWithValue("@Email", "john@example.com");
    
    connection.Open();
    int rowsAffected = command.ExecuteNonQuery();
    Console.WriteLine($"插入成功,影响行数: {rowsAffected}");
}

输出示例:

插入成功,影响行数: 1

执行查询命令[编辑 | 编辑源代码]

使用ExecuteReader()获取结果集:

using (SqlConnection connection = new SqlConnection(connectionString))
{
    string sql = "SELECT Id, Name, Email FROM Customers WHERE Country = @Country";
    SqlCommand command = new SqlCommand(sql, connection);
    command.Parameters.AddWithValue("@Country", "USA");
    
    connection.Open();
    using (SqlDataReader reader = command.ExecuteReader())
    {
        while (reader.Read())
        {
            Console.WriteLine($"ID: {reader["Id"]}, Name: {reader["Name"]}, Email: {reader["Email"]}");
        }
    }
}

输出示例:

ID: 1, Name: John Doe, Email: john@example.com
ID: 2, Name: Jane Smith, Email: jane@example.com

执行标量查询[编辑 | 编辑源代码]

当只需要返回单个值时使用ExecuteScalar():

using (SqlCommand command = new SqlCommand("SELECT COUNT(*) FROM Customers", connection))
{
    connection.Open();
    int count = (int)command.ExecuteScalar();
    Console.WriteLine($"总客户数: {count}");
}

输出示例:

总客户数: 42

参数化查询[编辑 | 编辑源代码]

重要: 永远使用参数化查询来防止SQL注入攻击!

参数化示例:

string sql = "UPDATE Products SET Price = @Price WHERE Id = @Id";
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@Price", 19.99m);
command.Parameters.AddWithValue("@Id", 101);

事务处理[编辑 | 编辑源代码]

确保多个操作作为一个原子单元执行:

using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();
    SqlTransaction transaction = connection.BeginTransaction();
    
    try
    {
        SqlCommand command1 = new SqlCommand("UPDATE Account SET Balance = Balance - 100 WHERE Id = 1", connection, transaction);
        SqlCommand command2 = new SqlCommand("UPDATE Account SET Balance = Balance + 100 WHERE Id = 2", connection, transaction);
        
        command1.ExecuteNonQuery();
        command2.ExecuteNonQuery();
        
        transaction.Commit();
        Console.WriteLine("转账成功");
    }
    catch
    {
        transaction.Rollback();
        Console.WriteLine("转账失败,已回滚");
    }
}

性能优化[编辑 | 编辑源代码]

使用存储过程[编辑 | 编辑源代码]

SqlCommand command = new SqlCommand("sp_GetCustomerOrders", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@CustomerId", 123);

批量操作[编辑 | 编辑源代码]

对于大量数据,考虑使用SqlBulkCopy类:

DataTable dataTable = GetLargeData();
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
{
    bulkCopy.DestinationTableName = "TargetTable";
    bulkCopy.WriteToServer(dataTable);
}

异步操作[编辑 | 编辑源代码]

现代应用应使用异步方法:

public async Task<List<Customer>> GetCustomersAsync()
{
    List<Customer> customers = new List<Customer>();
    
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        await connection.OpenAsync();
        SqlCommand command = new SqlCommand("SELECT * FROM Customers", connection);
        
        using (SqlDataReader reader = await command.ExecuteReaderAsync())
        {
            while (await reader.ReadAsync())
            {
                customers.Add(new Customer {
                    Id = reader.GetInt32(0),
                    Name = reader.GetString(1)
                });
            }
        }
    }
    
    return customers;
}

错误处理[编辑 | 编辑源代码]

正确处理数据库异常:

try
{
    // 数据库操作代码
}
catch (SqlException ex)
{
    foreach (SqlError error in ex.Errors)
    {
        Console.WriteLine($"错误 {error.Number}: {error.Message}");
    }
}
catch (Exception ex)
{
    Console.WriteLine($"一般错误: {ex.Message}");
}

实际案例[编辑 | 编辑源代码]

电子商务订单处理系统中的典型应用:

1. 创建订单 2. 扣减库存 3. 记录交易日志 4. 更新客户积分

所有这些操作需要在一个事务中完成,确保数据一致性。

数学表示[编辑 | 编辑源代码]

事务的ACID特性可以用以下公式表示:

{原子性(T)要么全部完成,要么全部撤销一致性(T)数据库从一个一致状态变为另一个一致状态隔离性(T)并发事务互不干扰持久性(T)一旦提交,永久有效

最佳实践[编辑 | 编辑源代码]

  • 总是及时关闭连接(使用using语句)
  • 使用参数化查询防止SQL注入
  • 考虑使用ORM(如Entity Framework)简化常见操作
  • 对频繁执行的查询使用连接池
  • 记录重要的数据库操作日志

总结[编辑 | 编辑源代码]

C#执行SQL命令是数据库交互的基础,掌握这些技术对于构建数据驱动的应用程序至关重要。从简单的查询到复杂的事务处理,理解这些概念将帮助开发者构建更健壮、更安全的应用程序。