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.