Pracuję nad projektem aplikacji ankiet uczelnianych. Opracowałem schemat bazy danych. Niestety nie mogę sobie poradzić z transakcjami do procedur i funkcji.
Bardzo proszę o pomoc w utworzeniu poziomów izolacji transakcji i informację dlatego tak a nie inaczej. Wszędzie wydaje mi się sensowne jedynie read commited :/
OPIS TABEL:
ankiety_wypelnione - przechuje informacje o tym, kto wypełnił ankietę ( później nie może już jej wyświetlić )
historia - zapisuje informacje o zmianach ( w nazwach ankiety, treści pytania )
pytania - przechowuje pytania przypisane do ankiet
pytania_typy - przechowuje informacje o typach pytań ( taknie, ocena, tekstowa itp; w każdej chwili można dodać nowe typy )
odpowiedzi - tabela odpowiedzi do pytań ( anonimowe, nie można wiedzieć jaki użytkownik udzielił daną odpowiedź )
odpowiedzi_archiwum - tabelka archiwalna wypełniana co określony czas za pomocą eventu
ankiety - przechowuje informacje o utworzonych ankietach ( nazwa, data otwarcia, data zamknięcia, informacja o tym do jakiego przedmiotu ją przypisujemy )
uzytkownicy - tabelka do zalogowania, konta użytkowników ( wspólna dla studentów, pracowników, administratorów itd )
uzytkownicy_typy - typy użytkowników ( np: student, wykładowca, administrator itd; w kazdej chwili można dodać nowe typy )
prowadzacy - tabela przypisuje użytkowników ( wykładowców ) do przedmiotów na danych wydziałach i kierunkach ( prowadzący może prowadzić wiele przedmiotów na różnych wydziałach, przedmioty mogą mieć wielu prowadzących )
studenci_przedmioty - przypisujemy studentów do przedmiotów na danych kierunkach ( po to aby móc wyświetlić im stosowne ankiety )
kierunki_przedmioty - tabelka złączeniowa przypisująca przedmioty do kierunków
przedmioty - tabela przechowuje przedmioty
kierunki - tabela kierunków ( są przypisane do wydziałów )
wydziały - tabela wydziałów
OPIS PROCEDUR I FUNKCJI:
archiwizuj_odpowiedzi - procedura wywoływana raz w roku co event, przenosi stare odpowiedzi do archiwum
dodaj_studenta - procedura dodawania nowego studenta
ile_uprawnionych - funkcja zwracająca liczbę uprawnionych do wypełnienia ankiety
ile_wypełniło - funkcja zwraca liczbę osób, które wypełniło ankietę
odpowiedz - procedura odpowiedzi na dane pytanie
srednia_pytania - funkcja zwraca średnią liczbę oceń dla pytań typu "ocena"
zaktualizuj_pytanie - funkcja umożliwiająca aktualizację treść pytania, jeśli nikt jeszcze nie udzielił na nie odpowiedzi

CREATE PROCEDURE `archiwizuj_odpowiedzi`() BEGIN SET session transaction isolation level READ committed; INSERT INTO odpowiedzi_archiwum SELECT * FROM odpowiedzi WHERE odpowiedzi_data < DATE_SUB(CURDATE(), INTERVAL 1 YEAR); DELETE FROM odpowiedzi WHERE odpowiedzi_data < DATE_SUB(CURDATE(), INTERVAL 1 YEAR); commit; END CREATE PROCEDURE `dodaj_studenta`(`login` varchar(50),`haslo` varchar(50),`email` varchar(50),`imie` varchar(50),`nazwisko` varchar(80),`typ` varchar(30)) BEGIN DECLARE TYPY_ID INTEGER; DECLARE USER_COUNT INTEGER; SET session transaction isolation level READ uncommitted; SELECT uzytkownicytypy_id INTO TYPY_ID FROM uzytkownicy_typy WHERE uzytkownicytypy_nazwa = typ; SELECT COUNT(*) INTO USER_COUNT FROM uzytkownicy WHERE uzytkownicy_login = login OR uzytkownicy_email = email; IF TYPY_ID > 0 AND USER_COUNT = 0 THEN INSERT INTO uzytkownicy(uzytkownicy_id,uzytkownicy_login,uzytkownicy_haslo,uzytkownicy_email,uzytkownicy_imie,uzytkownicy_nazwisko,uzytkownicytypy_id) VALUES(NULL,login,haslo,email,imie,nazwisko,TYPY_ID); END IF; commit; END CREATE FUNCTION `ile_uprawnionych`(`ankieta` int) RETURNS int(11) BEGIN declare studenci int; declare kierunek int; declare kierunkiprzedmioty int; SELECT kierunkiprzedmioty_id INTO kierunkiprzedmioty FROM ankiety WHERE ankiety_id = ankieta; SELECT count(studenciprzedmioty_id) INTO studenci FROM studenci_przedmioty WHERE kierunkiprzedmioty_id = kierunkiprzedmioty; RETURN studenci; END CREATE FUNCTION `ile_wypelnilo`(`ankieta` int) RETURNS int(11) BEGIN declare liczba int; SELECT count(*) INTO liczba FROM ankiety_wypelnione WHERE ankiety_id = ankieta; RETURN liczba; END CREATE PROCEDURE `odpowiedz`(`pytanie` int, `odpowiedz` varchar(500)) BEGIN declare ocena int; declare typ int; declare odp varchar(500); SET odp = cast(odpowiedz AS UNSIGNED); SET session transaction isolation level READ committed; SELECT pytaniatypy_id INTO ocena FROM pytania_typy WHERE pytaniatypy_nazwa = 'ocena'; SELECT pytaniatypy_id INTO typ FROM pytania WHERE pytania_id = pytanie; IF pytanie > 0 then IF typ = ocena then IF odp > 0 then INSERT INTO odpowiedzi (odpowiedzi_id,pytania_id,odpowiedzi_tresc,odpowiedzi_data) VALUES(NULL,pytanie,odpowiedz,NOW()); end IF; else INSERT INTO odpowiedzi (odpowiedzi_id,pytania_id,odpowiedzi_tresc,odpowiedzi_data) VALUES(NULL,pytanie,odpowiedz,NOW()); end IF; end IF; commit; END CREATE FUNCTION `srednia_pytania`(`pytania` int) RETURNS int(11) BEGIN declare liczba int; SELECT avg(odpowiedzi.odpowiedzi_tresc) INTO liczba FROM odpowiedzi, pytania WHERE pytania.pytaniatypy_id = 2 AND odpowiedzi.pytania_id = pytania; RETURN liczba; END CREATE PROCEDURE `zaktualizuj_pytanie`(`pytanie` int,`tresc` varchar(255)) BEGIN declare lo integer; SET session transaction isolation level READ committed; SELECT count(*) INTO lo FROM odpowiedzi WHERE pytania_id = pytanie; IF lo = 0 then UPDATE pytania SET pytania_tresc = tresc WHERE pytania_id = pytanie; end IF; commit; END