Сначала вы добавляете хранимую процедуру в ваш проект (при помощи использования меню Project и выбора пункта Add Stored Procedure). В проект будет добавлен новый класс. В листинге 18.1 показан базовый код. который имеется в файле нового класса. Вы можете добавить свой код в статическую процедуру UpdateEmployeeLogin.
\pannMvn К*31
using System; using System.Data; using System.Data.SalClient; using System.Data.SalTypes; using Microsoft.SalServer.Server;
public partial class StoredProcedures
[Microsoft.SqlServer.Server.SqlProcedure] public static void UpdateEmployeeLogin()
{
// Здесь вы можете разместить свой код
}
Все объекты управляемого кода (в проекте SQL Server) для выполнения своей работы используют классы данных .NET Framework (т. е. ADO.NET). Это означает, что написанные вами хранимые процедуры приведут к созданию и использованию экземпляров таких классов, как SqlConnection и SqlCommand. Код, который вы пишете, идентичен коду доступа к данным, который вы писали бы в любом другом типе проекта .NET: библиотеке классов, Web-проекте или проекте Windows-форм. Поскольку общим знаменателем является использование классов ADO.NET, то разработчикам не нужно изучать других языков (вроде Т- SQL) для работы с базой данных.
Примечание
В задачи данной главы не входит рассмотрение преимуществ и недостатков написания объектов баз данных на управляемом языке по сравнению с Т-SQL. Обратитесь к докладу фирмы Microsoft с названием "Using CLR Integration in SQL Server 2005", который имеется в MSDN. Несмотря на то, что он достаточно старый (написан в ноябре 2004 года), в нем хорошо изложена данная тема, и мы настоятельно рекомендуем его прочитать.
В листинге 18.2 показана процедура на языке С#, которая обновит таблицу Employee базы данных AdventureWorks информацией для входа в систему. Этот код несложен и понятен для любого, у кого есть опыт доступа к данным при помощи языка С#.
using System; using System.Data; using System.Data.SqlClient; using System.Data.SqlTypes; using Microsoft.SqlServer.Server;
public partial class StoredProcedures
[Microsoft.SqlServer.Server.SqlProcedure]
public static void UpdateEmployeeLogin(Sqllnt32 employeeld, Sqllnt32 managerld, SqlString loginld, SqlString title, SqlDateTime hireDate, SqlBoolean currentFlag)
using (SqlConnection conn = new SqlConnection("context connection=true"))
{
SqlCommand UpdateEmployeeLoginCommand = new SqlCommand () ; UpdateEmployeeLoginCommand. CommandText =
"update HumanResources.Employee SET Managerld = " + managerId.ToString() +
", Loginld = '" + loginld.ToString() + ",M +
", Title = 1" + title.ToString() + "'" +
", HireDate = '" + hireDate.ToString() + "'" +
", CurrentFlag = " + currentFlag.ToString() +
" WHERE Employeeld = " + employeeld.ToString();
UpdateEmployeeLoginCommand.Connection = conn;
conn.Open();
UpdateEmployeeLoginCommand.ExecuteNonQuery(); conn.Close();
}
Одна строка кода заслуживает более подробного объяснения. Объект SqlConnection создается следующим образом:
SqlConnection conn = new SqlConnection("context connection=true")
Строка подключения "context connection=true" говорит движку провайдеров данных о том, что подключение должно быть создано в том же контексте, что и вызывающее приложение. Поскольку эта процедура будет работать внутри базы данных, то это означает, что вы будете и подключаться к базе данных хоста в контексте (транзакционном и прочем) вызывающего приложения, и работать в нем. Поэтому вам не нужно жестко прописывать здесь полностью всю строку подключения SQL.
Для сравнения в листинге 18.3 показан тот же самый запрос обновления на языке T-SQL.
ALTER PROCEDURE [HumanResources].[uspUpdateEmployeeLogin] @EmployeeID [int],
@ManagerID [int],
@LoginID [nvarchar](256),
@Title [nvarchar] (50),
@HireDate [datetime],
@CurrentFlag [dbo].[Flag]
WITH EXECUTE AS CALLER AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
UPDATE [HumanResources].[Employee]
SET [ManagerlD] = @ManagerID ,[LoginID] = @LoginID , [Title] = @Title ,[HireDate] = @HireDate ,[CurrentFlag] = @CurrentFlag WHERE [EmployeelD] = @EmployeeID;
END TRY BEGIN CATCH
EXECUTE [dbo].[uspLogError];
END CATCH;
END;