Триггеры, так же как и хранимые процедуры и определенные пользователем функции, могут быть реализованы посредством CLR (Common Language Runtime). Если вам нужно реализовать, скомпилировать и сохранить триггеры CLR, выполните следующие шаги:
1. Создайте триггер с использованием С# или Visual Basic и скомпилируйте эту программу с помощью соответствующего компилятора (см. примеры 14.9 и 14.10). Используйте оператор create assembly для создания соответствующего исполняемого файла (см. пример 14.11).
2. Создайте триггер посредством оператора create trigger (см. пример 14.12).
Следующие примеры демонстрируют эти шаги. В примере 14.9 показан исходный текст программы на языке С#, которая будет использоваться для реализации триггера из примера 14.1.
Пространство имен Microsoft.SqlServer.Server включает все клиентские классы, Нужные программе на С#. SqlTriggerContext и SqlFunction являются
экземплярами классов, которые принадлежат этому пространству имен. Пространство имен System.Data.Sqiciient содержит такие классы, как SQLConnection и SQLCommand, которые используются для установления соединения и связи между клиентом и сервером базы данных. Соединение устанавливается при использовании строки соединения «context connection=true»: SqlConnection conn = new SqlConnection («context connection=true»);
После этого определяется класс storedProcedure, который служит для реализации триггеров. Метод ModifyBudget () реализует триггер с тем же именем.
Экземпляр класса SQLTriggerContext с именем context предоставляет программе доступ к виртуальной таблице, которая была создана в процессе выполнения этого триггера. Таблица хранит данные, которые приводят к выполнению триггера. Метод isupdatedcoiumno класса SQLTriggerContext дает возможность определить, был ли изменен указанный столбец таблицы.
Программа на языке С# содержит два других важных класса: SQLConnection и SQLCommand. Экземпляр класса SQLConnection обычно используется для установления соединения с базой данных, а экземпляр SQLCommand позволяет выполнять оператор SQL.
В примере 14.10 показано выполнение команды esc. С помощью этой команды вы можете скомпилировать программу на С# из примера 14.9.
В примере 14.11 показаны последующие два шага по созданию триггера modifybudget. Используйте SQL Server Management Studio для выполнения этих операторов.
Оператор create assembly использует управляемый код в качестве источника для создания соответствующего объекта вместе с создаваемым триггером CLR. Предложение with permission set в этом примере указывает, что полномочия доступа установлены в значение external_access, которое не позволяет сборкам осуществлять доступ к внешним системным ресурсам, а только некоторым из них.
В примере 14.12 создается триггер modifybudget посредством оператора create trigger.
Оператор create trigger в примере 14.12 отличается от оператора, примененного в примерах 14.1-14.5, т. к. он использует опцию external name. Эта опция указывает, что код сгенерирован с помощью CLR. Имя в этом предложении является именем, состоящим из трех частей. Первая часть является именем соответствующей сборки, вторая часть (storedProcedures) - имя класса public, определенного в примере 14.9, а третья часть (ModifyBudget) является именем метода, который указан внутри класса.
В примере 14.13 показано, как триггер из примера 14.3 может быть реализован с использованием языка С#.
Всего лишь две новые возможности, использованные в примере 14.13, требуют объяснения. Класс sqiPipe принадлежит пространству имен Microsoft.SqlServer.Server и дает вам возможность отправлять сообщения вызвавшей программе, подобные следующему: pipe.Send («The row inserted/modified»); (Строка добавлена/изменена.)
Для задания (или получения) текущей транзакции в триггере используется свойство Current класса Transaction. В примере 14.13 применяется метод Rollback о для отката всей транзакции при нарушении ограничения целостности.
В примере 14.14 показано создание сборки и соответствующего триггера, основанного на программе С# из примера 14.13. (Необходима компиляция программы на языке С# с помощью команды esc в качестве промежуточного шага, однако здесь это опущено по причине того, что является аналогом той же команды в примере 14.10.)