Опубликован: 11.12.2006 | Доступ: свободный | Студентов: 5821 / 381 | Оценка: 4.42 / 3.86 | Длительность: 57:15:00
Лекция 22:

Создание и использование триггеров

Создание триггера INSTEAD OF

Триггер INSTEAD OF позволяет вам управлять тем, что происходит, когда выполняются функции INSERT, UPDATE или DELETE. Триггер INSTEAD OF используется в первую очередь при модификации объединенного представления (union view). Обычно объединенные представления недоступны для модификации, поскольку SQL Server "не знает", какую базовую (underlying) таблицу или таблицы нужно модифицировать. Для обхода этой ситуации вы определяете по данному представлению триггер INSTEAD OF, позволяющий модифицировать базовые (underlying) таблицы. Рассмотрим один пример. Следующие операторы T-SQL создают представление под именем TitlesByAuthor со ссылкой на таблицы authors, titles и titleauthor. (О создании представлений см. "Создание и использование представлений" .)

USE pubs
GO

CREATE   VIEW TitlesByAuthor
AS
SELECT   authors.au_id, authors.au_lname, titles.title
FROM     authors INNER JOIN
           titleauthor ON authors.au_id = titleauthor.au_id INNER JOIN
    titles ON titleauthor.title_id = titles.title_id 
GO

Теперь после создания представления мы используем следующий набор T-SQL для вывода всех строк (они также показаны здесь), отвечающих критериям данного представления:

USE pubs
GO

SELECT *
FROM   TitlesByAuthor
GO

au_id             au_lname           title
————— ——————— —————————————————————
238-95-7766     Carson             But Is It User Friendly?
724-80-9391     MacFeather         Computer Phobic AND Non-Phobic Individuals:
756-30-7391     Karsen             Computer Phobic AND Non-Phobic Individuals:
267-41-2394     O’Leary            Cooking with Computers:
724-80-9391     MacFeather         Cooking with Computers: 
486-29-1786     Locksley           Emotional Security: A New Algorithm 
648-92-1872     Blotchet-Halls       Fifty Years in Buckingham Palace Kitchens
899-46-2035     Ringer             Is Anger the Enemy?
998-72-3567     Ringer             Is Anger the Enemy? 
998-72-3567     Ringer             Life Without Fear 
486-29-1786     Locksley           Net Etiquette 
807-91-6654     Panteley           Onions, Leeks, and Garlic: 
172-32-1176       White              Prolonged Data Deprivation: Four Case Studies
427-17-2319     Dull               Secrets of Silicon Valley
846-92-7186     Hunter             Secrets of Silicon Valley
712-45-1867     del Castillo       Silicon Valley Gastronomic Treats
274-80-9391     Straight           Straight Talk About Computers
267-41-2394     O’Leary            Sushi, Anyone?
472-27-2349     Gringlesby         Sushi, Anyone?
672-71-3249     Yokomoto           Sushi, Anyone?
213-46-8915     Green              The Busy Executive’s Database Guide
409-56-7008     Bennet             The Busy Executive’s Database Guide
722-51-5454     DeFrance           The Gourmet Microwave
899-46-2035     Ringer             The Gourmet Microwave
213-46-8915     Green              You Can Combat Computer Stress!


(25 row(s) affected)

Если вы попытаетесь удалить из этого представления строку, в которой значение колонки au_lname равно Carson, то появится следующее сообщение:

Server: Msg 4405, Level 16, State 1, Line 1 View or function 'TitlesByAuthor' is not updatable 
because the FROM clause names multiple tables. (Представление или 
функция 'TitlesByAuthor' недоступна для модифицирования, 
поскольку предложение FROM ссылается names на несколько таблиц)

Чтобы обойти эту ситуацию, мы создадим для операции удаления триггер INSTEAD OF. Следующий набор операторов T-SQL создает триггер INSTEAD OF с именем Delete_It:

Примечание. В следующем наборе операторов не происходит реального удаления строки из таблицы authors базы данных pubs. В целях данного примера здесь просто переименовывается строка.
USE pubs
GO
 
IF EXISTS   (SELECT     name 
                 FROM       sysobjects 
                 WHERE      name = 'Delete_It' AND 
                              type = 'TR') 
DROP TRIGGER Delete_It 
GO 
 
CREATE TRIGGER Delete_It 
ON TitlesByAuthor 
INSTEAD OF DELETE 
AS 
PRINT       'Row from authors before deletion...' 
SELECT      au_id, au_lname, city, state 
FROM        authors 
WHERE       au_lname = 'Carson' 
PRINT       'Deleting row from authors...' 
UPDATE      authors 
SET           au_lname = 'DELETED' 
WHERE       au_lname = 'Carson' 
PRINT       'Verifying deletion...' 
SELECT      au_id, au_lname, city, state 
FROM        authors 
WHERE       au_lname = 'Carson' 
GO

И если теперь мы введем операторы для удаления строки Carson из этого представления, то произойдет активизация триггера INSTEAD OF и мы получим следующие выходные результаты:

Row from authors before deletion...  (Строка из authors перед удалением)
au_id           au_name             city          state
-----------------------------------------------------------------------------------
238-95-7766   Carson                Berkeley         CA

(1 row(s) affected)
Deleting row from authors...            (Удаление строки из authors)
(1 row(s) affected)
Verifying deletion...:                       (Проверка удаления)
au_id           au_name             city             state
-----------------------------------------------------------------------------------

(0 row(s) affected)