Пример триггера в PostgreSQL #2: создание таблицы аудита
Создание таблицы аудита
create table time_punch_audit ( id serial primary key, change_time timestamp not null default now(), change_employee_id int not null references employee(id), time_punch_id int not null references time_punch(id), punch_time timestamp not null );
- Время обновления прохождения.
- Сотрудник, который выполнил обновление.
- ID прохода, который был изменен.
- Время прохода до того, как было сделано обновление.
alter table time_punch add column change_employee_id int null references employee(id);
update_time_punch(id, change_user_id, …)
create or replace function fn_change_time_punch_audit() returns trigger as $psql$ begin insert into time_punch_audit (change_time, change_employee_id, time_punch_id, punch_time) values (now(), new.change_employee_id, new.id, old.punch_time); return new; end; $psql$ language plpgsql; create trigger change_time_punch_audit after update on time_punch for each row execute procedure fn_change_time_punch_audit();
select punch_time from time_punch where id=2; punch_time --------------------- 2020-01-01 11:30:00 (1 row)
update time_punch set punch_time = punch_time + interval '5 minute', change_employee_id = 2 where id = 2;
Использование таблиц вставленных и удаленных данных в триггерах INSTEAD OF
Таблицы inserted и deleted в триггерах INSTEAD OF подчиняются тем же правилам, что и таблицы inserted и deleted в триггерах AFTER. Формат таблиц inserted и deleted совпадает с форматом таблицы, для которой задан триггер INSTEAD OF. Каждый столбец таблиц inserted и deleted прямо сопоставляется с определенным столбцом базовой таблицы.
Следующие правила относятся к инструкциям INSERT или UPDATE, ссылающимся на таблицу с триггером INSTEAD OF, которые должны предоставлять такие значения для столбцов, как если бы в таблице не было триггера INSTEAD OF.
-
Не могут быть заданы значения для вычисляемых столбцов и для столбцов с типом данных timestamp .
-
Если параметр IDENTITY_INSERT для этой таблицы не равен ON, то значения для столбцов со свойством IDENTITY не могут быть заданы. Когда значение параметра IDENTITY_INSERT равно ON, инструкции INSERT должны сами задавать это значение.
-
Инструкции INSERT должны определять значения для всех столбцов со свойством NOT NULL, не имеющих ограничений DEFAULT.
-
Для любого столбца, кроме вычисляемых столбцов, столбцов определителя и столбцов типа timestamp , определение значений является необязательным, если разрешены NULL значения или если какой-либо столбец со свойством NOT NULL обладает определением DEFAULT.
Если инструкция INSERT, UPDATE или DELETE ссылается на представление, для которого определен триггер INSTEAD OF, компонент Компонент Database Engine вызывает триггер вместо того, чтобы предпринять какое-либо прямое действие по отношению к таблице. Триггер использует сведения, представленные в таблицах inserted и deleted, для создания инструкций, необходимых для выполнения требуемых действий в базовых таблицах, даже в том случае, если формат данных в таблицах inserted и deleted, созданных для представления, отличается от формата данных базовой таблицы.
Формат таблиц inserted и deleted триггера INSTEAD OF, заданного для представления, совпадает со списком выборки инструкции SELECT, заданной для представления. Пример:
Результирующий набор для этого представления содержит три столбца: один int и два nvarchar . Таблицы inserted и deleted триггера INSTEAD OF, заданного для представления, также содержат столбец типа int с именем , столбец типа nvarchar с именем и столбец типа nvarchar с именем .
Список выборки представления также может содержать выражения, которые не сопоставлены напрямую с каким-либо одним столбцом базовой таблицы. Некоторые выражения представления, такие как вызов функции или константы, могут не ссылаться на столбцы и просто пропускаться. Сложные выражения могут ссылаться на несколько столбцов, однако таблицы inserted и deleted содержат только по одному значению для каждой вставляемой строки. Такие же проблемы появляются и в простых выражениях представления, если они ссылаются на вычисляемый столбец со сложным выражением. Триггер INSTEAD OF в представлении должен обрабатывать такие типы выражений.
Триггеры входа
Триггеры входа выполняют хранимые процедуры в ответ на событие LOGON. Это событие вызывается, когда для пользователя создается сеанс в экземпляре SQL Server. Триггеры входа срабатывают после проверки подлинности при входе, но перед тем, как устанавливается пользовательский сеанс. Таким образом, все созданные внутри триггера сообщения, которые обычно передаются пользователю (например, сообщения об ошибках и сообщения от инструкции PRINT), перенаправляются в журнал ошибок SQL Server. Дополнительные сведения см. в разделе Триггеры входа.
Если проверка подлинности завершается сбоем, триггеры входа не срабатывают.
Распределенные транзакции не поддерживаются в триггерах входа. Если триггер содержит распределенную транзакцию, при его срабатывании возвращается ошибка 3969.
Отключение триггера входа
Триггер входа может эффективно запрещать подключения к службам Компонент Database Engine для всех пользователей, в том числе членов предопределенной роли сервера sysadmin . Если триггер входа запрещает соединения, члены предопределенной роли сервера sysadmin могут подключаться с помощью выделенного административного соединения или путем вызова Компонент Database Engine в режиме минимальной конфигурации (-f). Дополнительные сведения см. в разделе Параметры запуска службы Database Engine.
Типы ограничений в SQL Server
В Microsoft SQL Server реализовано несколько типов ограничений, каждое из которых предназначено для выполнения какой-то конкретной задачи, и сейчас мы с Вами рассмотрим эти типы.
Ограничение NOT NULL
Это ограничение, с помощью которого мы можем запретить или наоборот разрешить хранение в столбце значений NULL, т.е. неопределенных значений. Таким образом, мы можем сказать, что если у нас запрещены значения NULL в столбце, то этот столбец является обязательным к заполнению, а если у нас разрешены значения NULL, то столбец можно и не заполнять, т.е. данное ограничение поможет нам контролировать внесение и хранение обязательных характеристик той или иной сущности. И, конечно же, Вы должны знать, что наличие значений NULL в базе данных — это не очень хорошо, поэтому данное ограничение помогает исключить такие значения.
С этим ограничением Вы, наверное, уже сталкивалась, и неоднократно работали, так как при создании таблицы, или добавления нового столбца, мы практически всегда указываем возможность принятия столбцом значений NULL, для этого мы пишем NULL или NOT NULL в определении таблицы.
Ограничение PRIMARY KEY
PRIMARY KEY – ограничение первичного ключа. Первичный ключ – это столбец или комбинация столбцов, значения которых гарантируют уникальность каждой строки, что дает нам возможность идентифицировать каждую строку в таблице по данному ключу.
PRIMARY KEY должен быть практически в каждой таблице, и он должен быть у нее один. Обычно первичный ключ создают для столбца, который выполняет роль счетчика (IDENTITY), и он не может содержать значения NULL. Создав ограничение PRIMARY KEY, Вы можете не беспокоиться о том, что в Вашей таблице вдруг окажется две записи с одинаковым идентификатором.
Ограничение FOREIGN KEY
FOREIGN KEY – это ограничение внешнего ключа. Ограничение FOREIGN KEY предназначено для установления связи между данными в таблицах. Иными словами, если в таблице есть ключ (столбец, обычно идентификатор), который есть и в другой таблице, то эти таблицы должны быть связаны с помощью ограничения FOREIGN KEY. Таким образом, с помощью данного ограничения мы выстраиваем связь между таблицами в базе данных.
Ограничение FOREIGN KEY обеспечивает ссылочную целостность, оно позволяет исключить ситуации, когда, например, у Вас в одной таблице есть записи, которые ссылаются на отсутствующие записи в другой таблицы, т.е. этих записей нет, в итоге получаются некорректные данные.
Ограничение UNIQUE
UNIQUE – это ограничение, которое обеспечивает уникальность значений в столбце или комбинации столбцов. UNIQUE позволяет исключить повторяющиеся значения в столбце. В отличие от PRIMARY KEY, для таблицы можно задать несколько ограничений UNIQUE, и столбец, для которого определено данное ограничение, может содержать значение NULL (но, как Вы понимаете, такое значение может быть только одно в этом столбце). В случае если столбцы в таблице были определены без ограничения UNIQUE при создании таблицы, то для того чтобы добавить этого ограничения, в соответствующем столбце не должно быть повторяющихся значений.
Ограничение CHECK
CHECK – это проверочное ограничение. Данное ограничение проверяет данные, на предмет выполнения определенных условий, при вводе в таблицу. Иными словами, если Вам требуется, чтобы в столбце хранились только значения, которые отвечают определённым требованиям, то как раз с помощью ограничение CHECK Вы можете автоматизировать процесс контроля за вводом данных. Например, по бизнес требованию, цена товара не должна быть отрицательной, для этого в таблице для столбца, который хранит цену товара, мы можем определить проверочное ограничение CHECK, которое будет проверять все значения, вносимые в данный столбец. Таким образом, мы на уровне сервера задаем четкие правила допустимых значений определенных столбцов.
К одному столбцу в таблице мы можем применять несколько проверочных ограничений. Создать проверочное ограничение UNIQUE можно с любым логическим выражением, которое возвращает значение TRUE или FALSE.
Ограничение DEFAULT
DEFAULT – это значение по умолчанию. Мы уже говорили о том, что значение NULL — это не очень хорошо, поэтому еще одним способом избавления от данного значения, является возможность задать для столбца значение по умолчанию, которое будет сохранено, если при вводе данных мы не указали никакого значения. Например, если в столбец с ценой товара не указать цену, когда мы будет добавлять новый товар, то SQL сервер автоматически добавит значение по умолчанию, которое мы укажем при определении этого ограничения, к примеру, 0.
3.4.1. Создание триггера
Для создания триггеров используйте оператор CREATE TRIGGER. В операторе указывается таблица, для которой объявляется триггер, событие, для которого триггер выполняется и индивидуальные инструкции для триггера. В общем команда показана в листинге 3.2.
Листинг 3.2. Общий вид команды CREATE TRIGGER
CREATE TRIGGER trigger_name ON { table | view } { { { FOR | AFTER | INSTEAD OF } { } AS | IF (COLUMNS_UPDATED() {bitwise_operator} updated_bitmask) { comparison_operator } column_bitmask } ] sql_statement } }
Прежде чем мы рассмотрим реальный пример, давайте рассмотрим два замечания. Когда вы создаете триггер, информация о триггере вставляется в системные таблицы sysobjects и syscomments. Если триггер создается с таким же именем, как и существующий, новый триггер перезаписывает существующий. Сервер SQL не поддерживает добавления триггеров объявленных пользователем на системные таблицы, поэтому вы не можете создавать их для системных таблиц.
Сервер SQL не позволяет использовать следующие операторы в теле триггера:
- ALTER DATABASE;
- CREATE DATABASE;
- DISK INIT;
- DISK RESIZE;
- DROP DATABASE;
- LOAD DATABASE;
- LOAD LOG;
- RECONFIGURE;
- RESTORE DATABASE;
- RESTORE LOG.
Чтобы не запоминать все эти операторы, проще запомнить, что нельзя изменять структуру базы данных.
Триггеры DDL и области их применения
Ранее мы рассмотрели триггеры DML, которые задают действие, предпринимаемое сервером при изменении таблицы инструкциями INSERT, UPDATE или DELETE. Компонент Database Engine также позволяет определять триггеры для инструкций DDL, таких как CREATE DATABASE, DROP TABLE и ALTER TABLE. Триггеры для инструкций DDL имеют следующий синтаксис:
Соглашения по синтаксису
Как можно видеть по их синтаксису, триггеры DDL создаются таким же способом, как и триггеры DML. А для изменения и удаления этих триггеров используются те же инструкции ALTER TRIGGER и DROP TRIGGER, что и для триггеров DML. Поэтому в этом разделе рассматриваются только те параметры инструкции CREATE TRIGGER, которые новые для синтаксиса триггеров DDL.
Первым делом при определении триггера DDL нужно указать его область действия. Предложение DATABASE указывает в качестве области действия триггера DDL текущую базу данных, а предложение ALL SERVER — текущий сервер.
После указания области действия триггера DDL нужно в ответ на выполнение одной или нескольких инструкций DDL указать способ запуска триггера. В параметре event_type указывается инструкция DDL, выполнение которой запускает триггер, а в альтернативном параметре event_group указывается группа событий языка Transact-SQL. Триггер DDL запускается после выполнения любого события языка Transact-SQL, указанного в параметре event_group. Ключевое слово LOGON указывает триггер входа.
Кроме сходства триггеров DML и DDL, между ними также есть несколько различий. Основным различием между этими двумя видами триггеров является то, что для триггера DDL можно задать в качестве его области действия всю базу данных или даже весь сервер, а не всего лишь отдельный объект. Кроме этого, триггеры DDL не поддерживают триггеров INSTEAD OF. Как вы, возможно, уже догадались, для триггеров DDL не требуются таблицы inserted и deleted, поскольку эти триггеры не изменяют содержимого таблиц.
В следующих подразделах подробно рассматриваются две формы триггеров DDL: триггеры уровня базы данных и триггеры уровня сервера.
Триггеры DDL уровня базы данных
В примере ниже показано, как можно реализовать триггер DDL, чья область действия распространяется на текущую базу данных:
Триггер в этом примере предотвращает удаление любого триггера для базы данных SampleDb любым пользователем. Предложение DATABASE указывает, что триггер trigger_PreventDrop является триггером уровня базы данных. Ключевое слово DROP_TRIGGER указывает предопределенный тип события, запрещающий удаление любого триггера.
Триггеры DDL уровня сервера
Триггеры уровня сервера реагируют на серверные события. Триггер уровня сервера создается посредством использования предложения ALL SERVER в инструкции CREATE TRIGGER. В зависимости от выполняемого триггером действия, существует два разных типа триггеров уровня сервера: обычные триггеры DDL и триггеры входа. Запуск обычных триггеров DDL основан на событиях инструкций DDL, а запуск триггеров входа — на событиях входа.
В примере ниже демонстрируется создание триггера уровня сервера, который является триггером входа:
Здесь сначала создается имя входа SQL Server loginTest, которое потом используется в триггере уровня сервера. По этой причине, для этого имени входа требуется разрешение VIEW SERVER STATE, которое и предоставляется ему посредством инструкции GRANT. После этого создается триггер trigger_ConnectionLimit. Этот триггер является триггером входа, что указывается ключевым словом LOGON.
С помощью представления sys.dm_exec_sessions выполняется проверка, был ли уже установлен сеанс с использованием имени входа loginTest. Если сеанс уже был установлен, выполняется инструкция ROLLBACK. Таким образом имя входа loginTest может одновременно установить только один сеанс.
Атомарность
Транзакции важны как в многопользовательских, так и в однопользовательских системах. В однопользовательских системах транзакции — это логические единицы работы, после выполнения которых база данных остается в целостном состоянии. Транзакции также являются единицами восстановления данных после сбоев — восстанавливаясь, система ликвидирует следы транзакций, не успевших успешно завершиться в результате программного или аппаратного сбоя. Эти два свойства транзакций определяют атомарность (неделимость) транзакции.
Атомарность. Транзакция выполняется как атомарная операция — либо выполняется вся транзакция целиком, либо она целиком не выполняется.
Ошибка MySQL: пользователь, указанный в качестве непредвиденного («Skip-Grants» @ ‘Skip-Grants Host’) не существует
http-equiv=»Content-Type» content=»text/html;charset=UTF-8″>style=»clear:both;»>
Причина: Я экспортирую базу данных с другого компьютера в файл SQL, а затем запустил файлы, структуры и данные SQL, но чтобы вставить данные, пользователь, указанный в виде ДЕПОТРЕНИЯ («Skip-Grants». «Skip-Grants Host») не существует
Я нашел некоторые документы, я обнаружил, что проблема привилегии, создавая пользователи, используемые этими данными, не существуют на компьютере, поэтому пользователь не имеет права на управление базой данных.
Решение — добавить разрешения для пользователей
Новый запрос, сделайте следующее утверждение
Соответствующая переписка внутри коробки
Интеллектуальная рекомендация
1. Для реальных сигналов (для понимания): A (ω) является соотношением амплитуды выходного сигнала и амплитуды входного сигнала, называемого частотой амплитуды. Φ (ω) — это разница межд…
Один. вести Многие люди задавали некоторые вопросы о создании проекта Flex + LCDS (FDS) в сообщениях и группах. Из-за операции ее трудно четко объяснить, поэтому я написал простой учебник (я обещал эт…
package com.example.phonehttp; import android.os.Bundle; import android.os.Handler; import android.app.Activity; import android.widget.ScrollView; import android.widget.TextView; public class MainActi…
Он предназначен для реализации подкласса того же родительского класса с родительским классом. Полиморфизм Один и тот же ссылочный тип использует разные экземпляры для выполнения разных операций; Идея …
тема: Объедините два упорядоченных слоя в новый заказанный список и возврат. Новый список состоит из всех узлов двух связанных списков, данных сплавным. Пример: Анализ: два связанных списка состоит в …
Вам также может понравиться
D. Самая ценная строка Пример ввода 2 2 aa aaa 2 b c Образец вывода aaa c На самом деле, будучи задетым этим вопросом, вы должны быть осторожны. После инвертирования строки, если две строки имеют один…
Given a 2D integer matrix M representing the gray scale of an image, you need to design a smoother to make the gray scale of each cell becomes the average gray scale (rounding down) of all the 8 surro…
calc () может быть очень незнакомым для всех, и трудно поверить, что calc () является частью CSS. Поскольку он выглядит как функция, почему он появляется в CSS, поскольку это функция? Этот момент такж…
Основываясь на дереве регрессии, сформированном CART, а также на предварительной и последующей обрезке дерева, код выглядит следующим образом:…
Откат Обновление в режиме онлайн с версии Centos (CentOS Linux версии 7.3.1611 (Core) до CentOS Linux версии 7.5.1804 (Core)) # ошибка соединения yum-ssh после обновления yexpected key exchange group …
Шесть: управлять триггерами
1. Просмотр триггера
(1). Просмотреть все триггеры в базе данных
sysobjects содержит объекты базы данных, а запись, тип которой x равен TR, является триггерным объектом. В столбце имени мы видим имя триггера.
(2) .sp_helptextПросмотреть содержимое триггера
Содержимое триггера будет отображаться в табличном стиле.
В дополнение к триггерам sp_helptext также может отображать текст правил, значений по умолчанию, незашифрованных хранимых процедур, пользовательских функций и представлений.
(3) .sp_helptrigger используется для просмотра свойств триггера
sp_helptrigger имеет два параметра: первый параметр — это имя таблицы, второй — тип триггера типа char (6), который может быть INSERT, UPDATE и DELETE. Если этот параметр не указан, отображаются атрибуты всех типов триггеров в указанной таблице. ,
2. Отключите триггер включения
Отключено: изменить имя таблицы, отключить имя триггера Включить: изменить имя таблицы, включить имя триггера
Если есть несколько триггеров, имена каждого триггера разделяются запятой.
Если «имя триггера» заменено на «ВСЕ», это означает, что все триггеры таблицы отключены или включены.
3 изменить триггер
4. Удалить триггер
Два: роль триггера
Основная функция триггера заключается в том, что он может обеспечить сложную ссылочную целостность и согласованность данных, которые не могут быть гарантированы первичным ключом и внешним ключом, и может каскадно изменять связанные таблицы в базе данных для улучшения данных, более сложных, чем ограничения CHECK. Полнота и пользовательские сообщения об ошибках. Основная функция триггера в основном имеет следующие аспекты:
- Обеспечить ссылочную целостность между базами данных
- Каскадное изменение всех связанных таблиц в базе данных, автоматический запуск других связанных операций
- Отслеживание изменений, отмена или откат незаконных операций для предотвращения незаконного изменения данных
- Возвращает пользовательское сообщение об ошибке, ограничение не может вернуть информацию, и триггер может
- Триггеры могут вызывать больше хранимых процедур
Преимущества триггеров DML
Триггеры DML аналогичны ограничениям в том, что могут предписывать целостность сущностей или целостность домена. Вообще говоря, целостность сущностей должна всегда предписываться на самом нижнем уровне с помощью индексов, являющихся частью ограничений PRIMARY KEY и UNIQUE или создаваемых независимо от ограничений. Целостность домена должна быть предписана через ограничения CHECK, а ссылочная целостность — через ограничения FOREIGN KEY. Триггеры DML наиболее полезны в тех случаях, когда функции ограничений не удовлетворяют функциональным потребностям приложения.
В следующем списке приведено сравнение триггеров DML с ограничениями и указано, в чем триггеры DML имеют преимущества.
-
Триггеры DML позволяют каскадно проводить изменения через связанные таблицы в базе данных; но эти изменения могут осуществляться более эффективно с использованием каскадных ограничений ссылочной целостности. Ограничения FOREIGN KEY могут проверить значения столбца только на предмет точного совпадения со значениями другого столбца, за исключением случаев, когда с помощью предложения REFERENCES задаются каскадные ссылочные действия.
-
Для предотвращения случайных или неверных операций INSERT, UPDATE и DELETE и реализации других более сложных ограничений, чем те, которые определены при помощи ограничения CHECK.
В отличие от ограничений CHECK, DML-триггеры могут ссылаться на столбцы других таблиц. Например, триггер может использовать инструкцию SELECT для сравнения вставленных или обновленных данных и выполнения других действий, например изменения данных или отображения пользовательского сообщения об ошибке.
-
Чтобы оценить состояние таблицы до и после изменения данных и предпринять действия на основе этого различия.
-
Несколько DML-триггеров одинакового типа (INSERT, UPDATE или DELETE) для таблицы позволяют предпринять несколько различных действий в ответ на одну инструкцию изменения данных.
-
Ограничения могут сообщать об ошибках только с помощью соответствующих стандартных системных сообщений. Если для пользовательского приложения требуются более сложные методы управления ошибками и, соответственно, пользовательские сообщения, то необходимо использовать триггер.
-
При использовании триггеров DML может произойти откат изменений, нарушающих ссылочную целостность, что приводит к запрету модификации данных. Подобные триггеры могут применяться при изменении внешнего ключа в случаях, когда новое значение не соответствует первичному ключу. Обычно в указанных случаях используются ограничения FOREIGN KEY.
-
Если в таблице триггеров существуют ограничения, то их проверка осуществляется между выполнением триггеров INSTEAD OF и AFTER. В случае нарушения ограничений выполняется откат действий триггеров INSTEAD OF, а триггер AFTER не срабатывает.
Два простых примера
1. вставьте триггер
Как упоминалось выше, количество заказа должно быть меньше количества запасов, и количество запасов уменьшится после заказа. Для этого мы должны создать триггер в списке заказов, который не только определяет соотношение количества, но и обновляет количество запасов при выполнении условий. Когда заказанное количество больше, чем количество запасов, выполняется операция отката; когда заказанное количество меньше или равно количеству запасов, количество запасов обновляется. код показан ниже:
Результаты экспериментов следующие: Вставьте правильные данные:
количество заказа> количество запасов:
2. удалить триггер
Наша цель — удалить товар, и соответствующие данные в деталях заказа будут удалены соответственно. Здесь используется каскадное удаление, мы также можем использовать триггеры для завершения. Основная идея — уточнить условия срабатывания триггера и порядок удаления таблиц. Наше условие триггера — «удалить товары», а порядок удаления таблиц — «сначала удалите таблицу деталей заказа, а затем удалите таблицу продуктов». код показан ниже:
Сравнение удаления выглядит следующим образом: Перед удалением: После удаления продукта:
Триггеры и среда CLR
Подобно хранимым процедурам и определяемым пользователем функциям, триггеры можно реализовать, используя общеязыковую среду выполнения (CLR — Common Language Runtime). Триггеры в среде CLR создаются в три этапа:
-
Создается исходный код триггера на языке C# или Visual Basic, который затем компилируется, используя соответствующий компилятор в объектный код.
-
Объектный код обрабатывается инструкцией CREATE ASSEMBLY, создавая соответствующий выполняемый файл.
-
Посредством инструкции CREATE TRIGGER создается триггер.
Выполнение всех этих трех этапов создания триггера CLR демонстрируется в последующих примерах. Ниже приводится пример исходного кода программы на языке C# для триггера из первого примера в статье. Прежде чем создавать триггер CLR в последующих примерах, сначала нужно удалить триггер trigger_PreventDrop, а затем удалить триггер trigger_ModifyBudget, используя в обоих случаях инструкцию DROP TRIGGER.
Пространство имен Microsoft.SQLServer.Server содержит все классы клиентов, которые могут потребоваться программе C#. Классы SqlTriggerContext и SqlFunction являются членами этого пространства имен. Кроме этого, пространство имен System.Data.SqlClient содержит классы SqlConnection и SqlCommand, которые используются для установления соединения и взаимодействия между клиентом и сервером базы данных. Соединение устанавливается, используя строку соединения «context connection = true».
Затем определяется класс Triggers, который применяется для реализации триггеров. Метод ModifyBudget() реализует одноименный триггер. Экземпляр context класса SqlTriggerContext позволяет программе получить доступ к виртуальной таблице, создаваемой при выполнении триггера. В этой таблице сохраняются данные, вызвавшие срабатывание триггера. Метод IsUpdatedColumn() класса SqlTriggerContext позволяет узнать, был ли модифицирован указанный столбец таблицы.
Данная программа содержит два других важных класса: SqlConnection и SqlCommand. Экземпляр класса SqlConnection обычно применяется для установления соединения с базой данных, а экземпляр класса SqlCommand позволяет исполнять SQL-инструкции.
Программу из этого примера можно скомпилировать с помощью компилятора csc, который встроен в Visual Studio. Следующий шаг состоит в добавлении ссылки на скомпилированную сборку в базе данных:
Инструкция CREATE ASSEMBLY принимает в качестве ввода управляемый код и создает соответствующий объект, на основе которого создается триггер CLR. Предложение WITH PERMISSION_SET в примере указывает, что разрешениям доступа присвоено значение SAFE.
Наконец, в примере ниже посредством инструкции CREATE TRIGGER создается триггер trigger_modify_budget:
Инструкция CREATE TRIGGER в примере отличается от такой же инструкции в примерах ранее тем, что она содержит параметр EXTERNAL NAME. Этот параметр указывает, что код создается средой CLR. Имя в этом параметре состоит из трех частей. В первой части указывается имя соответствующей сборки (CLRStoredProcedures), во второй — имя открытого класса, определенного в примере выше (Triggers), а в третьей указывается имя метода, определенного в этом классе (ModifyBudget).