c#中两种不同的存储过程调用与比较


在C#中调用存储过程通常有两种主要方式:使用`SqlCommand`对象与`ExecuteNonQuery`或`ExecuteReader`(取决于存储过程的操作类型),以及使用`SqlDataAdapter`(特别是当需要与`DataTable`或`DataSet`交互时)。下面我将分别展示这两种方法的示例,并进行简要的比较。

### 使用`SqlCommand`与`ExecuteNonQuery`或`ExecuteReader`

这种方法直接通过`SqlCommand`对象执行存储过程,适用于执行不需要返回大量数据的操作(如INSERT、UPDATE、DELETE),或者需要逐行读取返回的数据(如SELECT)。

#### 示例代码(使用`ExecuteNonQuery`)


using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();
    using (SqlCommand cmd = new SqlCommand("usp_YourStoredProcedureName", conn))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        // 如果有参数,可以这样添加
        // cmd.Parameters.AddWithValue("@paramName", paramValue);
        int rowsAffected = cmd.ExecuteNonQuery(); // 对于INSERT、UPDATE、DELETE操作
        // 处理rowsAffected...
    }
}

#### 示例代码(使用`ExecuteReader`)


using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();
    using (SqlCommand cmd = new SqlCommand("usp_YourStoredProcedureName", conn))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        // 添加参数(如果需要)
        // cmd.Parameters.AddWithValue("@paramName", paramValue);
        using (SqlDataReader reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                // 读取数据
                // 例如: Console.WriteLine(reader["ColumnName"].ToString());
            }
        }
    }
}

### 使用`SqlDataAdapter`

这种方法适用于需要将存储过程返回的数据集填充到`DataTable`或`DataSet`中的场景。它提供了更多的灵活性来处理大量数据。

#### 示例代码


DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(connectionString))
{
    SqlDataAdapter da = new SqlDataAdapter("usp_YourStoredProcedureName", conn);
    da.SelectCommand.CommandType = CommandType.StoredProcedure;
    // 添加参数(如果需要)
    // da.SelectCommand.Parameters.AddWithValue("@paramName", paramValue);
    da.Fill(dt); // 将存储过程的结果填充到DataTable中
    // 使用DataTable...
}

### 比较

- **`SqlCommand` + `ExecuteNonQuery`/`ExecuteReader`**:直接、高效,适合执行简单的数据库操作或逐行读取数据。对于复杂的业务逻辑或需要频繁访问数据库的场景,可能需要更多的代码来处理数据。

- **`SqlDataAdapter`**:适用于需要将大量数据加载到内存中的场景(如填充`DataTable`或`DataSet`)。它简化了数据处理过程,但在某些情况下可能不如直接使用`SqlCommand`灵活或高效。

选择哪种方法取决于你的具体需求,包括你需要执行的操作类型、返回数据的量以及你如何处理这些数据。