Advertisement
Guest User

Untitled

a guest
May 21st, 2019
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- ZESTAW IV
  2.  
  3. -- 5. Napisz procedurę sparametryzowaną, w której zostanie wybrany
  4. -- najlepszy student, a jego nazwisko, imię i numer albumu oraz średnia
  5. -- zostaną przekazane do środowiska wywołującego, gdzie należy wypisać
  6. -- je na ekranie. Wprowadź obsługę błędów, jeśli więcej niż jeden student
  7. -- uzyska najwyższą średnią.
  8.  
  9. CREATE OR REPLACE PROCEDURE najlepszystudent IS
  10. TYPE Stud IS RECORD (
  11.     im student.imie%TYPE,
  12.     nazw student.nazwisko%TYPE,
  13.     nr student.nralbumu%TYPE,
  14.     sr NUMBER
  15.     );
  16. najlepszy Stud;
  17. BEGIN
  18.     SELECT s.imie, s.nazwisko, s.nralbumu, AVG(o.ocena) INTO najlepszy
  19.     FROM student s
  20.     INNER JOIN ocena o ON o.id_student = s.id_student
  21.     GROUP BY s.imie, s.nazwisko, s.nralbumu
  22.     HAVING AVG(o.ocena) = (
  23.         SELECT MAX(AVG(o.ocena))
  24.         FROM student s
  25.         INNER JOIN ocena o ON o.id_student = s.id_student
  26.         GROUP BY s.imie, s.nazwisko, s.nralbumu
  27.     );
  28.     DBMS_OUTPUT.PUT_LINE(najlepszy.im || ' ' || najlepszy.sr);
  29.     EXCEPTION
  30.     WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT('ERROR');
  31. END;
  32.  
  33. BEGIN
  34.     najlepszystudent();
  35. END;
  36.  
  37. -- 6. Utworzyć funkcję, która dla podanego nazwiska i imienia prowadzącego
  38. -- (parametr), zwróci liczbę przedmiotów przez niego prowadzonych.
  39.  
  40. CREATE OR REPLACE FUNCTION liczbaprzedmiotow(im VARCHAR2, nazw VARCHAR2) RETURN NUMBER IS
  41. lprzedm NUMBER;
  42. BEGIN
  43.     SELECT COUNT(p.id_przedmiot) INTO lprzedm
  44.     FROM przedmiot p
  45.     INNER JOIN zajecia z ON z.id_przedmiot = p.id_przedmiot
  46.     INNER JOIN wykladowca w ON w.id_wykladowca = z.id_wykladowca
  47.     WHERE w.imie = im AND w.nazwisko = nazw;
  48.     RETURN lprzedm;
  49. END;
  50.  
  51. DECLARE
  52.     lprzedm NUMBER;
  53. BEGIN
  54.     lprzedm := liczbaprzedmiotow('Walenty', 'xD');
  55.     DBMS_OUTPUT.PUT_LINE('Liczba przedmiotow: ' || lprzedm);
  56. END;
  57.  
  58. -- 7. Napisać funkcje PL/SQL, która dla podanego nr albumu studenta oraz
  59. -- budynku i sali (parametry) zwróci liczbę przedmiotów, na które uczęszcza
  60. -- dany student.
  61.  
  62. CREATE OR REPLACE FUNCTION liczbazajec(nralb NUMBER, bud VARCHAR2, sala VARCHAR2) RETURN NUMBER IS
  63. lprzedm NUMBER;
  64. BEGIN
  65.     SELECT COUNT(p.id_przedmiot) INTO lprzedm
  66.     FROM zajecia z
  67.     INNER JOIN przedmiot p ON p.id_przedmiot = z.id_przedmiot
  68.     INNER JOIN sala s ON s.id_sala = z.id_sala
  69.     INNER JOIN budynek b ON b.id_budynek = s.id_budynek
  70.     INNER JOIN grupa g ON g.id_grupa = z.id_grupa
  71.     INNER JOIN student st ON st.id_grupa = g.id_grupa
  72.     WHERE b.nazwa = bud AND s.kodsali = sala AND st.nralbumu = nralb;
  73.     RETURN lprzedm;
  74. END;
  75.  
  76. DECLARE
  77.     lprzedm NUMBER;
  78. BEGIN
  79.     lprzedm := liczbazajec(121122, 'xD', 'xD');
  80.     DBMS_OUTPUT.PUT_LINE('Liczba przedmiotow: ' || lprzedm);
  81. END;
  82.  
  83. -- 8.Napisać procedurę, która zmodyfikuje typ zajęć dla podanej, jako
  84. -- parametr grupy studenckiej w zależności od jego aktualnej zawartości.
  85. -- Wykorzystaj klauzurę: L – W oraz W - Ć
  86.  
  87. CREATE OR REPLACE PROCEDURE modyfikuj(grupa VARCHAR2) IS
  88. CURSOR kursor IS
  89.     SELECT z.id_zajecia, c.nazwa
  90.     FROM zajecia z
  91.     INNER JOIN charakter c ON c.id_charakter = z.id_charakter
  92.     INNER JOIN grupa g ON g.id_grupa = z.id_grupa
  93.     WHERE g.nazwa = grupa
  94.     FOR UPDATE;
  95. BEGIN
  96.     FOR ROW IN kursor LOOP
  97.         IF ROW.nazwa = 'Laboratoria' THEN
  98.             UPDATE zajecia SET zajecia.id_charakter = 3 WHERE CURRENT OF kursor;
  99.         ELSIF ROW.nazwa = 'Wykład' THEN
  100.             UPDATE zajecia SET zajecia.id_charakter = 2 WHERE CURRENT OF kursor;
  101.         END IF;
  102.     END LOOP;
  103. END;
  104.  
  105. -- ZESTAW V
  106.  
  107. -- 1. Napisz procedurę sparametryzowaną, w której zostanie wybrany
  108. -- najlepszy student, a jego nazwisko, imię i numer albumu oraz średnia
  109. -- zostaną przekazane do środowiska wywołującego, gdzie należy wypisać
  110. -- je na ekranie. Wprowadź obsługę błędów, jeśli więcej niż jeden student
  111. -- uzyska najwyższą średnią.
  112.  
  113. CREATE OR REPLACE PROCEDURE najlepszystudentv2(im OUT VARCHAR2, nazw OUT VARCHAR2, nralb OUT VARCHAR2, sr OUT NUMBER) IS
  114. BEGIN
  115.     SELECT s.imie, s.nazwisko, s.nralbumu, AVG(o.ocena) INTO im, nazw, nralb, sr
  116.     FROM student s
  117.     INNER JOIN ocena o ON o.id_student = s.id_student
  118.     GROUP BY s.imie, s.nazwisko, s.nralbumu
  119.     HAVING AVG(o.ocena) = (
  120.         SELECT MAX(AVG(o.ocena))
  121.         FROM student s
  122.         INNER JOIN ocena o ON o.id_student = s.id_student
  123.         GROUP BY s.imie, s.nazwisko, s.nralbumu
  124.     );
  125. END;
  126.  
  127. DECLARE
  128.     im student.imie%TYPE;
  129.     nazw student.nazwisko%TYPE;
  130.     nralb student.nralbumu%TYPE;
  131.     sr NUMBER;
  132. BEGIN
  133.     najlepszystudentv2(im, nazw, nralb, sr);
  134.     DBMS_OUTPUT.PUT_LINE(im || ' ' || sr);
  135. END;
  136.  
  137. -- 5. Napisać procedurę PL/SQL, która dla podanego budynku, sali
  138. -- (parametry), wypisze wszystkie prowadzone zajęcia - tytuł, nazwisko i
  139. -- imię prowadzącego, nazwę przedmiotu, typ zajęć, nazwę grupy
  140. -- studenckiej.
  141.  
  142. CREATE OR REPLACE PROCEDURE listazajec(bud IN VARCHAR2, sala IN VARCHAR2) IS
  143. CURSOR kursor IS
  144.     SELECT t.nazwa tyt, w.imie, w.nazwisko, p.nazwa przedm, c.nazwa ch, g.nazwa gr
  145.     FROM zajecia z
  146.     INNER JOIN wykladowca w ON w.id_wykladowca = z.id_wykladowca
  147.     INNER JOIN przedmiot p ON p.id_przedmiot = z.id_przedmiot
  148.     INNER JOIN grupa g ON g.id_grupa = z.id_grupa
  149.     INNER JOIN charakter c ON c.id_charakter = z.id_charakter
  150.     INNER JOIN sala s ON s.id_sala = z.id_sala
  151.     INNER JOIN budynek b ON b.id_budynek = s.id_budynek
  152.     INNER JOIN tytulnaukowy t ON t.id_tytul = w.id_tytul
  153.     WHERE b.nazwa = bud AND s.kodsali = sala;
  154. BEGIN
  155.     FOR ROW IN kursor LOOP
  156.         DBMS_OUTPUT.PUT_LINE(ROW.tyt || ' ' || ROW.imie || ' ' || ROW.nazwisko || ' ' ||
  157.                              ROW.przedm || ' ' || ROW.ch || ' ' || ROW.gr);
  158.     END LOOP;
  159. END;
  160.  
  161. BEGIN
  162.     listazajec('Wydział Fizyki Matematyki i Iinformatyki', 'F201');
  163. END;
  164.  
  165. -- 6. Napisać procedurę, która zmieniałaby oceny z wybranego przedmiotu
  166. -- (parametr procedury) o 10% do momentu aż ocena ta stanie się oceną
  167. -- maksymalną lub też ocenę tę przekroczy. Nazwę przedmiotu wraz z
  168. -- ilością zmian przekazać do środowiska wywołującego i wypisać na
  169. -- ekranie.
  170.  
  171. CREATE OR REPLACE PROCEDURE podniesocene(przedm IN VARCHAR2, ilosc OUT NUMBER) IS
  172. CURSOR kursor IS
  173.     SELECT o.ocena
  174.     FROM ocena o
  175.     INNER JOIN zajecia z ON z.id_zajecia = o.id_zajecia
  176.     INNER JOIN przedmiot p ON p.id_przedmiot = z.id_przedmiot
  177.     WHERE p.nazwa = przedm
  178.     FOR UPDATE;
  179. BEGIN
  180.     ilosc := 0;
  181.     FOR ROW IN kursor LOOP
  182.         LOOP
  183.             EXIT WHEN ROW.ocena * 1.1 >= 5.0;
  184.             ROW.ocena := 1.1 * ROW.ocena;
  185.         END LOOP;
  186.         UPDATE ocena SET ocena.ocena = ROW.ocena WHERE CURRENT OF kursor;
  187.         ilosc := ilosc + 1;
  188.     END LOOP;
  189. END;
  190.  
  191. -- nie testowałem
  192. DECLARE
  193.     ilosc NUMBER;
  194. BEGIN
  195.     podniesocene('jakis przedmiot', ilosc);
  196.     DBMS_OUTPUT.PUT_LINE(ilosc);
  197. END;
  198.  
  199. -- 7.Napisz procedurę, która dla podanego wykładowcy (imię i nazwisko –
  200. -- parametry procedury) wyświetli imiona, nazwiska oraz numery albumu
  201. -- wszystkich studentów, którzy mieli zajęcia z tym wykładowcą w sali
  202. -- (parametr). Dane mają być posortowane alfabetycznie według nazwisk
  203. -- studentów. Utwórz tabelę HISTORIA i dodaj do niej zestaw rekordów
  204. -- zwrócony przez zapytanie.
  205. CREATE TABLE HISTORIA (
  206.     id_historia NUMBER(10) NOT NULL CONSTRAINT historia_pk PRIMARY KEY,
  207.     imie VARCHAR2(30) NOT NULL,
  208.     nazwisko VARCHAR2(30) NOT NULL,
  209.     nralbumu VARCHAR2(30) NOT NULL
  210. );
  211.  
  212.  
  213. CREATE OR REPLACE PROCEDURE utworzhistorie(im VARCHAR2, nazw VARCHAR2, sala VARCHAR2) IS
  214. CURSOR kursor IS
  215.     SELECT s.imie, s.nazwisko, s.nralbumu
  216.     FROM zajecia z
  217.     INNER JOIN grupa g ON g.id_grupa = s.id_grupa
  218.     INNER JOIN wykladowca w ON w.id_wykladowca = z.id_wykladowca
  219.     INNER JOIN sala sa ON sa.id_sala = z.id_sala
  220.     WHERE w.imie = im AND w.nazwisko = nazw AND s.kodsali = sala;
  221. ostatnieid NUMBER;
  222. BEGIN
  223.     SELECT MAX(id_historia) INTO ostatnieid FROM historia;
  224.     FOR ROW IN kursor LOOP
  225.         ostatnieid := ostatnieid + 1;
  226.         DBMS_OUTPUT.PUT_LINE(ROW.imie || ' ' || ROW.nazwisko || ' ' || ROW.nralbumu);
  227.         INSERT INTO historia(id_historia, imie, nazwisko, nralbumu) VALUES(ostatnieid, ROW.imie, ROW.nazwisko, ROW.nralbumu)l
  228.     END LOOP;
  229. END;
  230.  
  231. -- nie testowałem
  232.  
  233. -- ZESTAW IV
  234.  
  235. -- 1. Napisz procedurę, która obniży ocenę danego studenta (parametr) z danego
  236. -- przedmiotu (parametr) o podaną wartość przekazaną przez parametr, domyślna
  237. -- wartość: 0,5). Dodaj obsługę błędu – w przypadku podania danych studenta oraz
  238. -- przedmiotów, których nie ma w bazie.
  239.  
  240. CREATE OR REPLACE PROCEDURE obnizocene(nralb IN NUMBER, przedm IN VARCHAR2, wart IN NUMBER DEFAULT 0.5) IS
  241. CURSOR kursor IS
  242.     SELECT o.ocena
  243.     FROM ocena o
  244.     INNER JOIN student s ON s.id_student = o.id_student
  245.     INNER JOIN zajecia z ON z.id_zajecia = o.id_zajecia
  246.     INNER JOIN przedmiot p ON p.id_przedmiot = z.id_przedmiot
  247.     WHERE s.nralbumu = nralb AND p.nazwa = przedm
  248.     FOR UPDATE;
  249. r kursor%ROWTYPE;
  250. BEGIN
  251.     OPEN kursor;
  252.         FETCH kursor INTO r;
  253.         IF kursor%notfound THEN
  254.             RAISE NO_DATA_FOUND;
  255.         ELSE
  256.             IF r.ocena - wart >= 2.0 THEN
  257.                 UPDATE ocena SET ocena.ocena = r.ocena - wart WHERE CURRENT OF kursor;
  258.             END IF;
  259.         END IF;
  260.     CLOSE kursor;
  261.     EXCEPTION
  262.     WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('Brak danych');
  263. END;
  264.  
  265. BEGIN
  266.     obnizocene(121088, 'jakis przedmiot');
  267. END;
  268.  
  269. -- 2.Napisz procedurę w dwóch wariantach, która przeliczy stopnie Fahrenheita na
  270. -- Celsjusza według wzoru [ºC]=([ºF]-32)*5/9. W pierwszym wariancie procedura niech
  271. -- przyjmuje dwa parametry (Fahrenheit i Celsjusz), w drugim – jeden (temperatura).
  272. -- Skorzystaj z parametrów IN, OUT, IN OUT. Przetestuj jej działanie w bloku
  273. -- anonimowym.
  274.  
  275. CREATE OR REPLACE PROCEDURE oblicztemp(fahr IN NUMBER, cels OUT NUMBER) IS
  276. BEGIN
  277.     cels := (fahr - 32) * 5/9;
  278. END;
  279.  
  280. DECLARE
  281.     cels NUMBER;
  282. BEGIN
  283.     oblicztemp(100, cels);
  284.     DBMS_OUTPUT.PUT_LINE(cels);
  285. END;
  286.  
  287. CREATE OR REPLACE PROCEDURE oblicztempv2(temp IN OUT NUMBER) IS
  288. BEGIN
  289.     temp := (temp - 32) * 5/9;
  290. END;
  291.  
  292. DECLARE
  293.     temp NUMBER;
  294. BEGIN
  295.     temp := 100;
  296.     oblicztempv2(temp);
  297.     DBMS_OUTPUT.PUT_LINE(temp);
  298. END;
  299.  
  300. -- 3.Utwórz sekwencję, ktora pozwoli na nadawanie kolejnych numerów dla wstawianych
  301. -- ocen oraz studentów. Dodaj po dwa rekordy do tabeli student oraz oceny
  302. CREATE SEQUENCE sekw_st
  303. START WITH 200
  304. INCREMENT BY 1;
  305.  
  306. CREATE SEQUENCE sekw_oc
  307. START WITH 200
  308. INCREMENT BY 1;
  309.  
  310. INSERT INTO student VALUES (sekw_st.NEXTVAL, 'Zuza', 'Pazera', 3, 121078, 5);
  311.  
  312. -- 4.Utwórz wyzwalacz, który przy próbie zmiany oceny sprawdzi, czy nowa ocena nie
  313. -- jest zwiększona więcej niż 0.5. Jeśli tak wypisze starą i nową ocenę. Dodaj też
  314. -- odpowiedni komunikat.
  315.  
  316. CREATE OR REPLACE TRIGGER zmianaoceny BEFORE UPDATE ON ocena FOR EACH ROW
  317. BEGIN
  318.     IF :NEW.ocena > :old.ocena + 0.5 THEN
  319.         DBMS_OUTPUT.PUT_LINE('Stara ocena: ' || :old.ocena || ', nowa ocena: '  || :NEW.ocena);
  320.         RAISE_APPLICATION_ERROR(-20100, 'Za duża różnica');
  321.     END IF;
  322. END;
  323.  
  324. -- 5. Napisz funkcję SILNIA w sposób rekurencyjny. Przetestuj jej działanie.
  325. CREATE OR REPLACE FUNCTION silnia(wart NUMBER) RETURN NUMBER IS
  326. BEGIN
  327.     IF wart < 2 THEN
  328.         RETURN 1;
  329.     ELSE
  330.         RETURN wart * silnia(wart-1);
  331.     END IF;
  332. END;
  333.  
  334. BEGIN
  335.     DBMS_OUTPUT.PUT_LINE(silnia(5));
  336. END;
  337.  
  338. -- 6. Utworzyć pakiet o nazwie MOJ_PAKIET oraz zaimplementować podane niżej
  339. -- procedury i funkcje
  340. -- - DODAJ_STUD zadaniem procedury ma być dodawanie nowego studenta do
  341. -- tabeli student. Numer ID powinien być pobierany automatycznie ze
  342. -- zdefiniowanej w tym celu sekwencji.
  343. -- - ZMIEN_STUD – procedura modyfikuje dane wskazanego studenta.
  344. -- - USUN_STUD – procedura kasuje dane wskazanego studenta.
  345. -- - ZMIEN_ADRES – zadaniem tej procedury jest zmiana adresu wskazanego
  346. -- studenta.
  347. -- - TOP_N – wyświetla listę N studentów (N podawane jako parametr wejściowy
  348. -- procedury), którzy mają najwyższe średnie. Dane o tych studentach (imię,
  349. -- nazwisko, adres, średnia ocen) powinni zostać dodatkowo zapisani do tabeli o
  350. -- nazwie TOP_N_STUD (tabelę tą trzeba utworzyć bezpośrednio w kodzie
  351. -- procedury).
  352. -- - ZMIANA – procedura zmienia miejsce i czas prowadzenia przedmiotu przez
  353. -- konkretnego wykładowcę) nazwa przedmiotu, imię, nazwisko wykładowcy to
  354. -- parametry procedury.
  355. -- - WYPISZ– zadaniem procedury jest wypisanie średniej oceny dla wybranego
  356. -- przedmiotu, którego nazwa będzie parametrem..
  357. -- - MINMAX – zadaniem funkcji jest zwrócenie wartości (w zależności od
  358. -- podanego parametru) maksymalnej, minimalnej, średniej dla danej grupy
  359. -- (parametr). Funkcja powinna przyjmować tylko jeden z dwóch parametrów:
  360. -- MAX, MIN, Podanie innego parametru powinno wygenerować stosowne
  361. -- ostrzeżenie.
  362.  
  363. CREATE SEQUENCE sekw_stud
  364. START WITH 200
  365. INCREMENT BY 1;
  366.  
  367. CREATE OR REPLACE PACKAGE moj_pakiet AS
  368.     PROCEDURE dodaj_stud(im VARCHAR2, nazw VARCHAR2, idadr NUMBER, nralb NUMBER, idgr NUMBER);
  369.     PROCEDURE zmien_stud(im VARCHAR2, nazw VARCHAR2, idadr NUMBER, nralb NUMBER, idgr NUMBER, idst NUMBER);
  370.     PROCEDURE usun_stud(idst NUMBER);
  371.     PROCEDURE zmien_adres(idst NUMBER, ul VARCHAR2, nrbud NUMBER, nrlok NUMBER, kod VARCHAR2, miast VARCHAR2);
  372.     PROCEDURE top_n(n NUMBER);
  373.     PROCEDURE wypisz(przedm NUMBER);
  374.     PROCEDURE minmax(gr NUMBER, val VARCHAR2);
  375. END moj_pakiet;
  376.  
  377. CREATE OR REPLACE PACKAGE BODY moj_pakiet AS
  378.     PROCEDURE dodaj_stud(im VARCHAR2, nazw VARCHAR2, idadr NUMBER, nralb NUMBER, idgr NUMBER) IS
  379.         BEGIN
  380.             -- nie robię walidacji
  381.             INSERT INTO student VALUES (sekw_stud.NEXTVAL, im, nazw, idadr, nralb, idgr);
  382.         END;
  383.  
  384.     PROCEDURE zmien_stud(im VARCHAR2, nazw VARCHAR2, idadr NUMBER, nralb NUMBER, idgr NUMBER, idst NUMBER) IS
  385.         BEGIN
  386.             UPDATE student
  387.             SET imie = im, nazwisko = nazw, id_adres = idadr, nralbumu = nralb, id_grupa = idgr
  388.             WHERE id_student = idst;
  389.         END;
  390.  
  391.     PROCEDURE usun_stud(idst NUMBER) IS
  392.         BEGIN
  393.             DELETE FROM student WHERE student.id_student = idst;
  394.         END;
  395.  
  396.     PROCEDURE zmien_adres(idst NUMBER, ul VARCHAR2, nrbud NUMBER, nrlok NUMBER, kod VARCHAR2, miast VARCHAR2) IS
  397.         BEGIN
  398.             UPDATE adres SET ulica = ul, nrbudynku = nrbud, nrlokalu = nrlok, kodpocztowy = kod, miasto = miast
  399.             WHERE id_adres = (SELECT id_adres FROM student WHERE id_student = idst);
  400.         END;
  401.     PROCEDURE top_n(n NUMBER) IS
  402.         CURSOR kursor IS
  403.             SELECT s.nazwisko, a.miasto, AVG(o.ocena) sr
  404.             FROM student s
  405.             INNER JOIN ocena o ON o.id_student = s.id_student
  406.             INNER JOIN adres a ON a.id_adres = s.id_adres
  407.             GROUP BY s.nazwisko, a.miasto
  408.             ORDER BY AVG(o.ocena) DESC
  409.             FETCH FIRST n ROWS ONLY;
  410.         i NUMBER := 1;
  411.         BEGIN
  412.             EXECUTE IMMEDIATE 'CREATE TABLE top_n_stud (
  413.                id_t NUMBER(10) NOT NULL CONSTRAINT pk_id PRIMARY KEY,
  414.                nazwisko VARCHAR2(30) NOT NULL,
  415.                miasto VARCHAR2(30) NOT NULL,
  416.                srednia NUMBER(10) NOT NULL
  417.                )';
  418.             FOR ROW IN kursor LOOP
  419.                 INSERT INTO top_n_stud VALUES (i, ROW.nazwisko, ROW.miasto, ROW.sr);
  420.                 i := i + 1;
  421.             END LOOP;
  422.         END;
  423.  
  424.     PROCEDURE wypisz(przedm NUMBER) IS
  425.         sr NUMBER;
  426.         BEGIN
  427.             SELECT AVG(o.ocena) INTO sr
  428.             FROM ocena o
  429.             INNER JOIN zajecia z ON z.id_zajecia = o.id_zajecia
  430.             INNER JOIN przedmiot p ON p.id_przedmiot = z.id_przedmiot
  431.             WHERE p.nazwa = przedm;
  432.             DBMS_OUTPUT.PUT_LINE(sr);
  433.         END;
  434.  
  435.     PROCEDURE minmax(gr NUMBER, val VARCHAR2) IS
  436.         ret NUMBER;
  437.         bledny_rodzaj EXCEPTION;
  438.         BEGIN
  439.             IF val = 'MAX' THEN
  440.                 SELECT AVG(o.ocena) INTO ret
  441.                 FROM ocena o
  442.                 INNER JOIN student s ON s.id_student = o.id_student
  443.                 INNER JOIN grupa g ON g.id_grupa = s.id_grupa
  444.                 WHERE g.nazwa = gr
  445.                 HAVING AVG(o.ocena) = (
  446.                     SELECT MAX(AVG(o.ocena))
  447.                     FROM ocena o
  448.                     INNER JOIN student s ON s.id_student = o.id_student
  449.                     INNER JOIN grupa g ON g.id_grupa = s.id_grupa
  450.                     WHERE g.nazwa = gr
  451.                     );
  452.                 DBMS_OUTPUT.PUT_LINE(ret);
  453.             ELSIF val = 'MIN' THEN
  454.                                 SELECT AVG(o.ocena) INTO ret
  455.                 FROM ocena o
  456.                 INNER JOIN student s ON s.id_student = o.id_student
  457.                 INNER JOIN grupa g ON g.id_grupa = s.id_grupa
  458.                 WHERE g.nazwa = gr
  459.                 HAVING AVG(o.ocena) = (
  460.                     SELECT MIN(AVG(o.ocena))
  461.                     FROM ocena o
  462.                     INNER JOIN student s ON s.id_student = o.id_student
  463.                     INNER JOIN grupa g ON g.id_grupa = s.id_grupa
  464.                     WHERE g.nazwa = gr
  465.                     );
  466.                 DBMS_OUTPUT.PUT_LINE(ret);
  467.             ELSE
  468.                 RAISE bledny_rodzaj;
  469.             END IF;
  470.             EXCEPTION
  471.                 WHEN bledny_rodzaj THEN DBMS_OUTPUT.PUT_LINE('Prosze wybrac min albo max');
  472.         END;
  473. END moj_pakiet;
  474.  
  475. -- coś nie działa, nie wiem co
  476.  
  477. -- ZESTAW VII
  478.  
  479. -- 1.Uruchom następujący blok anonimowy:
  480. -- BEGIN
  481. -- execute immediate
  482. -- '
  483. -- begin
  484. -- dbms_output.put_line (' ' kierunek informatyka' ' );
  485. -- end;
  486. -- ';
  487. -- END;
  488.  
  489. BEGIN
  490.     EXECUTE IMMEDIATE  'BEGIN
  491.        DBMS_OUTPUT.PUT_LINE(''kierunek informatyka'');
  492.    end;';
  493. END;
  494.  
  495. -- 2.Napisz blok anonimowy warunkowo usuwający sekwencję – w pętli FOR sprawdź, czy
  496. -- sekwencja istnieje, a następnie twórz i uruchom dynamiczną instrukcję DDL DROP
  497. -- SEQUNCE. Wykonaj zadanie z użyciem NDS oraz pakietu DBMS_SQL
  498. CREATE SEQUENCE test_sekw
  499. START WITH 150
  500. INCREMENT BY 1
  501. MINVALUE 100
  502. MAXVALUE 200;
  503.  
  504. SELECT * FROM user_objects WHERE object_name = 'TEST_SEKW';
  505.  
  506.  
  507. BEGIN
  508.     FOR i IN (SELECT NULL FROM user_objects WHERE object_name = 'TEST_SEKW') LOOP
  509.         EXECUTE IMMEDIATE 'DROP SEQUENCE test_sekw';
  510.     END LOOP;
  511. END;
  512.  
  513. -- 3.Utworzyć procedurę przyjmującą jako parametry nazwę tabeli i opcjonalnie nazwę kolumny
  514. -- gdy podana jest tylko nazwa tabeli, procedura ma dodać komentarz do tabeli zawierający
  515. -- informację o ilości rekordów w tabeli w wypadku gdy podana jest też nazwa kolumny, należy
  516. -- dodać komentarz na odpowiedniej kolumnie z informacją na temat ilości różnych wartości tej
  517. -- kolumny
  518. CREATE OR REPLACE PROCEDURE dodajkomentarz(tab VARCHAR2, kol VARCHAR2 DEFAULT NULL) IS
  519.     lrekordow NUMBER;
  520.     lwartosci NUMBER;
  521.     BEGIN
  522.         EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || tab INTO lrekordow;
  523.         EXECUTE IMMEDIATE 'COMMENT ON TABLE ' || tab || ' IS ''liczba rekordow: ' || lrekordow || '''';
  524.         IF kol IS NOT NULL THEN
  525.             EXECUTE IMMEDIATE 'SELECT COUNT(DISTINCT '|| kol || ') FROM ' || tab INTO lwartosci;
  526.             EXECUTE IMMEDIATE 'COMMENT ON COLUMN ' || tab || '.' || kol || ' IS ''liczba wartosci ' || lwartosci || '''';
  527.         END IF;
  528.     END;
  529.  
  530. BEGIN
  531.     dodajkomentarz('STUDENT', 'IMIE');
  532. END;
  533.  
  534. -- 4.Utworzyć procedurę wypisującą na ekran ilość studentów spełniających określone kryteria -
  535. -- urodzonych w zadanym przedziale czasu -których imię, nazwisko pasuje do podanego wzorca
  536. -- klauzula where zapytania powinna zawierać tylko warunki dla tych parametrów (kryteriów),
  537. -- które nie są puste.
  538. CREATE OR REPLACE PROCEDURE ilstudentow(dataod DATE, datado DATE, wzorzecim VARCHAR2, wzorzecnazw VARCHAR2) IS
  539.     lstud NUMBER;
  540. BEGIN
  541.     SELECT COUNT(s.id_student) INTO lstud
  542.     FROM student s
  543.     WHERE s.dataurodzenia >= dataod AND s.dataurodzenia <= datado AND s.imie LIKE wzorzecim AND s.nazwisko LIKE wzorzecnazw;
  544.     DBMS_OUTPUT.PUT_LINE(lstud);
  545. END;
  546.  
  547. -- 5. nie robię
  548. -- 6. nie robię
  549.  
  550. -- 7. Napisać procedurę dodającą do podanej jako parametr tabeli pole ostatnia_modyfikacja oraz
  551. -- trigger uzupełniający to pole przy wykonaniu update na rekordzie.
  552.  
  553. CREATE OR REPLACE PROCEDURE dodajtrigger(tab VARCHAR2) IS
  554. BEGIN
  555.     EXECUTE IMMEDIATE 'ALTER TABLE ' || tab || ' ADD ostatnia_modyfikacja DATE';
  556.     EXECUTE IMMEDIATE 'CREATE OR REPLACE TRIGGER ' || tab || '_trigg AFTER UPDATE ON ' || tab ||
  557.                       ' FOR EACH ROW BEGIN ' ||
  558.                         'UPDATE ' || tab || ' SET ostatnia_modyfikacja = sysdate;' ||
  559.                       ' END;';
  560. END;
  561.  
  562. BEGIN
  563.     dodajtrigger('student');
  564. END;
  565.  
  566. -- nie testowałem
  567.  
  568. -- 9. Usuń z tabeli student wybrany rekord oraz dodaj nowy rekord korzystając z pakietu
  569. -- DBMS_SQL
  570. CREATE OR REPLACE PROCEDURE usunstudenta(idst NUMBER) IS
  571.     kursor INTEGER := DBMS_SQL.OPEN_CURSOR;
  572.     ret INTEGER;
  573.     stmt VARCHAR2(255);
  574. BEGIN
  575.     stmt := 'DELETE FROM student WHERE id_student = :idst';
  576.     DBMS_SQL.PARSE(kursor, stmt, DBMS_SQL.NATIVE);
  577.     DBMS_SQL.BIND_VARIABLE(kursor, ':idst', idst);
  578.     ret := DBMS_SQL.EXECUTE(kursor);
  579.     DBMS_SQL.CLOSE_CURSOR(kursor);
  580. END;
  581.  
  582. CREATE OR REPLACE PROCEDURE dodajstudenta(im VARCHAR2, nazw VARCHAR2, idadr NUMBER, nralb NUMBER, idgr NUMBER) IS
  583.     kursor INTEGER := DBMS_SQL.OPEN_CURSOR;
  584.     stmt VARCHAR2(255);
  585.     ret INTEGER;
  586. BEGIN
  587.     stmt := 'INSERT INTO student VALUES (:id, :im, :nazw, :idadr, :nralb, :idgr, null)';
  588.     DBMS_SQL.PARSE(kursor, stmt, DBMS_SQL.NATIVE);
  589.     DBMS_SQL.BIND_VARIABLE(kursor, ':id', sekw_st.NEXTVAL);
  590.     DBMS_SQL.BIND_VARIABLE(kursor, ':im', im);
  591.     DBMS_SQL.BIND_VARIABLE(kursor, ':nazw', nazw);
  592.     DBMS_SQL.BIND_VARIABLE(kursor, ':idadr', idadr);
  593.     DBMS_SQL.BIND_VARIABLE(kursor, ':nralb', nralb);
  594.     DBMS_SQL.BIND_VARIABLE(kursor, ':idgr', idgr);
  595.     ret := DBMS_SQL.EXECUTE(kursor);
  596.     DBMS_SQL.CLOSE_CURSOR(kursor);
  597. END;
  598.  
  599. BEGIN
  600.     usunstudenta(200);
  601.     dodajstudenta('Tomek', 'Pazera', 1, 123132, 13);
  602. END;
  603.  
  604. -- KOLOKWIUM II GRUPA 1
  605.  
  606. -- +---------------+----------------+----------------+-----------+----------------+
  607. -- | PRZEDMIOTY    | OCENY          | NAUCZYCIELE    | UCZNIOWIE | KLASY          |
  608. -- +---------------+----------------+----------------+-----------+----------------+
  609. -- | id_przedmiotu | id_oceny       | id_nauczyciela | id_ucznia | id_klasy       |
  610. -- | nazwa         | id_przedmiotu  | nazwisko       | nazwisko  | nazwa          |
  611. -- |               | id_ucznia      | imie           | imię      | id_nauczyciela |
  612. -- |               | id_nauczyciela | id_przedmiotu  | data_ur   |                |
  613. -- |               | ocena          |                | id_klasy  |                |
  614. -- |               | data           |                |           |                |
  615. -- +---------------+----------------+----------------+-----------+----------------+
  616.  
  617. -- 1.Napisz procedurę (imię i nazwisko, data_ur parametry) wprowadzającą do tabeli KLASY rekord rejestrujący utworzenie
  618. -- nowej klasy Vk. Do utworzonej klasy Vk należy wprowadzić ucznia. Aby można było zarejestrować nowego ucznia należy
  619. -- sprawdzić, czy uczeń o podanym nazwisku i imieniu znajduje się już w bazie danych. Jeśli tak to należy wyprowadzić
  620. -- komunikat informujący o tym fakcie, jeśli nie należy wprowadzić nowego ucznia. Zaimplementuj obsługę błędów.
  621. CREATE OR REPLACE PROCEDURE dodajklase(im IN VARCHAR2, nazw IN VARCHAR2, data IN DATE) IS
  622. lastid NUMBER;
  623. studentexist NUMBER;
  624. lastidst NUMBER;
  625. uczenistnieje EXCEPTION;
  626. BEGIN
  627.     SELECT MAX(id_klasy) INTO lastid FROM klasy;
  628.     lastid := lastid + 1;
  629.     -- nie ma info o nauczycielu
  630.     INSERT INTO klasy(id_klasy, nazwa, id_nauczyciela) VALUES (lastid, 'Vk', 1);
  631.     -- sprawdzamy czy rekord istnieje
  632.     SELECT COUNT(*) INTO studentexist FROM uczniowie u WHERE u.nazwisko = nazw AND u.imie = im AND u.data_ur = data GROUP BY u.id_ucznia;
  633.     IF studentexist = 0 THEN
  634.         SELECT MAX(id_student) INTO lastidst FROM uczniowie;
  635.         INSERT INTO uczniowie VALUES (lastidst+1, nazw, im, data, lastid);
  636.     ELSE
  637.         RAISE uczenistnieje;
  638.     END IF;
  639.     EXCEPTION
  640.     WHEN uczenistnieje THEN DBMS_OUTPUT.PUT_LINE('uczen istnieje');
  641.     WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Error');
  642. END;
  643.  
  644. -- 2.Napisz funkcję, która zwróci najniższą średnią ocen z danego przedmiotu. Funkcja, jako parametr wyjściowy
  645. -- powinna zwrócić nazwę przedmiotu oraz nazwisko i imię prowadzącego.
  646. CREATE OR REPLACE FUNCTION najnizszasrednia(przedm IN OUT VARCHAR2, nazw OUT VARCHAR2, im OUT VARCHAR2) RETURN NUMBER IS
  647. ret NUMBER;
  648. BEGIN
  649.     SELECT AVG(o.ocena), n.imie, n.nazwisko INTO ret, im, nazw
  650.     FROM oceny o
  651.     INNER JOIN przedmioty p ON p.id_przedmiotu = o.id_przedmiotu
  652.     WHERE p.nazwa = przedm
  653.     GROUP BY n.imie, n.nazwisko
  654.     HAVING AVG(o.ocena) = (
  655.         SELECT MIN(AVG(o.ocena)), n.imie, n.nazwisko
  656.         FROM oceny o
  657.         INNER JOIN przedmioty p ON p.id_przedmiotu = o.id_przedmiotu
  658.         WHERE p.nazwa = przedm
  659.         GROUP BY n.imie, n.nazwisko
  660.         );
  661.     RETURN ret;
  662. END;
  663.  
  664. DECLARE
  665.     im VARCHAR2;
  666.     nazw VARCHAR2;
  667.     przedm VARCHAR2;
  668.     sr NUMBER;
  669. BEGIN
  670.     przedm := 'Matematyka';
  671.     sr = najnizszasrednia(przedm, im, nazw);
  672. END;
  673.  
  674. -- 3.Napisz procedurę, której zadaniem jest obliczenie i wyprowadzenie na zewnątrz poprzez parametry wyjściowe
  675. -- średniej ocen dla każdej z istniejących klas z podaniem imienia i nazwiska wychowawcy klasy.
  676.  
  677. -- JAK NIBY MAM ZBIÓR REKORDÓW ZWRÓCIĆ W PARAMETRZE WYJŚCIOWYM??!?!??!?!?!?
  678. CREATE OR REPLACE PROCEDURE srednieklas(sre NUMBER, przedm VARCHAR2, im VARCHAR2, nazw VARCHAR2) IS
  679. CURSOR kursor IS
  680.     SELECT AVG(o.ocena) sr, p.nazwa, n.imie, n.nazwisko INTO sre, przedm, im, nazw
  681.     FROM ocena
  682.     INNER JOIN przedmioty p ON p.id_przedmiot = o.id_przedmiot
  683.     INNER JOIN nauczyciele n ON n.id_przedmiot = p.id_przedmiot
  684.     GROUP BY p.nazwa, n.nazwisko, n.imie;
  685. r kursor%ROWTYPE;
  686. BEGIN
  687.     FOR r IN kursor LOOP
  688.         DBMS_OUTPUT.PUT_LINE(r.nazwa || ' ' || r.imie || ' ' || r.nazwisko || ' ' || r.sr);
  689.     END LOOP;
  690. END;
  691.  
  692. -- 4.Napisz procedurę wyzwalaną, która przed wykonaniem operacji UPDATE i INSERT dla każdego wiersza tabeli UCZNIOWIE
  693. -- doda do tabeli TEST informację w postaci ciągu znaków: ‘operacja B C’, gdzie operacja to nazwa wykonywanej operacji,
  694. -- B, C to wartości poszczególnych atrybutów przed wykonaniem operacji. Tabela TEST istnieje i ma odpowiednią strukturę
  695. CREATE OR REPLACE TRIGGER jakistrigger BEFORE UPDATE OR INSERT ON uczniowie
  696. FOR EACH ROW
  697. BEGIN
  698.     IF UPDATING THEN
  699.         INSERT INTO test VALUES ('UPDATE ' || :OLD.imie || ' ' || :OLD.nazwisko || ' ' || :OLD.data_ur || ' TO ' || :NEW.imie || ' ' || :NEW.nazwisko || ' ' || :NEW.data_ur);
  700.     ELSIF INSERTING THEN
  701.         INSERT INTO test VALUES ('INSERT ' || :OLD.imie || ' ' || :OLD.nazwisko || ' ' || :OLD.data_ur || ' TO ' || :NEW.imie || ' ' || :NEW.nazwisko || ' ' || :NEW.data_ur);
  702.     END IF;
  703. END;
  704.  
  705. -- 5. Utwórz z pakiet (sekcja specyfikacji i ciała) składający się z procedur i funkcji, które znajdują się w tym zestawie.
  706. CREATE OR REPLACE PACKAGE pakiecik AS
  707.     PROCEDURE dodajklase(im IN VARCHAR2, nazw IN VARCHAR2, data IN DATE);
  708.     FUNCTION najnizszasrednia(przedm IN OUT VARCHAR2, nazw OUT VARCHAR2, im OUT VARCHAR2) RETURN NUMBER;
  709.     PROCEDURE srednieklas(sre NUMBER, przedm VARCHAR2, im VARCHAR2, nazw VARCHAR2);
  710. END pakiecik;
  711.  
  712. CREATE OR REPLACE PACKAGE BODY pakiecik AS
  713.     -- TUTAJ CIAŁO FUNKCJI
  714. END pakiecik;
  715.  
  716. -- Omów parametry wyzwalaczy
  717. -- *FOR EACH ROW - wyzwalacz będzie uruchamiany dla każdego rekordu przetworzonego przez polecenie
  718. -- *AFTER/BEFORE/INSTEAD OF - parametry mówiące kiedy ma wykonać się ciało wyzwalacza - przed, po, zamiast polecenia na
  719. -- *danej tabeli
  720. -- -- do wartości odwołujemy się za pomocą :OLD.atrybut (przed wykonaniem polecenia, dla insert wartośc null) oraz
  721.    -- :NEW.atrybut (po wykonaniu polecenia, dla delete wartość null)
  722. -- *INSERTING/DELETING/UPDATING - zwraca prawdę jeżeli zdarzenie uruchamiające wyzwalacz było odpowiednio INSERT/DELETE/UPDATE
  723. -- *WHEN (po FOR EACH ROW) - warunek jaki musi być spełniony dla konkretnego rekordu (np. OLD.atrybut IS NULL - pomijamy :)
  724.  
  725. -- KOLOKWIUM II GRUPA 2
  726. -- +------------+------------+-----------+-------------+-------------+-----------+--------------+
  727. -- | cz_nap     | naprawy    | samochody | mechanicy   | klienci     | magazyn   | specjalnosci |
  728. -- +------------+------------+-----------+-------------+-------------+-----------+--------------+
  729. -- | id_cznap   | id_naprawy | id_sam    | id_mech     | id_kli      | id_czesci | id_spec      |
  730. -- | id_czesci  | id_sam     | marka     | nazwisko    | nazwisko    | nazwa     | nazwa        |
  731. -- | id_naprawy | id_kli     | model     | imię        | imię        | cena      |              |
  732. -- |            | id_mech    | nr_rej    | data_ur     | nr_dowodu   | ilosc     |              |
  733. -- |            | cena       |           | data_zatrud | miejscowosc |           |              |
  734. -- |            | data       |           | id_spec     |             |           |              |
  735. -- +------------+------------+-----------+-------------+-------------+-----------+--------------+
  736.  
  737. -- 1.Napisz procedurę (imię i nazwisko, data_ur parametry) wprowadzającą do tabeli NAPRAWY rekord rejestrujący nową
  738. -- usługę. Aby można było zarejestrować nową usługę należy sprawdzić, czy klient o podanym nazwisku i imieniu
  739. -- (parametry procedury) znajduje się już w bazie danych. Jeśli nie należy wprowadzić nowego klienta do tabeli
  740. -- kLIENCI. Zaimplementuj obsługę błędów.
  741.  
  742. -- !??@!??!?!??@?!?D?S??@!?@?? stara chyba tego nie czytała nawet :)
  743.  
  744. -- 2.Napisz funkcję obliczającą, który z mechaników (nazwisko i imię mechanika - parametry wyjściowe) miał największą
  745. -- ilość napraw. Funkcja powinna zwrócić liczbę samochodów, które zostały przez niego naprawione bez powtórzeń.
  746. CREATE OR REPLACE FUNCTION najwiecejnapraw(nazw OUT VARCHAR2, im OUT VARCHAR2) RETURN NUMBER IS
  747.     maxilosc NUMBER := 0;
  748. BEGIN
  749.     SELECT COUNT(n.id_naprawy), m.nazwisko, m.imie INTO maxilosc, nazw, im
  750.     FROM naprawy n
  751.     INNER JOIN mechanicy m ON m.id_mech = n.id_mech
  752.     GROUP BY m.nazwisko, m.imie
  753.     HAVING COUNT(n.id_naprawy) = (
  754.         SELECT MAX(COUNT(n.id_naprawy))
  755.         FROM naprawy n
  756.         INNER JOIN mechanicy m ON m.id_mech = n.id_mech
  757.         GROUP BY m.nazwisko, m.imie
  758.         );
  759.     RETURN maxilosc;
  760. END;
  761.  
  762. -- 3.Napisz procedurę, której zadaniem jest obliczenie i wypisanie ceny wszystkich napraw, które zostały zlecone przez
  763. -- poszczególnych klientów. Procedura ma zwracać sumaryczną cenę  wszystkich napraw.
  764. CREATE OR REPLACE PROCEDURE cenynapraw(sumarycznasuma OUT NUMBER) IS
  765. CURSOR kursor IS
  766.     SELECT n.id_naprawy, k.imie, k.nazwisko, n.cena
  767.     FROM naprawy n
  768.     INNER JOIN klienci k ON k.id_kli = n.id_kli;
  769. r kursor%ROWTYPE;
  770. BEGIN
  771.     sumarycznasuma := 0;
  772.     FOR r IN kursor LOOP
  773.         sumarycznasuma := sumarycznasuma + r.cena;
  774.         DMBS_OUTPUT.PUT_LINE(n.id_naprawy || ' ' || k.imie || ' ' || k.nazwisko || ' ' || n.cena);
  775.     END LOOP;
  776. END;
  777.  
  778. -- 4.Napisz procedurę wyzwalaną dla tabeli NAPRAWY wstawiającą do pola klucz głównego kolejną wartość pobraną z
  779. -- sekwencji BETA, którą trzeba utworzyć.
  780. CREATE SEQUENCE beta
  781. START WITH 200
  782. INCREMENT BY 1;
  783.  
  784. CREATE OR REPLACE TRIGGER wstawklucz BEFORE INSERT ON naprawy
  785.     FOR EACH ROW
  786. --     WHEN (NEW.id_naprawy IS NULL)
  787.     BEGIN
  788.         :NEW.id_naprawy := beta.NEXTVAL;
  789.     END;
  790.  
  791. -- 5. Utwórz z pakiet (sekcja specyfikacji i ciała) składający się z procedur i funkcji, które znajdują się w
  792. -- tym zestawie.
  793. CREATE OR REPLACE PACKAGE pakiecik AS
  794.     FUNCTION najwiecejnapraw(nazw OUT VARCHAR2, im OUT VARCHAR2) RETURN NUMBER;
  795.     PROCEDURE cenynapraw(sumarycznasuma OUT NUMBER);
  796. END pakiecik;
  797.  
  798. CREATE OR REPLACE PACKAGE BODY pakiecik AS
  799.     -- ciała funkcji i procedur
  800. END pakiecik;
  801.  
  802. -- 6. Omów własności aktywnych baz danych
  803. -- • Modele aktywności – zależności czasowe i przyczynowo-skutkowe między zdarzeniami i akcjami
  804. -- • Zdarzenia elementarne – zbiór typów zdarzeń, które mogą być podstawą definiowania aktywnych reguł
  805. -- • Operatory zdarzeniowe – zbiór operatorów umożliwiających specyfikację złożonych wyrażeń zdarzeniowych
  806. -- • Kontekst definicji aktywnych reguł – pojedyncza dana, zbiór danych, baza danych
  807.  
  808. -- KOLOKWIUM II Grupa 3
  809. -- +------------+------------+-----------+-------------+-------------+-----------+--------------+
  810. -- | cz_nap     | naprawy    | samochody | mechanicy   | klienci     | magazyn   | specjalnosci |
  811. -- +------------+------------+-----------+-------------+-------------+-----------+--------------+
  812. -- | id_cznap   | id_naprawy | id_sam    | id_mech     | id_kli      | id_czesci | id_spec      |
  813. -- | id_czesci  | id_sam     | marka     | nazwisko    | nazwisko    | nazwa     | nazwa        |
  814. -- | id_naprawy | id_kli     | model     | imię        | imię        | cena      |              |
  815. -- |            | id_mech    | nr_rej    | data_ur     | nr_dowodu   | ilosc     |              |
  816. -- |            | cena       |           | data_zatrud | miejscowosc |           |              |
  817. -- |            | data       |           | id_spec     |             |           |              |
  818. -- +------------+------------+-----------+-------------+-------------+-----------+--------------+
  819. -- 1. Napisz procedurę wprowadzającą do tabeli magazyn rekordy rejestrujące nowe części. Dotyczy ono tych części,
  820. -- których brakuje w magazynie, a potrzebne są do naprawy samochodu o id_naprawy (parametr). Wykorzystaj obsługę błędów
  821. CREATE OR REPLACE PROCEDURE dodajnowaczesc(samochod NUMBER, nazwa_czesci IN VARCHAR2, cena IN NUMBER) IS
  822. czyczescwmagazynie NUMBER;
  823. lastidmagazyn NUMBER;
  824. czescwmagazynie EXCEPTION ;
  825. BEGIN
  826.     -- sprawdzam czy czesc jest w magazynie
  827.     SELECT COUNT(m.id_czesci) INTO czyczescwmagazynie
  828.     FROM naprawy n
  829.     INNER JOIN samochody s ON s.id_sam = n.id_sam
  830.     INNER JOIN cz_nap c ON c.id_naprawy = n.id_naprawy
  831.     INNER JOIN magazyn m ON m.id_czesci = c.id_czesci
  832.     WHERE s.id_sam = samochod;
  833.  
  834.     IF czyczescwmagazynie = 0 THEN
  835.         SELECT MAX(id_czesci) INTO lastidmagazyn FROM magazyn;
  836.         INSERT INTO magazyn VALUES (lastidmagazyn + 1, nazwa_czesci, cena, 0);
  837.     ELSE
  838.         RAISE czescwmagazynie;
  839.     END IF;
  840.  
  841.     EXCEPTION
  842.         WHEN czescwmagazynie THEN DBMS_OUTPUT.PUT_LINE('Czesc jest juz w magazynie');
  843.         WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('ERROR');
  844. END;
  845.  
  846. -- 2. Napisz funkcję, która obliczy, koszt wszystkich napraw, jakie miał klient o nazwisku i imieniu podanym jako
  847. -- parametry wejściowe. Funkcja powinna zwrócić jako parametr wyjściowy całkowity koszt wszystkich napraw
  848. CREATE OR REPLACE FUNCTION sumanapraw(im IN VARCHAR2, nazw IN VARCHAR2) RETURN NUMBER IS
  849. suma NUMBER := 0;
  850. CURSOR kursor IS
  851.     SELECT n.cena
  852.     FROM naprawy n
  853.     INNER JOIN klienci k ON k.id_kli = n.id_kli
  854.     WHERE k.imie = im AND k.nazwisko = nazw;
  855. r kursor%ROWTYPE;
  856. BEGIN
  857.     FOR r IN kursor LOOP
  858.         suma := suma + r.cena;
  859.     END LOOP;
  860.     RETURN suma;
  861. END;
  862.  
  863. -- 3. Napisz procedurę, której zadaniem jest dla podanego nazwiska i imienia mechanika (parametry) zapisanie informacji
  864. -- o wszystkich samochodach, które zostały przez niego naprawione. Markę, model i numer rejestracyjny samochodu należy
  865. -- wstawić do tabeli historia, przy założeniu, że tabela o tej strukturze istnieje w bazie danych.
  866. -- Zaimplementuj obsługę błędów:
  867. -- a) braku mechanika o podanym nazwisku;
  868. -- b) braku napraw przez niego wykonanych;
  869. -- c) pozostałych błędów.
  870. CREATE OR REPLACE PROCEDURE dodajlog(im IN VARCHAR2, nazw IN VARCHAR2) IS
  871. CURSOR kursor IS
  872.     SELECT s.marka, s.model, s.nr_rej
  873.     FROM naprawy n
  874.     INNER JOIN samochody s ON s.id_sam = n.id_sam
  875.     INNER JOIN mechanicy m ON m.id_kli = m.id_kli
  876.     WHERE m.imie = im AND m.nazwisko = nazw;
  877. r kursor%ROWTYPE;
  878. mechanik NUMBER;
  879. brakmechanika EXCEPTION;
  880. braknapraw EXCEPTION;
  881. i NUMBER := 0;
  882. BEGIN
  883.     SELECT id_mech FROM mechanik m WHERE m.imie = im AND m.nazwisko = nazw;
  884.     IF id_mech IS NULL THEN
  885.         RAISE brakmechanika;
  886.     END IF;
  887.     FOR r IN kursor LOOP
  888.         i := i + 1;
  889.         INSERT INTO historia VALUES(r.marka, r.model, r.nr_rej);
  890.     END LOOP;
  891.     IF i = 0 THEN
  892.         RAISE braknapraw;
  893.     END IF;
  894.     EXCEPTION
  895.     WHEN brakmechanika THEN DBMS_OUTPUT.PUT_LINE('brak mechanika');
  896.     WHEN braknapraw THEN DBMS_OUTPUT.PUT_LINE('brak napraw');
  897.     WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('ERROR');
  898. END;
  899.  
  900. -- 4. Napisz procedurę wyzwalaną, która ma utrzymywać stały budżetu zakładu. Zmiany, które mają wpływ na budżet
  901. -- zakładu są związane ze zwalnianiem i zatrudnianiem mechaników oraz zmianą ich zarobków.
  902. CREATE OR REPLACE TRIGGER stalybudzet BEFORE INSERT OR DELETE ON mechanicy
  903.     FOR EACH ROW
  904.     DECLARE
  905.         sumazarobkow NUMBER := 0;
  906.         liczbazatrudnionych NUMBER := 0;
  907.         nowapensja NUMBER := 0;
  908.         CURSOR kursor IS
  909.             SELECT pensja, id_mech
  910.             FROM mechanicy;
  911.         r kursor%ROWTYPE;
  912.     BEGIN
  913.         -- CO? zakładam że wszyscy zarabiają tyle samo cały czas i że naprawy nie mają wpływu na budżet
  914.         SELECT SUM(pensja), COUNT(id_mech) INTO sumazarobkow, liczbazatrudnionych FROM mechanicy;
  915.         IF INSERTING THEN
  916.             nowapensja := sumazarobkow/(liczbazatrudnionych+1);
  917.         ELSIF DELETING THEN
  918.             nowapensja := sumazarobkow/(liczbazatrudnionych-1);
  919.         END IF;
  920.         FOR r IN kursor LOOP
  921.             UPDATE mechanicy SET pensja = nowapensja WHERE CURRENT OF kursor;
  922.         END LOOP;
  923.     END;
  924.  
  925. -- 5. Utwórz z pakiet (sekcja specyfikacji i ciała) składający się z procedur i funkcji, które znajdują się w
  926. -- tym zestawie.
  927. CREATE OR REPLACE PACKAGE pakiecik AS
  928.     PROCEDURE dodajnowaczesc(samochod NUMBER, nazwa_czesci IN VARCHAR2, cena IN NUMBER);
  929.     FUNCTION sumanapraw(im IN VARCHAR2, nazw IN VARCHAR2) RETURN NUMBER;
  930.     PROCEDURE dodajlog(im IN VARCHAR2, nazw IN VARCHAR2);
  931. END pakiecik;
  932.  
  933. CREATE OR REPLACE PACKAGE BODY pakiecik AS
  934.     -- ciała funkcji
  935. END pakiecik;
  936.  
  937. -- 6. Jakie wymagania powinien spełniać zbiór potencjalnie powiązanych reguł
  938. -- • własność stopu – przetwarzanie akcji reguł uaktywnionych przez pojedyncze zdarzenie zostanie zakończone w
  939. -- skończonym czasie
  940. -- • determinizm stanu – kolejność wykonania akcji reguł uaktywnionych tym samym zdarzeniem nie ma wpływu na końcowy
  941. -- stan bazy danych
  942.  
  943. -- KOLOKWIUM II Grupa 6
  944. -- +------------+------------+--------------+--------------+------------+--------------+
  945. -- | obsługa    | sale       | rozprawy     | pozwani      | typ_sprawy | specjalnosci |
  946. -- +------------+------------+--------------+--------------+------------+--------------+
  947. -- | id_obsługi | id_sali    | id_rozprawy  | id_pozwanego | id_typu    | id_spec      |
  948. -- | nazwisko   | nazwa      | id_pozwanego | nazwisko     | nazwa      | nazwa        |
  949. -- | imie       | poziom_zab | id_typu      | imię         |            |              |
  950. -- | id_spec    |            | id_obsługi   | data_ur      |            |              |
  951. -- |            |            | data         | pesel        |            |              |
  952. -- |            |            | godzina      | kod_pocztowy |            |              |
  953. -- |            |            | id_sali      | miejscowość  |            |              |
  954. -- |            |            |              | ulica        |            |              |
  955. -- +------------+------------+--------------+--------------+------------+--------------+
  956.  
  957. -- 1. Napisz procedurę  wprowadzającą do tabeli ROZPRAWY rekord rejestrujący nową rozprawę. Aby można było
  958. -- zarejestrować nową rozprawę należy sprawdzić, czy pozwany o podanym nazwisku i imieniu (parametry procedury)
  959. -- znajduje się już w bazie danych. Jeśli nie należy wprowadzić nowego pozwanego do tabeli POZWANI.
  960. -- Zaimplementuj obsługę błędów.
  961. CREATE OR REPLACE PROCEDURE nowarozprawa(idtyp IN NUMBER, idobs IN NUMBER, data IN DATE,
  962.                                         godz IN VARCHAR2, sala IN NUMBER, nazw IN VARCHAR2, im IN VARCHAR2,
  963.                                         ur IN DATE, pesel IN NUMBER, kod IN NUMBER, miejsc IN VARCHAR2, ul IN VARCHAR2) IS
  964. czypozwwbazie NUMBER;
  965. lastidroz NUMBER;
  966. idpoz NUMBER;
  967. BEGIN
  968.     SELECT COUNT(id_pozwanego) INTO czypozwwbazie FROM pozwani WHERE imie = im AND nazwisko = nazw;
  969.     IF czypozwwbazie = 0 THEN
  970.         SELECT MAX(id_pozwanego) INTO idpoz FROM pozwani;
  971.         idpoz := idpoz + 1;
  972.         INSERT INTO pozwani VALUES(idpoz, nazw, im, ur, pesel, kod, miejsc, ul);
  973.     ELSE
  974.         SELECT id_pozwanego INTO idpoz FROM pozwani WHERE imie = im AND nazwisko = nazw;
  975.     END IF;
  976.     SELECT MAX(id_rozprawy) INTO lastidroz FROM rozprawy;
  977.     INSERT INTO rozprawy VALUES (lastidroz+1, idpoz, idtyp, idobs, data, godz, sala);
  978.     EXCEPTION
  979.         WHEN OTHERS THEN DMBS_OUTPUT.PUT_LINE('Error');
  980. END;
  981.  
  982. -- 2. Napisz funkcję, która wyświetli wszystkie rozprawy (nazwisko i imię pozwanego, adwokata oraz termin rozprawy),
  983. -- które odbyły się w zadanym okresie (parametry od i do) oraz obliczy i zwróci ich liczbę. Rozprawy nie mogą się
  984. -- powtarzać i muszą być wyświetlone w porządku odwróconym w stosunku do daty rozprawy.
  985. CREATE OR REPLACE FUNCTION liczbarozpraw(od DATE, DO DATE) RETURN NUMBER IS
  986. liczba NUMBER := 0;
  987. CURSOR kursor IS
  988.     SELECT DISTINCT p.imie, p.nazwisko, r.data, a.imie, a.nazwisko
  989.     FROM rozprawy r
  990.     INNER JOIN pozwani p ON p.id_pozwanego = r.id_pozwanego
  991.     INNER JOIN adwokaci a ON a.id_adwokata = r.id_adwokata
  992.     WHERE r.data >= od AND r.data <= DO
  993.     ORDER BY r.data DESC;
  994. r kursor%ROWTYPE;
  995. BEGIN
  996.     FOR r IN kursor LOOP
  997.         liczba := liczba + 1;
  998.         DBMS_OUTPUT.PUT_LINE('wypisz kolumny');
  999.     END LOOP;
  1000.     RETURN liczba;
  1001. END;
  1002.  
  1003. -- 3. Napisz procedurę, której zadaniem jest wypisanie dla podanego nazwiska i imienia pozwanego (parametry)
  1004. -- informacji o rozprawach, które go dotyczyły. Są to: nazwisko i imię sędziego, typ rozprawy, sala, data godzina.
  1005. -- Informacje te należy wpisać do tabeli historia, której struktura istnieje w bazie danych.
  1006. -- Zaimplementuj obsługę błędów:
  1007. -- a) braku pozwanego o podanym nazwisku;
  1008. -- b) braku rozpraw z jego udziałem;
  1009. -- c) pozostałych błędów. Skorzystaj z wyjątków predefiniowanych
  1010. CREATE OR REPLACE PROCEDURE udzialwrozprawach(im IN VARCHAR2, nazw IN VARCHAR2) IS
  1011. CURSOR kursor IS
  1012.     SELECT s.imie, s.nazwisko, t.nazwa, sa.nazwa, r.data
  1013.     FROM rozprawy r
  1014.     INNER JOIN sale sa ON sa.id_sali = r.id_sali
  1015.     INNER JOIN sedzia s ON s.id_sedzi = r.id_sedzi
  1016.     INNER JOIN typ_rozpr t ON t.id_typ = r.id_typ
  1017.     INNER JOIN pozwani p ON p.id_pozw = r.id_pozw
  1018.     WHERE p.imie = im AND p.nazwisko = nazw;
  1019. liczba NUMBER := 0;
  1020. czypozwwbazie NUMBER;
  1021. brakpozw EXCEPTION;
  1022. brakrozpraw EXCEPTION;
  1023. r kursor%ROWTYPE;
  1024. BEGIN
  1025.     SELECT COUNT(id_pozwany) INTO czypozwwbazie FROM pozwani p WHERE p.imie = im AND p.nazwisko = nazw;
  1026.     IF czypozwwbazie = 0 THEN
  1027.         RAISE brakpozw;
  1028.     ELSE
  1029.         FOR r IN kursor LOOP
  1030.             liczba := liczba + 1;
  1031.             DBMS_OUTPUT.PUT_LINE('wypisz wszystko');
  1032.         END LOOP;
  1033.         IF liczba = 0 THEN
  1034.             RAISE brakrozpraw;
  1035.         END IF;
  1036.     END IF;
  1037.     EXCEPTION
  1038.         WHEN brakpozw THEN DBMS_OUTPUT.PUT_LINE('brak pozwanego');
  1039.         WHEN brakrozpraw THEN DBMS_OUTPUT.PUT_LINE('brak rozpraw');
  1040.         WHEN DATA_NOT_FOUND THEN DBMS_OUTPUT.PUT_LINE('xd');
  1041.         WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('xd');
  1042. END;
  1043.  
  1044. -- 4. Napisz procedurę wyzwalaną, która ma trzymywać liczbę rozpraw w ciągu każdego dnia nieprzekraczającą pewnej
  1045. -- stałej. Zmiany, które mają wpływ na liczbę rozpraw to dodanie nowej rozprawy lub wykreślenie jej z porządku
  1046. -- na dany dzień.
  1047.  
  1048. -- nie bardzo rozumiem, robię tak, że sprawdzam liczbę rozpraw danego dnia i jeżeli jest mniejsza od stałej to dodaje, jak nie to olewam
  1049. CREATE OR REPLACE TRIGGER sprawdzczymoznadodacrozprawetrigger INSTEAD OF INSERT ON rozprawy FOR EACH ROW
  1050.     DECLARE
  1051.         lrozpraw NUMBER := 0;
  1052.         MAX_L_ROZPRAW CONSTANT NUMBER := 10;
  1053.         zaduzo EXCEPTION;
  1054.     BEGIN
  1055.         SELECT COUNT(r.id_rozpr) INTO lrozpraw FROM rozprawy WHERE data = SYSDATE;
  1056.         IF lrozpraw >= MAX_L_ROZPRAW THEN
  1057.             INSERT INTO rozprawy VALUES (:NEW:kolumna, :NEW:kolumna2);
  1058.         ELSE
  1059.             RAISE zaduzo;
  1060.         END IF;
  1061.         EXCEPTION
  1062.         WHEN zaduzo THEN DBMS_OUTPUT.PUT_LINE('xd');
  1063.     END;
  1064.  
  1065. -- KOLOKWIUM II Grupa 4
  1066. -- +---------+-------------+-------------+------------------+-----------------+---------------+
  1067. -- | gatunek | wydawnictwo | ksiazki     | autorzy          | wypozyczenia    | czytelnicy    |
  1068. -- +---------+-------------+-------------+------------------+-----------------+---------------+
  1069. -- | id_gat  | id_wyd      | id_ksiazki  | id_autora        | id_wypozyczenia | id_czytelnika |
  1070. -- | nazwa   | nazwa       | id_autora   | nazwisko         | id_czytelnika   | nazwisko      |
  1071. -- |         |             | tytul       | imię             | id_ksiazki      | imię          |
  1072. -- |         |             | id_gatunku  | kraj_pochodzenia | data_wyp        | data_ur       |
  1073. -- |         |             | ilosc_stron |                  | data_zwr        | pesel         |
  1074. -- |         |             | ISBN        |                  |                 | kod_pocztowy  |
  1075. -- |         |             | cena        |                  |                 | miejscowość   |
  1076. -- |         |             | id_wyd      |                  |                 | ulica         |
  1077. -- |         |             | data_wyd    |                  |                 | kara          |
  1078. -- +---------+-------------+-------------+------------------+-----------------+---------------+
  1079.  
  1080. -- 1. Napisz procedurę  wprowadzającą do tabeli WYPOŻYCZENIA rekord rejestrujący nowe wypożyczenie. Aby można było
  1081. -- zarejestrować nowe wypożyczenie należy sprawdzić, czy czytelnik o podanym nazwisku i imieniu (parametry procedury)
  1082. -- znajduje się już w bazie danych. Jeśli nie należy wprowadzić nowego czytelnika do tabeli CZYTELNICY.
  1083. -- Zaimplementuj obsługę błędów.
  1084. CREATE OR REPLACE PROCEDURE dodajwypozyczenie(im IN VARCHAR2, nazw IN VARCHAR2, idks NUMBER, dwyp DATE, dzwr DATE,
  1085.                                                 dur DATE, pesel NUMBER, kod VARCHAR2, miejsc VARCHAR2, ul VARCHAR2, kara NUMBER) IS
  1086. czywbazie NUMBER;
  1087. idczyt NUMBER;
  1088. idwyp NUMBER;
  1089. BEGIN
  1090.     SELECT COUNT(c.id_czytelnika) INTO czywbazie FROM czytelnicy WHERE imie = im AND nazwisko = nazw;
  1091.     IF czywbazie = 0 THEN
  1092.         SELECT MAX(id_czytelnika) INTO idczyt FROM czytelnicy;
  1093.         idczyt := idczyt + 1;
  1094.         INSERT INTO czytelnicy VALUES (idczyt, nazw, im, dur, pesel, kod, miejsc, ul, kara);
  1095.     ELSE
  1096.         SELECT id_czytelnika INTO idczyt FROM czytelnicy;
  1097.     END IF;
  1098.     SELECT MAX(id_wypozyczenia) INTO idwyp FROM wypozyczenia;
  1099.     INSERT INTO wypozyczenia VALUES(idwyp + 1, idczyt, idks, dwyp, dzwr);
  1100.     EXCEPTION
  1101.         WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('xd');
  1102. END;
  1103.  
  1104. -- 2. Napisz funkcję, która pobierze i wyświetli wszystkie książki, które były w stanie wypożyczenia w zadanym okresie
  1105. -- (parametry od i do) . Książki nie mogą się powtarzać i muszą być wyświetlone w porządku odwróconym w stosunku do
  1106. -- roku wydania. Funkcja ma zwrócić liczbę wypożyczonych książek, które zostały wydane po roku 2015.
  1107. CREATE OR REPLACE FUNCTION liczbawypozyczonychksiazek(od DATE, DO DATE) RETURN NUMBER IS
  1108. liczba NUMBER := 0;
  1109. CURSOR kursor IS
  1110.     SELECT DISTINCT k.tytul, k.data_wyd
  1111.     FROM ksiazki k
  1112.     INNER JOIN wypozyczenia w ON w.id_ksiazki = k.id_ksiazki
  1113.     WHERE k.data_wyp >= od AND k.data_wyp <= DO
  1114.     ORDER BY k.data_wyd DESC;
  1115. r kursor%ROWTYPE;
  1116. BEGIN
  1117.     FOR r IN kursor LOOP
  1118.         IF YEAR(r.data_wyd) > 2015 THEN
  1119.             liczba := liczba + 1;
  1120.         END IF;
  1121.         DBMS_OUTPUT.PUT_LINE('xd');
  1122.     END LOOP;
  1123.     RETURN liczba;
  1124. END;
  1125.  
  1126. -- 3. Napisz procedurę, która dla podanego gatunku literackiego (parametr) wyświetli autora, tytuł, oraz nazwę gatunku
  1127. -- wszystkich książek wydanych  w ciągu ostatniego roku. Dane mają być posortowane alfabetycznie według nazwisk i imion
  1128. -- autorów. Procedura jako parametr wyjściowy ma zwracać liczbę książek z podanego gatunku, która znajduje się w
  1129. -- bibliotece.
  1130. CREATE OR REPLACE PROCEDURE wyswietlinformacjeoksiazce(gat IN VARCHAR2, liczba OUT NUMBER) IS
  1131. CURSOR kursor IS
  1132.     SELECT a.nazwisko, a.imie, k.tytul, g.nazwa
  1133.     FROM ksiazki k
  1134.     INNER JOIN autorzy a ON a.id_autora = k.id_autora
  1135.     INNER JOIN gatunek g ON g.id_gat = k.id_gat
  1136.     WHERE g.nazwa = gat AND YEAR(k.data_wyd) = YEAR(SYSDATE)
  1137.     ORDER BY a.nazwisko, a.imie;
  1138. r kursor%ROWTYPE;
  1139. BEGIN
  1140.     liczba := 0;
  1141.     FOR r IN kursor LOOP
  1142.         liczba := liczba + 1;
  1143.         DBMS_OUTPUT.PUT_LINE('xd');
  1144.     END LOOP;
  1145. END;
  1146.  
  1147. -- 4. Napisz procedurę wyzwalaną, która ma utrzymywać stałą liczbę wypożyczonych książek. Zmiany, które mają wpływ
  1148. -- na liczbę wypożyczonych książek są związane z pożyczaniem i oddawaniem książki lub zakupem nowej.
  1149. -- NIE ROZUMIEM
  1150.  
  1151. -- KOLOKWIUM II Grupa 5
  1152. -- +-------------+--------------+-----------------+-------------+--------------+
  1153. -- | gabinety    | pacjencji    | lekarze         | wizyty      | specjalnosci |
  1154. -- +-------------+--------------+-----------------+-------------+--------------+
  1155. -- | id_gabinetu | id_pacjenta  | id_lekarza      | id_wizyty   | id_spec      |
  1156. -- | nazwa       | nazwisko     | nazwisko        | id_pacjenta | nazwa        |
  1157. -- |             | imię         | imię            | id_lekarza  |              |
  1158. -- |             | data_ur      | id_specjalnosci | id_gabinetu |              |
  1159. -- |             | pesel        |                 | data        |              |
  1160. -- |             | kod_pocztowy |                 | godzina     |              |
  1161. -- |             | miejscowość  |                 |             |              |
  1162. -- |             | ulica        |                 |             |              |
  1163. -- +-------------+--------------+-----------------+-------------+--------------+
  1164.  
  1165. -- 1. Napisz procedurę  wprowadzającą do tabeli WIZYTY rekord rejestrujący nową wizytę. Aby można było zarejestrować
  1166. -- nową wizytę należy sprawdzić, czy pacjent o podanym nazwisku i imieniu (parametry procedury) znajduje się już w
  1167. -- bazie danych. Jeśli nie należy wprowadzić nowego pacjenta do tabeli PACJENCI. Zaimplementuj obsługę błędów.
  1168. -- PRAKTYCZNIE TO SAMO CO W INNYCH GRUPACH
  1169.  
  1170. -- 2. Napisz funkcję, która pobierze i wyświetli wszystkich pacjentów, którzy mieli wizyty w zadanym okresie
  1171. -- (parametry od i do). Należy wypisać nazwisko i imię pacjenta, datę wizyty oraz nazwisko i imię lekarza.
  1172. -- Funkcja ma zwrócić liczbę wizyt, pacjenta, który tych wizyt miał najwięcej.
  1173. -- TO TEŻ JUŻ BYŁO
  1174.  
  1175. -- 3. Napisz procedurę, która wyprowadzi jako parametry wyjściowe nazwisko i imię lekarza, który przyjął największą
  1176. -- liczbę pacjentów. Wewnątrz procedury należy wypisać nazwiska i imiona wszystkich lekarzy wraz z ilością przyjętych
  1177. -- przez nich pacjentów. Dane mają być posortowane alfabetycznie według nazwisk i imion lekarzy.
  1178. CREATE OR REPLACE PROCEDURE najlepszylekarzorazwypiszwszystkichlekarzyprocedura(im OUT VARCHAR2, nazw OUT VARCHAR2, maxlwizyt OUT VARCHAR2) IS
  1179. CURSOR kursor IS
  1180.     SELECT l.imie, l.nazwisko, COUNT(w.id_wizyty) lwizyt
  1181.     FROM lekarze l
  1182.     INNER JOIN wizyty w ON w.id_lekarza = l.id_lekarza
  1183.     ORDER BY l.nazwisko, l.imie;
  1184. r kursor%ROWTYPE;
  1185. BEGIN
  1186.     maxlwizyt := 0;
  1187.     FOR r IN kursor LOOP
  1188.         IF r.lwizyt > maxlwizyt THEN
  1189.             maxlwizyt := r.lwizyt;
  1190.             im := r.imie;
  1191.             nazw := r.nazwisko;
  1192.         END IF;
  1193.         DBMS_OUTPUT.PUT_LINE(r.imie || ' ' || r.nazwisko || ' ' || r.lwizyt);
  1194.     END LOOP;
  1195. END;
  1196.  
  1197.  
  1198. -- 4. Napisz procedurę wyzwalaną, która przed wykonaniem operacji DELETE i INSERT dla każdego wiersza tabeli WIZYTY
  1199. -- doda do tabeli TEST informację w postaci ciągu znaków: „A operacja B” , gdzie operacja to nazwa wykonywanej
  1200. -- operacji, A, B to wartości poszczególnych atrybutów przed wykonaniem operacji i po jej wykonaniu.
  1201. -- Tabela TEST istnieje i ma odpowiednią strukturę
  1202. CREATE OR REPLACE TRIGGER dodajdotablicytestinformacjeooperacjitrigger BEFORE DELETE OR INSERT ON wizyty FOR EACH ROW
  1203.     BEGIN
  1204.         IF DELETING THEN
  1205.             INSERT INTO test VALUES (:OLD.id_wizyty || ' ' || :OLD.id_pacjenta || '... DELETE ' || :NEW.id_wizyty || ' ' || :NEW.id_pacjent || '...');
  1206.         ELSIF INSERTING THEN
  1207.             INSERT INTO test VALUES (:OLD.id_wizyty || ' ' || :OLD.id_pacjenta || '... INSERT ' || :NEW.id_wizyty || ' ' || :NEW.id_pacjent || '...');
  1208.         END IF;
  1209.     END;
  1210.  
  1211. -- 6. Omów wyzwalacze INSTEAD OF oraz dla wielu zdarzeń.
  1212. -- INSTEAD OF:
  1213. -- • Definiowany tylko dla perspektyw
  1214. -- • Wykonywany zamiast polecenia, które uruchomiło
  1215. -- wyzwalacz
  1216. -- • Stosowany najczęściej dla perspektyw złożonych
  1217. -- celem zapewnienia ich modyfikowalności
  1218. -- • Nie można bezpośrednio odwoływać się do
  1219. -- atrybutów perspektywy
  1220.  
  1221. -- DLA WIELU ZDARZEŃ:
  1222. -- AFTER/BEFORE/INSTEAD OF INSERT OR BEFORE OR DELETE
  1223. -- • Uruchamiany przez kilka zdarzeń
  1224. -- • Aby selekcjonować kod, który ma być wykonany w przypadku
  1225. -- wystąpienia określonego zdarzenia używa się zmiennych logicznych
  1226. -- INSERTING, DELETING i UPDATING, które przyjmują wartość
  1227. -- prawdy jeśli zdarzeniem uruchamiającym wyzwalacz jest odpowiednio
  1228. -- zdarzenie INSERT, DELETE bądź UPDATE
  1229.  
  1230.  
  1231. -- KOLOKWIUM III Rózne zadania
  1232. -- Korzystając z pakietu DBMS_SQL napisz procedurę usuwającą tabelę o podanej nazwie będącej parametrem procedury.
  1233. CREATE OR REPLACE PROCEDURE usuntabele(tabela VARCHAR2) IS
  1234.     kursor INTEGER := DBMS_SQL.OPEN_CURSOR;
  1235.     ret INTEGER;
  1236.     stmt VARCHAR2(255);
  1237. BEGIN
  1238.     stmt := 'DROP TABLE :tab';
  1239.     DBMS_SQL.PARSE(kursor, stmt, DBMS_SQL.NATIVE);
  1240.     DBMS_SQL.BIND_VARIABLE(kursor, ':tab', tabela);
  1241.     ret := DBMS_SQL.EXECUTE(kursor);
  1242.     DBMS_SQL.CLOSE_CURSOR(kursor);
  1243. END;
  1244.  
  1245. -- Utworzyć procedurę przyjmującą jako parametry nazwę tabeli i nazwę kolumny. Zapisz w tabeli TEST
  1246. -- (tabela istnieje i jest jednokolumnowa) korzystając z dynamicznego SQL ilości rekordów w tabeli podanej
  1247. -- jako parametr oraz liczbę różnych wartości kolumny podanej jako parametr.
  1248. CREATE OR REPLACE PROCEDURE liczbarekordowiroznychwartosci(tab VARCHAR2, kol VARCHAR2) IS
  1249.     lrekordow INTEGER;
  1250.     lwartosci INTEGER;
  1251.     BEGIN
  1252.         EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || tab INTO lrekordow;
  1253.         EXECUTE IMMEDIATE 'SELECT COUNT(DISTINCT '|| kol || ') FROM ' || tab INTO lwartosci;
  1254.         EXECUTE IMMEDIATE 'INSERT INTO test VALUES(''liczba rekordow: ' || lrekordow || ' liczba wartosci: ' || lwartosci || ''')';
  1255.     END;
  1256.  
  1257.  
  1258. -- Korzystając z pakietu DBMS_SQL napisz procedurę uaktualniając rekord z nazwiskiem KOWALSKA na
  1259. -- KOWALSA_NOWY z tabeli o podanej nazwie będącej parametrem procedury.
  1260. CREATE OR REPLACE PROCEDURE zmiennazwisko(tab VARCHAR2) IS
  1261.     kursor INTEGER := DBMS_SQL.OPEN_CURSOR;
  1262.     stmt VARCHAR2(255);
  1263.     ret INTEGER;
  1264. BEGIN
  1265.     stmt := 'UPDATE :tab SET nazwisko=''KOWALSA NOWY'' WHERE nazwisko=''KOWALSKA''';
  1266.     DBMS_SQL.PARSE(kursor, stmt, DBMS_SQL.NATIVE);
  1267.     DBMS_SQL.BIND_VARIABLE(kursor, ':tab', tab);
  1268.     ret := DBMS_SQL.EXECUTE(kursor);
  1269.     DBMS_SQL.CLOSE_CURSOR(kursor);
  1270. END;
  1271.  
  1272. -- Utworzyć procedurę przyjmującą jako parametry nazwę tabeli i nazwę kolumny typu NUMBER. Korzystając z
  1273. -- dynamicznego SQL policz sumę wartości z kolumny będącej parametrem wywołania oraz liczbę różnych wartości tej
  1274. -- kolumny Wynik zapisz w tabeli jednokolumnowej w postaci np.: SUMA = 34, liczba różnych = 5
  1275. CREATE TABLE tabelka (
  1276.     kolumna VARCHAR2(255) NOT NULL
  1277. );
  1278. CREATE OR REPLACE PROCEDURE sumawartoscikolumny(tab VARCHAR2, kol VARCHAR2) IS
  1279.     suma INTEGER;
  1280.     lwartosci INTEGER;
  1281.     BEGIN
  1282.         EXECUTE IMMEDIATE 'SELECT SUM('|| tab || ',' || kol ||') FROM ' || tab INTO suma;
  1283.         EXECUTE IMMEDIATE 'SELECT COUNT(DISTINCT '|| kol || ') FROM ' || tab INTO lwartosci;
  1284.         EXECUTE IMMEDIATE 'INSERT INTO tabelka VALUES(''SUMA: ' || suma || ', liczba roznych: ' || lwartosci || ''')';
  1285.     END;
  1286.  
  1287. -- Korzystając z pakietu DBMS_SQL napisz procedurę usuwającą rekord z tabeli o podanej nazwie będącej parametrem
  1288. -- procedury
  1289. CREATE OR REPLACE PROCEDURE proceduradousuwaniarekorduzkonkretnejtabeli(tab VARCHAR2, id NUMBER) IS
  1290. kursor INTEGER := DBMS_SQL.OPEN_CURSOR;
  1291. stmt VARCHAR2(255);
  1292. ret INTEGER;
  1293. BEGIN
  1294.     stmt := 'DELETE FROM :tab WHERE id = :id';
  1295.     DBMS_SQL.PARSE(kursor, stmt, DBMS_SQL.NATIVE);
  1296.     DBMS_SQL.BIND_VARIABLE(kursor, ':tab', tab);
  1297.     DBMS_SQL.BIND_VARIABLE(kursor, ':id', id);
  1298.     ret := DBMS_SQL.EXECUTE(kursor);
  1299.     DBMS_SQL.CLOSE_CURSOR(kursor);
  1300. END;
  1301.  
  1302. -- Utworzyć procedurę wypisującą na ekran ilość studentów urodzonych w roku 1990, których imię, nazwisko
  1303. -- pasuje do podanego wzorca.
  1304. CREATE OR REPLACE PROCEDURE iloscstudentowurodzonychwroku1990(im VARCHAR2, nazw VARCHAR2) IS
  1305. liczba NUMBER;
  1306. BEGIN
  1307.     EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM tabela WHERE imie LIKE ' || im || ' AND nazwisko LIKE ' || nazw INTO liczba;
  1308.     DBMS_SQL.PUT_LINE(liczba);
  1309. END;
  1310.  
  1311. -- Omów funkcje i procedury pakietu DBMS_SQL
  1312. -- • Służy do wykonywania dynamicznych zapytań SQL
  1313. -- • Bardziej złożony niż NDS, jednak niezbędny w
  1314. -- szczególnych przypadkach np. gdy lista SELECT jest
  1315. -- nieznana (nieznany zbiór kolumn)
  1316. -- Procedury pakietu:
  1317. -- • DESCRIBE_COLUMNS
  1318. -- • DESCRIBE_COLUMNS2
  1319. -- • OPEN_CURSOR – otwiera nowy kursor i zwraca jego ID (numer)
  1320. -- DBMS_SQL.OPEN_CURSOR RETURN INTEGER;
  1321. -- • CLOSE_CURSOR – zamyka kursor
  1322. -- • EXECUTE – wykonuje kursor (podany przez ID) i zwraca liczbę
  1323. -- przetworzonych wierszy
  1324. -- • EXECUTE_AND_FETCH – uruchamia instrukcję powiązana z
  1325. -- otwartym kursorem DBMS_SQL i pobiera z niego wiersze
  1326. -- • IS_OPEN – sprawdza, czy podany kursor jest otwarty
  1327. -- • DEFINE_COLUMN – definiuje kolumny, które mają być
  1328. -- pobrane z kursora
  1329. -- • PARSE – dokonanie analizy i weryfikacji zapytania SQL
  1330. -- • BIND_VARIABLE – wiąże podane wartości ze zmiennymi w kursorze
  1331. -- • FETCH_ROWS – pobiera wiersze z kursora o danym ID
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement