Макеты страниц
Распознанный текст, спецсимволы и формулы могут содержать ошибки, поэтому с корректным вариантом рекомендуем ознакомиться на отсканированных изображениях учебника выше
Также, советуем воспользоваться поиском по сайту, мы уверены, что вы сможете найти больше информации по нужной Вам тематике
4.3.3 Триггер, обновляющий представление
Обновление представлений
в ряде случаев может оказаться затруднительным. Одна из таких проблем касается
представлений, созданных при помощи операции соединения: как правило, СУБД не
способна обновлять таблицы, лежащие в основе таких представлений. Однако, зная
специфику конкретного приложения, можно определить, как следует интерпретировать
запрос на обновление соединенного представления.
Рассмотрим представление
Customerlnterests, определенное ранее в
этой главе на стр. 77. Оно содержит строки таблиц CUSTOMER и ARTIST, соединенные через
таблицу пересечения. Столбцу CUSTOMER.Name дан псевдоним Customer, а столбцу ARTIST.Name — Artist.
Запрос на изменение
имени клиента в представлении Customerlnterests можно интерпретировать
как запрос на изменение столбца Name в таблице CUSTOMER. Такой запрос, однако,
может быть обработан лишь в том случае, если это имя является уникальным в
таблице CUSTOMER. В противном случае
невозможно будет определить, какую из строк следует обновлять.
В листинге 4.3 приведен
текст замещающего триггера, который обновляет имя клиента, если это имя
является уникальным в базе данных. Вместо того чтобы подсчитывать количество
строк с данным именем клиента и выполнять обновление только в том случае, если
такая строка всего одна, триггер обусловливает обновление ключевым словом NOT EXISTS. Такая конструкция
триггера позволяет Oracle оптимизировать SQL-оператор и приводит к
лучшей производительности.
Листинг 4.3.
CREATE OR REPLACE TRIGGER CustomerlnterestsJJpdate INSTEAD
OF UPDATE ON Customerlnterests
FOR EACH ROW
BEGIN
UPDATE CUSTOMER C1 SET C1.Name = :new.Customer
WHERE C1.Name =
:old.Customer
AND NOT EXISTS (SELECT * FROM CUSTOMER C2 WHERE C2.Name = C1.Name
AND C2.CustomerlD <> C1.CustomerlD);
END;
/