Zadania do wykonania Plik

Transkrypt

Zadania do wykonania Plik
Zadania do wykonania
Laboratorium IBM DB2 - procedury
-1-
1. Dodatkowe informacje
1.1.
1.2.
1.3.
Każde zdanie SQL musi być zakończone średnikiem (;).
Zdanie CREATE PROCEDURE musi być zakończone symbolem “małpa” (@ po słowie END).
Dana procedura nie może być modyfikowana np. przez zdanie ALTER PROCEDURE, a jedynie przez
zmianę jej definicji (najpierw DROP PROCEDURE nazwa a potem ponownie CREATE PROCEDURE).
2. Struktura używanej bazy danych
Department
Employee
Org
Project
Sales
Staff
Pracownik
Zespol
Temat
Dochod
(deptno, deptname, mgrno, location)
(midinit, lastname, workdept, hiredate, job, birthdate, salary, bonus, comm, ...)
(deptnumb, deptname, manager, division)
(projno, projname, deptno, respemp)
(sales_date, sales_person, region, sales)
(id, name, dept, job, years, salary, comm)
(nr_prac, nazwisko, nr_zesp)
(nr_zesp, nazwa_zesp, lokalizacja, nr_prac_kz)
()
(nr_prac, kwota, premia, nr_tem, data)
3. Czynności wstępne
3.1.
Zalogować się do systemu Windows (np. jako użytkownik vpc z hasłem Kowalski1).
3.2.
Uruchomić PUTTY (na pulpicie) i połączyć się z adresem wskazanym przez prowadzącego lub uruchomić
wskazaną maszynę wirtualną.
Połączyć się z serwerem jako użytkownik db2labx (hasło: db2labx), gdzie x jest numerem sekcji lub jako
użytkownik db2admin.
Sprawdzić czy istnieje instancja na serwerze (komenda db2ilist). Jeżeli zachodzi potrzeba wystartować
instancję poleceniem db2start.
Sprawdzić istniejące bazy danych (komenda db2 list database directory).
Jeżeli baza sample nie istnieje, utworzyć ją poleceniem db2sampl.
Połączyć się z bazą poleceniem db2 connect to sample.
Sprawdzić istniejące w bazie tabele (komenda db2 list tables).
Wyświetlić strukturę wybranej tabeli – polecenie db2 describe table nazwa.
3.3.
3.4.
3.5.
3.6.
3.7.
3.8.
3.9.
4. Zadania
4.1.
Stworzyć tabelę WORKERS o atrybutach: id integer, name varchar(20), parent int, payment decimal(6,2),
bonus decimal(6,2), salary decimal(6,2). Kluczem podstawowym jest id. Kolumna salary powinna być
generowana automatycznie jako suma kolumn payment oraz bonus:
db2 create table workers (id integer primary key NOT NULL,
..., salary decimal(6,2) GENERATED ALWAYS AS (bonus+payment));
4.2.
Stworzyć tabelę w1 o identycznej strukturze co workers, korzystając z predykatu LIKE:
db2 create table w1 LIKE workers;
4.3.
Wypełnić tabelę workers przykładowymi danymi:
1
2
Jurek
Piotr
NULL
1
5000
4000
2000
1500
Zadania do wykonania
Laboratorium IBM DB2 - procedury
4.4.
3
Adam 2
3000
1000
4
Jan
2500
1500
NULL
-2-
Uruchomić i przeanalizować działanie polecenia, wyświetlającego rekurencyjnie wszystkich przodków
Adama:
WITH temp1 (id, name, parent) AS
(
SELECT w1.id, w1.name, w1.parent
FROM workers w1, temp1 t1
WHERE w1.id = t1.parent)
UNION ALL
SELECT w.id, w.name, w.parent
FROM workers w
WHERE w.name=’ADAM’
)
SELECT * FROM temp1;
4.5.
Z platformy MOODLE skopiować, a następnie wywołać, procedurę ins znajdującą się w pliku ins.sql.
Procedura ta tworzy tabele Pracownik, Zespol, Dochod i wstawia do nich wiersze, pochodzące z już
istniejących w systemie tabel.
cp ścieżka/ins.sql .
db2 -td@ -f ./ins.sql
db2 call ins
4.6.
4.7.
Sprawdzić istniejące w bazie tabele (komenda db2 list tables).
Utworzyć procedurę o nazwie ins_tem, tworzącą i wypełniającą wartościami początkowymi tabelę temat.
W tym celu utworzyć nowy zbiór (np. o nazwie ins_tem.sql) w katalogu bieżącym.
Struktura tworzonej tabeli: nr_tem integer, nazwa_tem varchar(30), nr_prac_kt integer.
Uwagi!
• Kolumnę nazwa_tem tabeli temat należy wypełnić danymi z kolumny projname tabeli project.
• Wartości kolumny nr_tem mają być automatycznie generowane. W tym celu za specyfikacją typu kolumny
należy dodać frazę:
generated by default as identity (start with 1increment by 1)
4.8.
Schować okno Mid.Comm. – [Ctrl–O] – i utworzyć, a następnie wywołać, procedurę ins_tem znajdującą się
w pliku ins_tem.sql:
db2 -td@ -f ./ins_tem.sql
db2 call ins_tem
4.9.
Sprawdzić istniejące w bazie tabele (komenda db2 list tables) i wylistować zawartość tabeli temat:
db2 „select * from temat”
4.10. Przeczytać z katalogu sysroutines wybrane informacje o procedurze ins_tem:
db2 "select routinename, routinetype, text from sysibm.sysroutines where routinename = 'INS_TEM'"
4.11. Napisać procedurę o nazwie sel (plik sel.sql) z jednym parametrem OUT typu integer, zwracającą wartości
kolumny nr_prac tabeli Pracownik.
CREATE PROCEDURE sel
(OUT nr integer)
LANGUAGE SQL
BEGIN
SELECT ... INTO nr FROM ...;
END@
4.12. Utworzyć, a następnie wywołać, procedurę sel:
Laboratorium IBM DB2 - procedury
Zadania do wykonania
-3-
db2 -td@ -f ./sel.sql
db2 "call sel (?)"
Co się stało?
4.13. Poprawić procedurę sel, deklarując kursor kurs1, który pozwoli na wylistowanie żądanej wartości. W treści
procedury – po deklaracjach zmiennych – należy kursor zadeklarować i otworzyć poleceniami:
DECLARE kurs1 CURSOR FOR SELECT ....
OPEN kurs1;
Dodatkowo, należy wykasować z nagłówka procedury parametr OUT. Poprawioną procedurę należy
utworzyć i ponownie wykonać. Co się stało?
4.14. Jeszcze raz poprawić procedurę sel, dopisując do polecenia DECLARE CURSOR frazę WITH RETURN (przed
słowem FOR). Sprawdzić działanie procedury.
4.15. Sprawdzić, czy w ten sam sposób, co w punkcie poprzednim, można zwrócić wartości wszystkich kolumn
tabel Pracownik i Dochod (zastosować 2 kursory).
4.16. Utworzyć procedurę o nazwie sel_prac, zwracającą wszystkie informacje o pracowniku (tabela Pracownik),
którego numer podany jest parametrem procedury (typ IN). Utworzoną procedurę wywoływać:
db2 "call sel_prac(10)"
4.17. Poprawić utworzoną w poprzednim punkcie procedurę, dodając wyświetlanie komunikatu 'Brak pracownika
o tym numerze w bazie' w momencie, gdy w tabeli Pracownik nie będzie podanego parametrem numeru
pracownika. W części operacyjnej procedury należy zadeklarować poleceniem DECLARE zmienną
SQLSTATE jako CHAR(5) i 2 kursory, które posłużą do późniejszej sygnalizacji błędu poleceniem SIGNAL:
SIGNAL SQLSTATE '38000'
SET MESSAGE_TEXT='Brak ....''
Pierwszy z kursorów zadeklarować z frazą WITH RETURN:
DECLARE nazwakursora1 CURSOR WITH RETURN FOR SELECT ... FROM Pracownik WHERE ...
natomiast drugi – dla polecenia SELECT nr_prac FROM Pracownik WHERE ...bez ww. frazy.
Kursor drugi otworzyć (OPEN nazwakursora2), a następnie pobrać dane do wcześniej zadeklarowanej
zmiennej pomocniczej – FETCH FROM nazwakursora2 INTO zmiennapomocnicza.
W przypadku gdy pobranie nie powiedzie się (brak danych), należy zgłosić błąd; w przeciwnym przypadku –
wyświetlić żądane informacje na ekranie:
IF (SQLSTATE <> '00000') THEN
... zgłoszeniebłedu
ELSE
OPEN nazwakursora1;
END IF;
4.18. Napisać funkcję fun_nvl, sklejającą 2 ciągi znaków (varchar(20)) podanych parametrem. Funkcja powinna
mieć postać:
CREATE FUNCTION fun_nvl(zmienna typ, ...)
RETURNS varchar(40)
LANGUAGE SQL
RETURN (p_zm1 || p_zm2)@
4.19. Utworzyć i wykonać funkcję nvl:
db2 -td@ -f ./fun_nvl.sql
db2 "select fun_nvl('Jan', 'Kowalski') from sysibm.sysdummy1"
4.20. Utworzyć procedurę wiekowi, wypisującą nazwiska tych pracowników, którzy przekroczyli 70 rok życia. W
procedurze wykorzystać napisaną specjalnie na jej potrzeby funkcję fun_wiek, obliczającą i zwracającą
różnicę (typ integer) lat (funkcja YEAR) pomiędzy podaną parametrem datą urodzin a datą bieżącą
(CURRENT_DATE). W funkcji wykorzystać polecenie:
SELECT ... FROM sysibm.sysdummy1;
Laboratorium IBM DB2 - procedury
Zadania do wykonania
-4-
Funkcja będzie użyta w procedurze we frazie WHERE polecenia SELECT:
... WHERE fun_wiek(Employee.birthdate) > 70;
4.21. Napisać wyzwalacz (trigger) typu BEFORE o nazwie trig_del_doch zabezpieczający przed usunięciem
jakichkolwiek wierszy z tabeli dochod. Wyzwalacz powinien zgłosić błąd w przypadku, gdy zostanie
wydane polecenie DELETE dla tabeli dochod:
CREATE TRIGGER trig_del_doch
BEFORE delete ON dochod
FOR EACH ROW
SIGNAL SQLSTATE '75001' ('Nie wolno usuwać wierszy z tej tabeli')@
4.22. Utworzyć (poleceniem db2 -td@ -f ...sql) wyzwalacz i przetestować jego działanie wpisując polecenie:
db2 "DELETE FROM dochod WHERE kwota > 10000"
4.23. W celu ograniczenia zjawiska kaskadowego wyzwalania triggerów, usunąć utworzony przed chwilą trigger
poleceniem:
db2 drop trigger trig_del_doch;
4.24. Utworzyć wyzwalacz trig_upd_sal, aktualizujący kwotę wypłaty pod warunkiem, że proponowana stawka nie
przekracza 20% poprzedniej ("starej") wypłaty. W definicji triggera dodać frazy:
FOR EACH ROW
WHEN (...)
Część operacyjna triggera ma mieć postać: BEGIN ATOMIC...END@
4.23. Napisać procedurę upd_kt, aktualizującą wartości kolumny nr_prac_kt tabeli temat. Aktualizacja ma
przebiegać następująco. Dla danego tematu (nr_tem) kierownikiem tego tematu powinien zostać pracownik,
który dostał w nim (jednorazowo) maksymalną wypłatę. W procedurze wykorzystać pętlę FOR o konstrukcji:
FOR etykieta_pętli AS SELECT .....
DO
UPDATE ...
END FOR
Pętla ta jest używana tylko do przetwarzania wierszy tabel - tzn. przetwarzania każdego wiersza
zwróconego przez podaną instrukcję SELECT.