Программирование >>  Программирование баз данных 

1 ... 156 157 158 [ 159 ] 160 161 162 ... 346


вызвать откат (например, из-за того, что вводится в действие сложное правило обеспечения целостности данных, которое невозможно реализовать с помощью ограничения), именно этот триггер должен быть предназначен для запуска в первую очередь как триггер FIRST. Это позволяет добиться того, чтобы наиболее вероятная причина отката уже осталась позади до того, как будут приложены какие-то дополнительные усилия в осуществление транзакции. Ведь чем больший объем работы будет выполнен до обнаружения условий выполнения отката, тем больше придется сделать в процессе вьшолнения отката. Поэтому, прежде чем переходить к осуществлению дальнейших действий, необходимо сделать все возможное для того, чтобы был своевременно обнаружен возможный откат.

Триггеры instead of

Безусловно, триггеры INSTEAD OF могут применяться для работы с таблицами, но обычно триггеры этого типа служат для обеспечения возможности вьшолнения операций обновления применительно к представлениям в тех обстоятельствах, в которых до сих пор такая возможность отсутствовала.

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

Триггеры INSTEAD OF, как и триггеры FOR/AFTER, подразделяются на три основные разновидности- INSERT, UPDATE и DELETE. Но в отличие от триггеров FOR/AFTER, предусмотрена возможность задавать только по одному триггеру INSTEAD OF каждого типа в расчете на одну таблицу или представление (т.е. по одному триггеру INSTEAD OF для выполнения операций вставки, обновления и удаления).

Прежде чем приступать к практическому изучению этой темы, необходимо подготовить подходящие примеры таблиц. Для этого воспользуемся следующими четырьмя таблицами (при желании, можно внести изменения в этот сценарий, чтобы использовать существующую базу данных):

CREATE TABLE dbo.Customers (

CustomerlD varchar(5) NOT NULL PRIMARY KEY , Name varchar(4 0) NOT NULL

CREATE TABLE dbo.Orders (

OrderlD int IDENTITY NOT NULL PRIMARY KEY, CustomerlD varchar(5) NOT NULL

REFERENCES Customers(CustomerlD), OrderDate datetime NOT NULL )

CREATE TABLE dbo.Products (

ProductID int IDENTITY NOT NULL PRIMARY KEY, Name varchar(40) NOT NULL, UnitPrice money NOT NULL



CREATE TABLE dbo.OrderItems (

OrderlD int NOT NULL

REFERENCES dbo.Orders(OrderlD), ProductID int NOT NULL

REFERENCES dbo.Products(ProductID), UnitPrice money NOT NULL, Quantity int NOT NULL

CONSTRAINT PKOrderltem PRIMARY KEY CLUSTERED (OrderlD, ProductID)

-- Примеры вставки строк с помощью оператора INSERT INSERT dbo.Customers

VALUES ( ABCDE, Bob s Pretty Good Garage )

INSERT dbo.Orders

VALUES (ABCDE, CURRENT TIMESTAMP)

INSERT dbo.Products

VALUES (Widget, 5.55)

INSERT dbo.Products

VALUES (Thingamaj ig, 8.88)

INSERT dbo.Orderltems

VALUES (1, 1, 5.55, 3)

Эти таблицы будут применяться во всех трех описанных ниже примерах использования триггеров INSTEAD OF.

Триггеры instead of insert

Триггер INSTEAD OF INSERT позволяет проверить данные, которые должны поступить в таблицу или представление, и принять решение о проведении каких-либо дополнительных действий с этими данными до фактического осуществления физической вставки данных. 1Сак правило, триггеры такого типа определяются применительно к представлениям, поскольку именно в представлениях от правильной подготовки данных перед фактическим осуществлением физической вставки зависит, будет ли операция вставки выполнена успешно или неудачно.

Рассмотрим, как применяются триггеры этого типа на примере обновляемого представления, а именно такого представления, которое позволит применять к нему операторы INSERT, тогда как перед вводом в действие триггеров INSTEAD OF INSERT такая возможность была исключена.

В данном случае будет создано представление, позволяющее показать, какие проблемы возникают при обновлении, а затем с помощью этого представления будет продемонстрировано, как устранить возникающие нарушения в работе. Рассмотрим случай, в котором осуществляется просмотр некоторых позиций заказа, но с получением более подробной информации о клиенте и товарах (убедитесь в том, что используется та же база данных, в которой были созданы образцы таблиц):

CREATE VIEW CustomerOrders vw

WITH SCHEMABINDING

SELECT o.SalesOrderlD, o.OrderDate,



od.ProductID,

р.Name,

od.OrderQty,

od.UnitPrice,

od.LineTotal FROM Sales.SalesOrderHeader AS о JOIN Sales.SalesOrderDetail AS od

ON o.SalesOrderlD = od.SalesOrderlD JOIN Production.Product AS p

ON od.ProductID = p.ProductID

В своем текущем состоянии это представление не является полностью обновляемым, поскольку в СУБД SQL Server отсутствует возможность определить, какие данные должны поступать в ту или иную таблицу. Безусловно, один из вариантов решения этой задачи мог бы предусматривать непосредственное использование операторов обновления, но в данном случае это невозможно, поскольку первичный ключ предусмотрен не для каждой таблицы. Еще более затруднительная ситуация возникает, если должна быть выполнена операция вставки (такую необходимость нельзя исключить, а способ решения этой задачи в данном случае отсутствует).

Выходом из этого положения становится применение тех средств, которые отсутствуют в базовом языке SQL; дело в том, что в возникающих сложных ситуациях требуется передать в СУБД SQL Server больше инструкций, чем могли бы предоставить простые операторы обновления и вставки. Именно в подобных обстоятельствах триггеры INSTEAD OF проявляют себя просто блестяще.

Рассмотрим пример выборки данных о заказе:

SELECT *

FROM CustomerOrders vw WHERE OrderlD = 1

В результате происходит получение той единственной строки, которая была введена в процессе подготовки примера:

Bobs Pretty Good Garage ... 1... 2006-04-13 05:14:22.780.. .1...Widget. ..3...5.55

Теперь, исключительно для проверки того, что выполнить вставку данных с помощью созданного выше представления невозможно, попытаемся применить оператор INSERT для ввода в базу данных новой позиции заказа:

INSERT INTO CustomerOrders vw (

OrderlD,

OrderDate,

ProductID,

Quantity,

UnitPrice

VALUES (

4998-04-06 ,

6 . 00

Как и можно было предположить, эта попытка оканчивается неудачей: Server: Msg 4405, Level 16, State 2, Line 1

View or function CustomerOrders vw is not updatable because the modification affects multiple base tables.



1 ... 156 157 158 [ 159 ] 160 161 162 ... 346

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика