Поделиться через


Программирование DML-триггеров

Чтобы создать DML-триггер, разрешается использовать почти любую инструкцию Transact-SQL, которую можно написать как пакет, за исключением следующих.

ALTER DATABASE

CREATE DATABASE

DROP DATABASE

LOAD DATABASE

LOAD LOG

RECONFIGURE

RESTORE DATABASE

RESTORE LOG

ms190227.note(ru-ru,SQL.90).gifВажно!
Инструкции LOAD DATABASE и LOAD LOG включены в SQL Server 2005 только для обеспечения обратной совместимости. Их поддержка в дальнейшем может быть прекращена.

Кроме того, при применении DML-триггера к таблице или представлению, для которого инициируется триггерное действие, в теле DML-триггера нельзя использовать следующие инструкции Transact-SQL.

ms190227.note(ru-ru,SQL.90).gifВажно!
Хотя это ограничение введено в SQL Server 2005, оно также применяется, если значение режима обратной совместимости равно 80.

CREATE INDEX

ALTER INDEX

DROP INDEX

DBCC DBREINDEX

ALTER PARTITION FUNCTION

DROP TABLE

ALTER TABLE при использовании для:

  • Добавления, изменения или удаления столбцов.
  • Переключения секций.
  • Добавления или удаления ограничений первичного ключа или ограничений уникальности.

Применение запутывания к определениям DML-триггеров

Чтобы применить запутывание к исходному тексту инструкции CREATE TRIGGER, используется параметр WITH ENCRYPTION. Результат запутывания не виден непосредственно ни в одной системной таблице или представлении SQL Server 2005. Пользователи, не имеющие доступа к системным представлениям, системным таблицам или файлам баз данных, не смогут получить текст, подвергнутый запутыванию. Однако этот текст будет доступен привилегированным пользователям, имеющим прямой доступ к файлам баз данных. Эти пользователи могут применить обратную к запутыванию процедуру и получить исходный текст определения триггера.

Использование аргумента WITH ENCRYPTION не позволяет публиковать триггер как часть репликации SQL Server.

Параметры инструкции SET

Когда приложение ODBC подключается к SQL Server, сервер автоматически задает следующие параметры сеанса.

  • SET QUOTED_IDENTIFIER ON
  • SET TEXTSIZE 2147483647
  • SET ANSI_DEFAULTS ON
  • SET CURSOR_CLOSE_ON_COMMIT OFF
  • SET IMPLICIT_TRANSACTIONS OFF

Эти параметры улучшают совместимость приложений ODBC. Так как приложения, использующие DB-Library, обычно не задают эти параметры, триггеры следует проверять с указанными выше параметрами SET, установленными в ON и OFF. Это гарантирует, что триггеры будут правильно работать независимо от того, какие параметры конкретное соединение задаст при вызове триггера. Если для работы триггера требуется конкретное значение одного из этих параметров, инструкцию SET следует выполнить в начале триггера. Она сохраняет силу только до завершения триггера; после этого восстанавливается первоначальное значение.

Проверка конкретных столбцов на предмет изменений

Функция UPDATE() позволяет узнать, привела ли инструкция INSERT или UPDATE к изменению конкретного столбца таблицы. Она возвращает TRUE при присвоении значения столбцу.

ms190227.note(ru-ru,SQL.90).gifПримечание.
Так как инструкция DELETE не позволяет удалить конкретное значение столбца, предложение IF UPDATE() этой инструкцией не поддерживается.

Кроме того, для получения сведений о том, какие столбцы таблицы были изменены при помощи инструкции INSERT или UPDATE, можно использовать функцию COLUMNS_UPDATED. Чтобы указывать проверяемые столбцы, при выполнении этой функции используется целочисленная битовая маска. Дополнительные сведения см. в разделе CREATE TRIGGER.

Примеры

А. Использование предложения IF UPDATE() для проверки данных на предмет изменений

Следующий код создает триггер INSERT с именем my_trig для таблицы my_table и проверяет, был ли изменен столбец b какими-либо операциями INSERT.

CREATE TABLE my_table*
(a int NULL, b int NULL)
GO

CREATE TRIGGER my_trig
ON my_table
FOR INSERT
AS
IF UPDATE(b)
   PRINT 'Column b Modified'
GO

Б. Использование функции COLUMNS UPDATED для проверки данных на предмет изменений

В следующем примере выполняется то же самое, что и в предыдущем, с использованием предложения COLUMNS_UPDATED().

CREATE TRIGGER my_trig2
ON my_table
FOR INSERT
AS
IF ( COLUMNS_UPDATED() & 2 = 2 )
   PRINT 'Column b Modified'
GO

Отложенное разрешение имен

Триггеры DML могут ссылаться на таблицы, не существующие в момент создания триггера. Это действие называется отложенным разрешением имен. Дополнительные сведения об отложенном разрешении имен см. в разделе Отсроченное разрешение и компиляция имен.

ms190227.note(ru-ru,SQL.90).gifПримечание.
Если объект, на который ссылается DML-триггер, будет удален или переименован, при попытке выполнить триггер будет возвращена ошибка. Однако если объект, на который ссылается DML-триггер, будет заменен одноименным объектом, триггер можно будет выполнить, не создавая его заново. Например, если триггер trig1 ссылается на таблицу test1, которую мы удаляем и заменяем другой таблицей с именем test1, триггер trig1 будет ссылаться на новую таблицу.

Возвращаемые результаты

Рекомендуется не возвращать из DML-триггеров никаких результатов. В противном случае в каждом приложении, поддерживающем изменение таблицы триггера, нужно будет реализовать специальные средства обработки возвращаемых результатов. Чтобы предотвратить возврат каких-либо результатов из DML-триггера, не включайте в определение триггера ни инструкции SELECT, ни операции присваивания значений переменным. Если присвоить значение переменной в триггере необходимо, выполните перед триггером инструкцию SET NOCOUNT, чтобы предотвратить возврат каких-либо результирующих наборов.

ms190227.note(ru-ru,SQL.90).gifВажно!
Возможность возвращать результирующие наборы из триггеров будет удалена в следующей версии SQL Server. Не используйте в разрабатываемых приложениях триггеры, которые возвращают результирующие наборы, и запланируйте изменение приложений, которые сейчас используют их. Чтобы триггеры не возвращали результирующие наборы в SQL Server 2005, присвойте значение 1 параметру Параметр disallow results from triggers. В будущей версии SQL Server значение этого параметра будет 1 по умолчанию.

См. также

Другие ресурсы

CREATE TRIGGER (Transact-SQL)
SELECT (Transact-SQL)
SET (Transact-SQL)

Справка и поддержка

Получение помощи по SQL Server 2005

Журнал изменений

Версия Журнал
Изменения
  • Заголовок «Шифрование определений DML-триггеров» заменен на «Применение запутывания к определениям DML-триггеров».