Wykład 5 funkcje i procedury pamiętane widoki (perspektywy) wyzwalacze 1
Funkcje i procedury pamiętane Następujące polecenie tworzy zestawienie zawierające informację o tym ilu jest na naszej hipotetycznej uczelni studentów, a ile studentek. SELECT PlecSt(plec) AS "Plec studenta", count(*) AS "Liczba" FROM studenci GROUP BY plec; Odpowiedzią jest następująca tabela: Plec studenta Liczba ============= ====== Studentka 45 Student 71 2
W poleceniu tym pojawiła się tzw. funkcja pamiętana. Język SQL umożliwia pamiętanie wraz z danymi (w jednej z systemowych tablic bazy) funkcji i procedur definiowanych przez użytkowników systemu. Funkcje i procedury pamiętane są związane z bazą, a nie z aplikacją. Mogą być wykorzystywane przez różne aplikacje mające dostęp do bazy. Dalej podano przykład ciągu poleceń SQL, za pomocą których zdefiniowano funkcję PlecSt. CREATE FUNCTION PlecSt(IN p char(1)) RETURNS char(10) begin declare plec char(10); if p='k' then set plec='studentka' else set plec='student' end if; return(plec) end 3
Sposoby wprowadzenia do bazy danych funkcji lub procedury pamiętanej, w większości systemów zarządzania bazami danych, to albo wykonanie za pomocą interakcyjnego klienta bazy skryptu tworzącego funkcję lub procedurę pamiętaną, albo skorzystanie z odpowiedniej opcji programu wspomagającego administrowanie bazą. W systemach serii Sybase SQL jest to program o nazwie Sybase Center (scview.exe). Następne plansze pokazują kolejne kroki procesu definiowania przykładowej procedury wykladowcy za pomocą programu Sybase Center. 4
5
6
7
2014-05-30 19:31 BD_1_W5 8
9
10
11
12
Oprócz omówionych wcześniej funkcji zagregowanych i funkcji pamiętanych w systemie zarządzania bazą danych wykorzystującym język SQL istnieje zawsze pewna liczba funkcji wbudowanych. Umożliwiają one wykonywanie najczęściej spotykanych w zastosowaniach praktycznych operacji na danych. Następujące przykładowe polecenie pozwala znaleźć informację o liczbie pracowników uczelni zatrudnionych na poszczególnych stanowiskach oraz o ich zarobkach minimalnych, średnich i maksymalnych. SELECT stanowisko AS "Stanowisko", count(*) AS "Liczba zatr.", min(wynagrodzenie) AS "Min. placa zl", floor(avg(wynagrodzenie)) AS "Sr. placa zl", max(wynagrodzenie) AS "Max. placa zl" FROM pracownicy GROUP BY stanowisko ORDER BY stanowisko DESC; 13
W poleceniu tym użyto funkcji floor która zaokrągla argument do najbliższej liczby całkowitej o wartości nie większej niż wartość argumentu. Funkcja floor nie jest funkcją agregującą. 700.00 14
Polecenie: SELECT nazwisko_imie(max(nazwisko), max(imie)) AS "Nazwisko i Imie", rejestr.kurs AS "Kurs", max(num_zalicz) AS "Licz. zal.", min(punkty) as "Min. ocena", ceiling(avg(punkty)) AS "Sr. ocena", max(punkty) AS "Max. ocena" FROM studenci KEY JOIN rejestr, punkty where rejestr.num_stud = punkty.num_stud GROUP BY rejestr.num_stud, rejestr.kurs ORDER BY "Nazwisko i imie", kurs pozwala sporządzić zestawienie liczby zaliczeń poszczególnych studentów z poszczególnych przedmiotów, minimalnych, średnich i maksymalnych uzyskanych ocen. Funkcja pamiętana nazwisko_im zwraca połączenie zawartości dwóch kolumn znakowych. Funkcja ceiling jest zdefiniowana w SQL - zaokrągla argument do najbliższej liczby całkowitej nie mniejszej niż wartość argumentu. 15
Fragment odpowiedzi na to zapytanie ma postać: 16
Funkcja nazwisko_imie jest zdefiniowana jako: CREATE FUNCTION nazwisko_imie(in nazw char(25), IN im char(25)) RETURNS char(51) begin declare full_name char(51); set full_name=trim(nazw) ' ' trim(im); return(full_name) end Można ją utworzyć w bazie danych wykorzystując w tym celu program do interakcyjnego dostępu dbisqlc umieszczając w polu edycyjnym powyższy skrypt. 17
18
19
1. Definicja procedury dopisującej do tabeli studenci nowego studenta: create procedure nowy_student(in nowy_num integer, IN nowy_nazw char(25), IN nowy_imie char(25), IN nowy_plec char(1)) begin insert into DBA.studenci (num_stud, nazwisko, imie, plec) values (nowy_num, nowy_nazw, nowy_imie, nowy_plec); end Przykładowe wywołanie tej procedury ma postać: call nowy_student(90111, Zagłoba, Onufry, M ); commit; 20
2. Dopisywanie nowego studenta do tabeli studenci do kolumny plec wstawia M lub K w zależności od ostatniej litery imienia create procedure "DBA".nowy_student_1(in nowy_num integer,in nowy_nazw char(25), in nowy_imie char(25)) begin declare pplec char(1); if substr(nowy_imie,length(nowy_imie),1)='a' or substr(nowy_imie,length(nowy_imie),1)='a' then set pplec='k' else set pplec='m' end if; insert into "DBA".Studenci(num_stud,nazwisko,imie,plec) values(nowy_num,nowy_nazw,nowy_imie,pplec) end 21
3. Odczyt danych przykład procedury create procedure srednia(in nr_st integer, OUT sr_oc DECIMAL(12,2)) begin select avg(punkty) into sr_oc from "DBA".Punkty where num_stud=nr_st; end i jej użycie create variable sred NUMERIC(12,2); call srednia(86004, sred); select sred as "Srednia ocena"; 22
23
4.. Inna wersja procedury dopisującej nowego studenta do tabeli studenci: create procedure nowy_stud1(in nowy_nazw char(25), IN nowy_imie char(25), IN nowy_plec char(1)) begin insert into DBA.studenci (nazwisko, imie, plec) values (nowy_nazw, nowy_imie, nowy_plec); end Przykładowe wywołanie tej procedury: call nowy_stud1( Bachleda, Klimek, M ); commit; Jaki warunek musi być umieszczony w definicji tabeli studenci? 24
S T U D E N C I n u m _ s tu d n a z w is k o im ie a d re s d a ta _ u r p le c P R A C O W N IC Y n u m _ p ra c n a z w is k o _ p ra c im ie _ p ra c a d re s te le fo n _ d o m s ta n o w is k o w y n a g ro d z e n ie n r_ p o k o ju P U N K T Y n u m _ s tu d k u r s n u m _ z a lic z p u n k ty R E J E S T R n u m _ s tu d k u rs s e k c ja P O K O J E n r_ p o k o ju ty p p o je m n o s c Z A L IC Z E N IA k u rs n u m _ z a lic z w a g a k o m e n ta rz d a ta K U R S Y k u rs w s p o lc z y n n ik lic z _ g o d z in k o m e n ta rz S E K C J A k u rs s e k c ja n u m _ p ra c L A B O R A T O R IA k u rs la b o ra to r iu m G R U P Y k u rs s e k c ja d z ie n c z a s lic z _ g o d z in n r_ p o k o ju 25
- % Tworzenie tablic % - tablica Studenci ------------------------------- CREATE TABLE Studenci ( num_stud integer NOT NULL DEFAULT AUTOINCREMENT, nazwisko char(25) NOT NULL, % nazwisko stu imie char(25), adres char(40), data_ur date, % data urodzenia plec char(1) NOT NULL CHECK (plec in ('M', 'K', 'm', 'k')), PRIMARY KEY (num_stud)); % Tworzenie indeksu NazwiskaStud - kolejnosc % alfabetyczna studentow CREATE INDEX NazwiskaStud on Studenci(nazwisko, imie); 26
5. Inny przykład funkcji, która wartość w kolumnie plec tabeli studenci zwraca w postaci napisu Dziewczyna albo Chłopak : 27
28
6. Inna procedura: create procedure plec1(in nazw_stud char(25), OUT plec_stud char(12)) begin declare p_stud char(1); select plec into p_stud from studenci where nazwisko = nazw_stud; case p_stud when K then set plec_stud = Dziewczyna when M then set plec_stud = Chłopak else set plec_stud = Nieznana end case; end i przykład jej wywołania: create variable plec_stud char(1); call plec1( Gagarin, plec_stud); select plec_stud as Chłopak? ; 29
7. Procedura, która pozwala odczytać wykaz nazwisk wykładowców prowadzących zajęcia ze studentem o nazwisku podanym jako parametr 30
i jej wywołanie: 3 1
Widoki Tabele wirtualne. Przykład: create view "dba".wykladowcy(student,wykladowca,pokoj) as select nazwisko, imie_prac ' ' nazwisko_prac,nr_pokoju from "dba".pracownicy key join "dba".sekcja key join "dba".rejestr key join "dba".studenci i użycie, np. select * from "DBA".wykladowcy where student = 'ADAMS' order by wykladowca 32
33
34
35
36
37
Korzyści wynikające ze stosowania widoków: - wygoda - ukrywanie efektów normalizacji - ograniczanie danych dostępnych dla użytkowników - tworzenie warstwy abstrakcji 38
Wyzwalacze Wyzwalacze są związane z określonymi tablicami bazy danych. Są one wywoływane ( zapalane ) automatycznie zawsze wtedy, gdy wiersze odpowiedniej tablicy są wstawiane, poprawiane lub kasowane. Wyzwalacze nie mają parametrów i nie mogą być wywoływane za pomocą instrukcji CALL. Z wyzwalacza można wywoływać procedury oraz zapalać inne wyzwalacze. Wyzwalaczy używa się wszędzie tam, gdzie nie wystarczą warunki integralności bazy wbudowane podczas definiowania schematu bazy. Często konieczne jest wymuszenie bardziej złożonego badania warunków spójności. Wyzwalacze są wykonywane jeżeli pozwalają na to uprawnienia właściciela odpowiedniej tabeli. Wyzwalacz może modyfikować wiersze w tabeli wtedy kiedy nie może tego wykonać bezpośrednio użytkownik. 39
Wyzwalacze definiuje się dla następujących zdarzeń: INSERT - wyzwalacz jest wywoływany zawsze wtedy, gdy do tabeli z nim związanej wstawiany jest nowy wiersz, DELETE wtedy, gdy wiersz w odpowiedniej tabeli jest kasowany, UPDATE gdy wiersz jest aktualizowany, UPDATE OF lista_kolumn wtedy gdy wiersz został poprawiony tak, że zmieniły się wartości w kolumnach wymienionych na liście. Wyzwalacze można definiować jako wierszowe albo rozkazowe. Wyzwalacze wierszowe mogą działać przed (BEFORE) albo po (AFTER) modyfikacji przez wstawianie, poprawianie lub kasowanie wiersza. Wyzwalacze rozkazowe są wykonywane po wykonaniu całej operacji. Jeżeli pojawi się błąd podczas wykonywania wyzwalacza operacja, która go zapaliła kończy się niepowodzeniem. 40
Do tworzenia wyzwalaczy służy polecenie create trigger. Usuwanie wyzwalacza z bazy następuje po wydaniu polecenia drop trigger nazwa. Poprawić definicję wyzwalacza można za pomocą polecenia alter trigger... Wewnątrz wyzwalacza nie można używać poleceń commit ani rollback. Do przechowywania wyzwalaczy w bazie służą tabele SYS.TRIGGERS oraz SYS.TRIGGER. 41
42
43
44
45
46
47
48
Przykłady: 1. Wyzwalacz wierszowy dla wstawiania nowego wiersza create trigger spr_dat_ur after insert on studenci referencing new as nowy_student for each row begin declare blad_uzytkownika exception for SQLSTATE 99999 ; if nowy_student.data_ur > January 1, 1981 then signal blad_uzytkownika; end if; end 49
2. Wyzwalacz wierszowy dla usuwania wiersza create trigger usun_stud before delete on studenci referencing old as stary for each row begin declare blad_usuwania exception for sqlstate '99999'; if stary.num_stud not in (10077, 10078, 23001) then signal blad_usuwania; end if; end 50
3. Wyzwalacz wierszowy dla poprawiania wiersza create trigger popraw after update on studenci referencing new as po old as przed for each row begin declare blad_popr exception for sqlstate '99999'; if przed.data_ur<po.data_ur then signal blad_popr; end if; end 51
4. Wyzwalacz wierszowy - wstawia wiersz z kolejnym, unikalnym identyfikatorem create trigger "dba".setidstud after insert order 1 on "DBA".studenci referencing new as nowa for each row begin if nowa.num_stud is NULL then set nowa.num_stud = 1 + (select max(num_stud) from "DBA".studenci); end if; end 52