Изменение данных с помощью хранимых процедур (ADO.NET)

Хранимые процедуры могут принимать данные в виде входных параметров и возвращать их в виде выходных параметров, результирующих наборов или возвращаемых значений. Образец, приведенный ниже, показывает, как ADO.NET отправляет и получает входные и выходные параметры, а также возвращаемые значения. Пример добавляет в таблицу новую запись, где столбец первичного ключа является столбцом идентификаторов в базе данных SQL Server.

ПримечаниеПримечание

При использовании хранимых процедур SQL Server для изменения или удаления данных с помощью SqlDataAdapter убедитесь, что в определении хранимой процедуры не указана инструкция SET NOCOUNT ON.В таком случае возвращается число затронутых строк, равное нулю, что DataAdapter интерпретирует как конфликт параллелизма.Это событие вызовет исключение DBConcurrencyException.

Пример

Образец использует следующую хранимую процедуру для вставки новой категории в таблицу Northwind Categories. Хранимая процедура принимает значение столбца CategoryName в качестве входного параметра и с помощью функции SCOPE_IDENTITY() получает новое значения поля идентификатора CategoryID и возвращает его в выходном параметре. Инструкция RETURN использует функцию @@ROWCOUNT, чтобы вернуть количество вставленных строк.

CREATE PROCEDURE dbo.InsertCategory
  @CategoryName nvarchar(15),
  @Identity int OUT
AS
INSERT INTO Categories (CategoryName) VALUES(@CategoryName)
SET @Identity = SCOPE_IDENTITY()
RETURN @@ROWCOUNT

Следующий пример кода использует хранимую процедуру InsertCategory, показанную выше, в качестве источника для свойства InsertCommand класса SqlDataAdapter. Выходной параметр @Identity будет отражен в наборе данных DataSet после вставки записи в базу данных при вызове метода Update объекта SqlDataAdapter. Код также получает возвращаемое значение.

ПримечаниеПримечание

При использовании объекта OleDbDataAdapter необходимо указать параметры с помощью сущности ParameterDirection в ReturnValue до указания других параметров.

Private Sub ReturnIdentity(ByVal connectionString As String)
    Using connection As SqlConnection = New SqlConnection( _
       connectionString)

        ' Create a SqlDataAdapter based on a SELECT query.
        Dim adapter As SqlDataAdapter = New SqlDataAdapter( _
           "SELECT CategoryID, CategoryName FROM dbo.Categories", _
           connection)

        ' Create a SqlCommand to execute the stored procedure. 
        adapter.InsertCommand = New SqlCommand("dbo.InsertCategory", _
           connection)
        adapter.InsertCommand.CommandType = CommandType.StoredProcedure

        ' Create a parameter for the ReturnValue.
        Dim parameter As SqlParameter = _
           adapter.InsertCommand.Parameters.Add( _
          "@RowCount", SqlDbType.Int)
        parameter.Direction = ParameterDirection.ReturnValue

        ' Create an input parameter for the CategoryName.
        ' You do not need to specify direction for input parameters.
        adapter.InsertCommand.Parameters.Add( _
          "@CategoryName", SqlDbType.NChar, 15, "CategoryName")

        ' Create an output parameter for the new identity value.
        parameter = adapter.InsertCommand.Parameters.Add( _
          "@Identity", SqlDbType.Int, 0, "CategoryID")
        parameter.Direction = ParameterDirection.Output

        ' Create a DataTable and fill it.
        Dim categories As DataTable = New DataTable
        adapter.Fill(categories)

        ' Add a new row.
        Dim newRow As DataRow = categories.NewRow()
        newRow("CategoryName") = "New Category"
        categories.Rows.Add(newRow)

        ' Update the database.
        adapter.Update(categories)

        ' Retrieve the ReturnValue.
        Dim rowCount As Int32 = _
           CInt(adapter.InsertCommand.Parameters("@RowCount").Value)

        Console.WriteLine("ReturnValue: {0}", rowCount.ToString())
        Console.WriteLine("All Rows:")
        Dim row As DataRow
        For Each row In categories.Rows
            Console.WriteLine("  {0}: {1}", row(0), row(1))
        Next
    End Using
End Sub
private static void ReturnIdentity(string connectionString)
{
    using (SqlConnection connection =
               new SqlConnection(connectionString))
    {
        // Create a SqlDataAdapter based on a SELECT query.
        SqlDataAdapter adapter = new SqlDataAdapter(
          "SELECT CategoryID, CategoryName FROM dbo.Categories",
          connection);

        // Create a SqlCommand to execute the stored procedure.
        adapter.InsertCommand = new SqlCommand("InsertCategory", connection);
        adapter.InsertCommand.CommandType = CommandType.StoredProcedure;

        // Create a parameter for the ReturnValue.
        SqlParameter parameter = adapter.InsertCommand.Parameters.Add(
          "@RowCount", SqlDbType.Int);
        parameter.Direction = ParameterDirection.ReturnValue;

        // Create an input parameter for the CategoryName.
        // You do not need to specify direction for input parameters.
        adapter.InsertCommand.Parameters.Add(
          "@CategoryName", SqlDbType.NChar, 15, "CategoryName");

        // Create an output parameter for the new identity value.
        parameter = adapter.InsertCommand.Parameters.Add(
          "@Identity", SqlDbType.Int, 0, "CategoryID");
        parameter.Direction = ParameterDirection.Output;

        // Create a DataTable and fill it.
        DataTable categories = new DataTable();
        adapter.Fill(categories);

        // Add a new row.
        DataRow categoryRow = categories.NewRow();
        categoryRow["CategoryName"] = "New Beverages";
        categories.Rows.Add(categoryRow);

        // Update the database.
        adapter.Update(categories);

        // Retrieve the ReturnValue.
        Int32 rowCount =
            (Int32)adapter.InsertCommand.Parameters["@RowCount"].Value;

        Console.WriteLine("ReturnValue: {0}", rowCount.ToString());
        Console.WriteLine("All Rows:");
        foreach (DataRow row in categories.Rows)
        {
            {
                Console.WriteLine("  {0}: {1}", row[0], row[1]);
            }
        }
    }
}

См. также

Основные понятия

Выполнение команды (ADO.NET)

Другие ресурсы

Получение и изменение данных в ADO.NET

Объекты DataAdapter и DataReader (ADO.NET)