• Microsoft .NET
  • ASP.NET
  • Доступ к данным с помощью элементов управления источником данных (DataSource) в ASP.NET 2.0

Доступ к данным с помощью элементов управления источником данных (DataSource) в ASP.NET 2.0 - Вставка и возврат значения колонки IDENTITY только что вставленной записи

ОГЛАВЛЕНИЕ


Вставка и возврат значения колонки IDENTITY только что вставленной записи

Многие таблицы баз данных предоставляют некоторый механизм для уникальной идентификации каждой записи. Существует множество подходов, но одним из часто применяемых является использование колонки IDENTITY, которая также называется AutoNumber. Значение  колонки IDENTITY автоматически присваивается системой базы данных в момент, когда в таблицу добавляется новая запись. Эти значения начинаются с какого-то начального значения (обычно 1) и инкрементируются на какое-то указанное число с добавлением каждой новой записи (обычно увеличивается на 1). Поэтому если вы добавите три новые записи к таблице, значения колонки IDENTITY для данных трех записей будут, соответственно, 1, 2 и 3.

При использовании колонок IDENTITY стандартным требованием  могла бы стать возможность получения значения колонки IDENTITY только что вставленной записи. Скорее всего, после вставки новой записи, вам понадобится автоматически перенести пользователя на странице с деталями, куда вы должны передать значение колонки IDENTITY посредством строки запроса, либо вам понадобится добавить дополнительные записи в дочернюю таблицу, и вам потребуется значение колонки IDENTITY только что вставленной записи родительской таблицы для того, чтобы связать записи дочерней таблицы с родительскими. В обоих случаях, в Microsoft SQL Server вы можете использовать ключевое слово SCOPE_IDENTITY() для того, чтобы получить значение колонки IDENTITY только что вставленной записи.

Для того чтобы получить данную информацию при использовании SqlDataSource необходимо сделать следующее:

  1. Создайте хранимую процедуру, которая возвращала бы значение колонки IDENTITY только что вставленной записи при помощи параметра OUTPUT.
  2. Настройте SqlDataSource таким образом, чтобы он использовал хранимую процедуру. Это подразумевает обновление InsertCommand в названии хранимой процедуры, созданной в первом пункте, путем установки InsertCommandType элемента управления источником данных в StoredProcedure и  добавления  выходного параметра к набору InsertParameters.
  3. Для получения доступа к результирующему значению выходного параметра нам необходимо создать обработчик для события Inserted элемента SqlDataSource. Помните, что данное событие выполняется после того, как действие вставки было выполнено. Как только мы получим значение IDENTITY только что вставленной записи, мы можем использовать его при необходимости.

В приложении к данной статье база данных содержит хранимую процедуру, названную AddProductAndReturnNewProductIDValue, которая принимает четыре входных параметра и имеет один выходной параметр (@NewProductID). Как демонстрирует следующий синтаксис T-SQL, данная хранимая процедура вставляет новую запись в Products и затем присваивает значение, возвращенное SCOPE_IDENTITY(), к @NewProductID:

ALTER PROCEDURE dbo.AddProductAndReturnNewProductIDValue          (
    @ProductName nvarchar(40),
    @CategoryID int,
    @UnitPrice money,
    @Discontinued bit,
    @NewProductID int OUTPUT
)
AS

-- Вставка записи в базу данных
INSERT INTO Products(ProductName, CategoryID, UnitPrice, Discontinued)
VALUES (@ProductName, @CategoryID, @UnitPrice, @Discontinued)

-- Считывание только что вставленного ProductID в @NewProductID
SET @NewProductID = SCOPE_IDENTITY()

Далее, обновите SqlDataSource таким образом, чтобы он использовал AddProductAndReturnNewProductIDValue в качестве InsertCommand вместо незапрограммированного SQL-выражения. Также, добавьте выходной параметр в набор InsertParameters. Заметьте, что выходной параметр в наборе InsertParameters является объектом Parameter , чье свойство Direction установлено в Output:

<asp:SqlDataSource ID="AddProductDataSource" runat="server" ConnectionString="..."
      InsertCommand="AddProductAndReturnNewProductIDValue"
      ProviderName="..." InsertCommandType="StoredProcedure">
   <InsertParameters>
      <asp:ControlParameter ControlID="ProductName" Name="ProductName" PropertyName="Text" />
      <asp:ControlParameter ControlID="Categories" Name="CategoryID" PropertyName="SelectedValue" />
      <asp:ControlParameter ControlID="UnitPrice" Name="UnitPrice" PropertyName="Text" />
      <asp:ControlParameter ControlID="Discontinued" Name="Discontinued" PropertyName="Checked" />
      <asp:Parameter Direction="Output" Name="NewProductID" Type="Int32" />
   </InsertParameters>
</asp:SqlDataSource>

Добавление выходного параметра к набору InsertParameters элемента SqlDataSource также добавляет выходной параметр к набору Parameters внутреннего объекта SqlCommand , используемого элементом управления источником данных во время действия вставки. Значение данного параметра может быть исследовано в обработчике события Inserted. Как показывает следующий код обработчика события, внутренний объект SqlCommand доступен через свойство e.Command в обработчике события. Здесь мы можем получить конкретный экземпляр параметра и исследовать его свойство Value для определения значения колонки IDENTITY только что вставленной записи:

Protected Sub AddProductDataSource_Inserted(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.SqlDataSourceStatusEventArgs) Handles AddProductDataSource.Inserted
   'Считываем значение выходного параметра @NewProductID
   Dim newProductID As Integer = Convert.ToInt32(e.Command.Parameters("@NewProductID").Value)

   'Отображаем сообщение о подтверждении
   NewProductAddedMsg.Text = String.Format("Товар {0} был добавлен в базу данных ... Значение ProductID данного товара равно {1}...", ProductName.Text, newProductID)
End Sub