Instrukcja Select

Transkrypt

Instrukcja Select
Bazy danych – zadania lista nr 11
Wyzwalacze
Wyzwalacze są szczególnym rodzajem procedur przechowywanych na serwerze.
Wyzwalacze są obiektami bazy danych – ich nazwa musi być, unikalna w obrębie całej bazy.
Wyzwalacze pomagają zachować spójność danych.
Wyzwalacze tworzone są na poziomie tabeli.
Wyzwalacze są procedurami związanymi z operacjami wykonywanymi na tabelach – dodaniem nowych
rekordów (INSERT), usuwaniem rekordów (DELETE) i aktualizowaniem (UPDATE).
Są dwa rodzaje wyzwalaczy:
AFTER – wykonywany po jednej z operacji: INSERT, UDATE, DELETE. Wyzwalacz typu
AFTER może być zdefiniowany tylko dla tabel (nie dla widoków)
INSTEAD OF – wykonywane zamiast operacji dla których zostały zdefiniowane. Wyzwalacz
typu INSTEAD OF może być zdefiniowany dla tabel i widoków
52. Definiowanie wyzwalaczy typu AFTER
CREATE TRIGGER nazwa_wyzwalacza
ON nazwa_tabeli
AFTER {INSERT|UPDATE|DELETE}
AS
polecenia języka SQL
Wyzwalacze AFTER są wywoływane po wprowadzeniu zmian, a zatem również po przetworzeniu
wszystkich ograniczeń niższego poziomu. Najpierw przetwarzane są ograniczenia podstawowe (CHECK,
UNIQUE i kluczy podstawowych), później ograniczenie FOREIGN KEY gwarantujące spójność kilku
tabel, a dopiero na końcu wykonywany jest wyzwalacz. I tak np. przy próbie dodania wiersza, który nie
spełnia jednego z ograniczeń (np. CHECK) nie dojdzie do sytuacji wykonania wyzwalacza.
Przykład – załóżmy, że konieczne jest rejestrowanie zmian (w dodatkowej tabeli), jakie wprowadzono w tabeli Olejki,
potrzebne jest utworzenie takiej tabeli, a także dodanie wyzwalacza do instrukcji UPDATE w tabeli Olejki
CREATE TABLE KiedyZmiany
(
id int identity(1,1) primary key,
Opis varchar(30),
IleRekordow int,
Data datetime
)
CREATE TRIGGER ZapiszZmiany ON Olejki
AFTER UPDATE
AS
INSERT INTO KiedyZmiany(Opis,IleRekordow,Data)
VALUES('Aktualizacja',@@ROWCOUNT,GetDate())
W powyższym przykładzie każda modyfikacja w tabeli Olejki, będzie miała swój skutek z tabeli
KIEDYZMIANY: zapisana zostanie liczba zaktualizowanych wierszy (zmienna globalna @@ROWCOUNT),
oraz aktualna data systemowa.
Przygotowała: mgr Aneta Klaczyńska
1/1
Bazy danych – zadania lista nr 11
Wykonanie instrukcji:
UPDATE Olejki
SET NazwaOlejku='Pewna nowa nazwa'
where IDOlejku>48
spowoduje dodanie do tabeli KIEDYZMIANY następującego wiersza:
Funkcja Update() – w połączeniu z akcją UPDATE lub INSERT. Pozwoli ustalić które pole było
aktualizowane. W poniższym przykładzie tabela KIEDYZMIANY, oprócz dotychczas zapisywanych
informacji, będzie również przechowywała nazwę aktualizowanego pola.
CREATE TRIGGER ZapiszZmiany ON Olejki
AFTER UPDATE
AS
DECLARE @ILE INT
SET @ILE=@@ROWCOUNT
if UPDATE(NazwaOlejku)
INSERT INTO KiedyZmiany(Opis,IleRekordow,Data)
VALUES('NazwaOlejku',@ILE,getdate())
if UPDATE(NazwaLacinska)
INSERT INTO KiedyZmiany(Opis,IleRekordow,Data)
VALUES('NazwaLacinska',@ILE,getdate())
Każda tabela może mieć przypisanych kilka wyzwalaczy. Może jednak wystąpić sytuacja w której nie
wiadomo będzie w jakiej kolejności będą wywoływane. Procedura sp_settriggerorder pozwoli ustalić,
który wyzwalacz ma być wywołany jako pierwszy, który ostatni. Niestety nie ma możliwości ustalenia
kolejności pozostałych wyzwalaczy. Parametrami procedury są: nazwa wyzwalacza, jedno ze słów:
FIRST, LAST , NONE oraz akcja z którą będzie skojarzony (INSERT, UPDATE lub DELETE).
sp_settriggerorder nazwa_wyzwalacza, FIRST, UPDATE
Przygotowała: mgr Aneta Klaczyńska
2/2
Bazy danych – zadania lista nr 11
53. Tabele inserted i deleted
W przypadku wyzwalaczy, polecenie modyfikujące przechowuje w tabelach inserted i deleted,
informacje o wykonanej operacji. Tabele te, mają taką samą strukturę i nazwy kolumn, jak tabele, które
były modyfikowane. Np. przy UPDATE tabela deleted będzie przechowywała stare wiersze (przed
modyfikacją), a tabela inserted wiersze po modyfikacji.
Poniższa tabela przedstawia informacje o przechowywanych wierszach, gdy wyzwalacz został
wykonany w wyniku wywołania więcej niż jednego polecenia modyfikującego.
Ustalenie, która akcja wykonuje wyzwalacz
Polecenie
Zawartość tabeli inserted
Zawartość tabeli deleted
INSERT
Dodane wiersze
Pusta
UPDATE
Nowe wiersze
Stare wiersze
DELETE
Pusta
Usunięte wiersze
54. Definiowanie wyzwalaczy typu INSTEAD OF
CREATE TRIGGER nazwa_wyzwalacza
ON nazwa_tabeli
INSTEAD OF {INSERT|UPDATE|DELETE}
AS
polecenia języka SQL
Po napotkaniu polecenia wywołującego wyzwalacz, SQL wykonuje zamiast niego, operacje zawarte w
wyzwalaczu, a dopiero później, sprawdzane są pozostałe ograniczenia (CHECK itp.) – w wyzwalaczu
typu AFTER jest odwrotnie.
55. Zadanie – Załóżmy, że mamy dwie tabele: KLIENCI i KLIENCIZAMÓWIENIA. Pierwsza z nich zawiera
informacje o klientach m.in. IdKlienta, nazw i limit na zamówienia. Druga zawiera konkretne
informacje dotyczące zamówień (IdZamowienia, IdKlienta, Kwota).
CREATE TABLE Klienci
(
IdKlienta int IDENTITY(1,1) PRIMARY KEY,
NazwaKlienta varchar(20),
KwotaLimitu int
)
INSERT INTO Klienci (NazwaKlienta,KwotaLimitu)VALUES('Firma AAA',10000)
INSERT INTO Klienci (NazwaKlienta,KwotaLimitu)VALUES('Firma BBB',5000)
INSERT INTO Klienci (NazwaKlienta,KwotaLimitu)VALUES('Firma CCC',30000)
CREATE TABLE KlienciZamowienia
(
IdZamowienia int IDENTITY(1,1) PRIMARY KEY,
IdKlienta int FOREIGN KEY REFERENCES
Klienci(IdKlienta),
Kwota int CHECK(Kwota>0),
)
Przygotowała: mgr Aneta Klaczyńska
3/3
Bazy danych – zadania lista nr 11
INSERT
INSERT
INSERT
INSERT
INTO
INTO
INTO
INTO
KlienciZamowienia(IdKlienta,Kwota)
KlienciZamowienia(IdKlienta,Kwota)
KlienciZamowienia(IdKlienta,Kwota)
KlienciZamowienia(IdKlienta,Kwota)
VALUES
VALUES
VALUES
VALUES
(1,2300)
(2,300)
(1,8300)
(3,2300)
Potrzebne jest zabezpieczenie, które nie pozwoli dokonać klientowi zamówienia powyżej
przydzielonego limitu. Zabezpieczenie takie, może i zazwyczaj wykonuje aplikacja kliencka, ale można
jezorganizować za pomocą wyzwalacza.
CREATE TRIGGER OgraniczenieLimit ON KlienciZamowienia
AFTER INSERT,UPDATE
AS
if @@ROWCOUNT=0
RETURN
ELSE
BEGIN
IF EXISTS
(
SELECT *
FROM Klienci K,inserted I
WHERE (K.IdKlienta=I.IdKlienta) and (K.KwotaLimitu<I.Kwota)
)
BEGIN
ROLLBACK TRANSACTION
RAISERROR ('KWOTA LIMITU PRZEKROCZONA',15,1)
END
END
Wykonanie instrukcji:
INSERT INTO KlienciZamowienia(IdKlienta,Kwota) VALUES (1,15000)
Nie zakończy się sukcesem (polecenie ROLLBACK – wycofało transakcje) i zostanie przekazany do
strony klienta komunikat (RAISERROR – przekazanie do strony klienta komunikatu i kodu błędu):
Przygotowała: mgr Aneta Klaczyńska
4/4