Выбрать главу

РИС. 6.2. Отображение данных из таблицы tblEmployees в сетке grdDataGrid

НА ЗАМЕТКУ

Хотя использование объекта CommandBuilder для генерации команд обновления требует минимального количества кода, оно связано со значительными накладными расходами. Дело в том, что объект CommandBuilder должен выполнить дополнительное обращение к серверу базы данных для извлечения метаданных, которые необходимы для автоматической генерации команд обновления. Эта возможность очень полезна и позволяет создавать запросы "на лету". Однако, если запросы уже известны во время создания приложения, явное указание команд и их параметров в коде и использование явных команд обновления или программы-мастера DataAdapter Configuration Wizard приведет к повышению производительности.

Явное указание команд обновления

В отличие от довольно простого способа генерации нужных команд обновления с помощью объекта CommandBuilder, явное указание команд обновления в коде представляет собой хотя и более гибкий, но весьма трудоемкий способ. При его использовании каждая из четырех команд управления данными (Select, Insert, Update и Delete) должна быть создана отдельно. Чаще всего они кодируются в виде хранимой процедуры для каждой команды SQL.

В листинге 6.4 представлен сценарий SQL Server для генерации четырех хранимых процедур. Хранимая процедура SelectEmployees просто выбирает все поля таблицы tblEmployee. Хранимая процедура InsertEmployee принимает четыре параметра, т.е. по одному для каждого обновляемого поля. Хранимая процедура UpdateEmployee принимает те же четыре параметра для обновляемых полей и еще один параметр для исходного значения идентификационного поля, которое используется в предложении WHERE для выбора обновляемой записи (на основании первичного ключа). Хранимая процедура DeleteEmployee принимает исходное значение идентификационного поля для удаления указанной записи.

Листинг 6.4. Сценарий SQL Server для создания хранимых процедур для таблицы tblEmployee

IF EXISTS (SELECT * FROM sysobjects WHERE name =

 'SelectEmployees' AND user__ name(uid) = 'dbo'

 DROP PROCEDURE [dbo].[SelectEmployees]

GO

CREATE PROCEDURE [dbo].[SelectEmployees]

AS

 SET NOCOUNT ON;

 SELECT FirstName, LastName, DepartmentID, Salary, ID FROM

 tblEmployee

GO

IF EXISTS (SELECT * FROM sysobjects WHERE name =

 'InsertEmployee' AND user_name(uid) = 'dbo'

 DROP PROCEDURE [dbo].[InsertEmployee]

GO

CREATE PROCEDURE [dbo].[InsertEmployee] (

 @FirstName varchar(50),

 @LastName varchar(70),

 @DepartmentID int,

 @Salary money

)

AS

 SET NOCOUNT ON;

 SELECT INTO tblEmployee(FirstName, LastName, DepartmentID, Salary)

 VALUES (@FirstName, @LastName, @DepartmentID, @Salary)

GO

IF EXISTS (SELECT * FROM sysobjects WHERE name =

 'UpdateEmployee' and user_name(uid) = 'dbo'

 DROP PROCEDURE [dbo].[UpdateEmployee]

GO

CREATE PROCEDURE [dbo].[UpdateEmployee] (

 @FirstName varchar(50),

 @LastName varchar(70),

 @DepartmentID int,

 @Salary money,

 @Original_ID int

)

AS

 SET NOCOUNT ON;

 UPDATE tblEmployee SET FirstName = @FirstName, LastName = @LastName,

  DepartmentID = @DepartmentID, Salary = @Salary

 WHERE (ID = @Original_ID)

GO

IF EXISTS (SELECT * FROM sysobjects WHERE name

 'DeleteEmployee' and user_name

 DROP PROCEDURE [dbo].[DeleteEmployee]

GO

create procedure [dbo].[DeleteEmployee] (@Original_ID int)

AS

 SET NOCOUNT ON;

 DELETE FROM tblEmployee

 WHERE (ID = @Original_ID)

GO

Вернемся к коду приложения. Во-первых, изменим первую строку кода в подпрограмме btnLoad_Click, т.е. вместо вызова подпрограммы LoadCommandBuilder вставим вызов подпрограммы LoadExplicitCode. Кроме того, для отладки явно заданного кода для команды обновления нужно добавить блок Try-Catch в подпрограмму btnUpdate_Click, которая теперь будет иметь приведенный ниже вид.

Private Sub btnUpdate_Click(ByVal sender As System.Object, _

 ByVal e As System.EventArgs) Handles btnUpdate.Click

 Try

  daEmployees.Update(dsEmployeeInfo, "Employees")

 Catch es As SqlException

  MessageBox.Show(es.Message)

 End Try

End Sub

Наконец, код подпрограммы LoadExplicitCode будет выглядеть так, как показано в листинге 6.5.

Листинг 6.5. Подпрограмма LoadExplicitCode для четырех специализированных команд SQL для адаптера данных daEmployees

Private Sub LoadExplicitCode()

 Dim param As SqlParameter

 If conn.State = ConnectionState.Closed Then

  conn.Open()

 End If

 ' Создание нового объекта DataAdapter.

 daEmployees = New SqlDataAdapter()

 ' Создание специализированной

 ' хранимой процедуры для команды Select.

 daEmployees.SelectCommand = New SqlCommand()

 With daEmployees.SelectCommand

  .Connection = conn

  .CommandType = CommandType.StoredProcedure

  .CommandText = "SelectEmployees"

 End With

 ' Создание специализированной

 ' хранимой процедуры для команды Insert.

 daEmployees.InsertCommand = New SqlCommand()