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