All pastes #50015 Raw Edit

Anonymous

public text v1 · immutable
#50015 ·published 2006-04-19 21:34 UTC
rendered paste body
CREATE OR REPLACE PACKAGE BODY unterricht_pkg_tw04n166 AS

    -- Prozedur, um die Vortragenden eines Faches zu entfernen
    PROCEDURE drop_fachzuordnung(mykbz IN VARCHAR)
    IS
        CURSOR GET_VORTRAGENDE IS   -- Cursor ueber alle Vortragenden des Faches vom Studienjahr
            SELECT personal_tw04n166.personen_id, personal_tw04n166.stunden
            FROM personal_tw04n166
            JOIN unterricht ON personal_tw04n166.personen_id = unterricht.personen_id
            JOIN faecher ON unterricht.fach_id = faecher.fach_id
            WHERE faecher.kbz = mykbz AND unterricht.studienjahr = p_studienjahr;

            myfach_id faecher.fach_id%TYPE := 0;
            mystunden INT := 0;
            result_votragende GET_VORTRAGENDE%ROWTYPE;
            myname VARCHAR(50);
    BEGIN

        -- Ueberpruefung, ob ein gueltiges Studienjahr angegeben wurde
        IF NOT check_studienjahr THEN
            DBMS_OUTPUT.PUT_LINE('Package besitzt kein gueltiges Studienjahr!');
            RETURN;
        END IF;

        -- pruefe, ob uebergebenes Fach existiert
        BEGIN
            SELECT fach_id INTO myfach_id
            FROM faecher
            WHERE kbz = mykbz;

            EXCEPTION
                WHEN NO_DATA_FOUND THEN
                    DBMS_OUTPUT.PUT_LINE('Das Fach "' || mykbz || '" existiert nicht.');
                    RETURN;
        END;

        --DBMS_OUTPUT.PUT_LINE(mykbz);

        OPEN GET_VORTRAGENDE;
        LOOP
            FETCH GET_VORTRAGENDE INTO result_votragende;
            EXIT WHEN GET_VORTRAGENDE%NOTFOUND;

            -- Update der Stunden
            
            update_stunden(result_votragende.personen_id);
            

            -- Ueberpruefung der gefundenen Lektoren:

            /*DBMS_OUTPUT.PUT_LINE(result_votragende.personen_id);
              SELECT personen.name INTO myname
              FROM personen WHERE personen.personen_id = result_votragende.personen_id;
              DBMS_OUTPUT.PUT_LINE(myname);*/

        END LOOP;
        CLOSE GET_VORTRAGENDE;

        -- loeschen der Lektor-Relation in der Unterricht-Tabelle
        DELETE FROM unterricht_tw04n166
        WHERE fach_id = myfach_id AND studienjahr = p_studienjahr;

    END drop_fachzuordnung;

    -- Prozedur, um das Studienjahr zu setzen
    PROCEDURE set_studienjahr(jahr IN INT) IS
    BEGIN
        p_studienjahr := jahr;

        EXCEPTION
            WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Fehler beim Setzen des Studienjahres!');
    END set_studienjahr;

    -- Funktion, die das gesetzte Studienjahr zurueckliefert
    FUNCTION get_studienjahr RETURN INT
    IS
    BEGIN
        RETURN p_studienjahr;
    END get_studienjahr;

    -- Funktion, die ueberprueft, ob das gesetzte Studienjahr verfuegbar ist
    FUNCTION check_studienjahr RETURN BOOLEAN
    IS
        CURSOR GET_STUDIENJAHRE IS
            SELECT studienjahr FROM unterricht;
        mystudienjahr unterricht.studienjahr%TYPE;
    BEGIN

        IF p_studienjahr = 0 THEN     -- studienjahr ist auf default-Wert --> wurde noch nicht gesetzt
            RETURN FALSE;
        END IF;

        OPEN GET_STUDIENJAHRE;
        LOOP

            FETCH GET_STUDIENJAHRE INTO mystudienjahr;
            EXIT WHEN GET_STUDIENJAHRE%NOTFOUND;

            IF mystudienjahr = p_studienjahr THEN     -- gueltiges studienjahr
                CLOSE GET_STUDIENJAHRE;
                RETURN TRUE;
            END IF;

        END LOOP;
        CLOSE GET_STUDIENJAHRE;

        RETURN FALSE;   -- kein gueltiges studienjahr gefunden
    END check_studienjahr;

    -- aktualisiert die Anzahl der unterrichtenden Stunden fuer einen Vortragenden
    PROCEDURE update_stunden(vortragender_id IN INT)
    IS
        mystunden faecher.stunden%TYPE;
        myid personal_tw04n166.personen_id%TYPE;
    BEGIN

        -- Ueberpruefung, ob ein gueltiges Studienjahr angegeben wurde
        IF NOT check_studienjahr THEN
            DBMS_OUTPUT.PUT_LINE('Das Package besitzt kein gueltiges Studienjahr!');
            RETURN;
        END IF;

        -- pruefe, ob zu uebergebener ID ein Vortragender existiert
        BEGIN
            SELECT personen_id INTO myid
            FROM personal_tw04n166
            WHERE personen_id = vortragender_id;

            EXCEPTION
                WHEN NO_DATA_FOUND THEN
                    DBMS_OUTPUT.PUT_LINE('Ein Vortragender mit der ID: ' || vortragender_id || ' existiert nicht!');
                    RETURN;
        END;

        BEGIN
            -- Stunden berechnen
            SELECT sum(faecher.stunden) INTO mystunden
            FROM personal_tw04n166
            JOIN unterricht_tw04n166 ON personal_tw04n166.personen_id = unterricht_tw04n166.unterricht_id
            JOIN faecher ON unterricht_tw04n166.fach_id = faecher.fach_id
            WHERE unterricht_tw04n166.studienjahr = p_studienjahr AND personal_tw04n166.personen_id = vortragender_id;

            IF mystunden IS NULL THEN
                --DBMS_OUTPUT.PUT_LINE('Stunden fuer den Vortragenden mit der ID: ' || vortragender_id || ' konnten nicht aktualisiert werden!');
                --RETURN;
                mystunden := 0;
            END IF;

            --DBMS_OUTPUT.PUT_LINE('Stunden: ' || mystunden);

            -- Stunden aktualisieren
            UPDATE personal_tw04n166
            SET stunden = mystunden
            WHERE personen_id = vortragender_id;

            EXCEPTION
                WHEN NO_DATA_FOUND THEN
                    DBMS_OUTPUT.PUT_LINE('Stunden fuer den Vortragenden mit der ID: ' || vortragender_id || ' konnten nicht aktualisiert werden!');
                WHEN OTHERS THEN
                    DBMS_OUTPUT.PUT_LINE('Fehler bei der Aktualisierung der Stunden des Vortragenden mit der ID: ' || vortragender_id || '!');
        END;

    END update_stunden;

    -- Prozedur, die einen Lektor einem zu unterrichtenden Fach zuordnet (sofern nicht voll besetzt)
    PROCEDURE assign_lektor_to_fach(myname IN VARCHAR, mykbz IN VARCHAR)
    IS
        mylektor_id personal_tw04n166.personen_id%TYPE;
        myfach_id faecher.fach_id%TYPE;
        lektor_summe INT := 0;
    BEGIN

        -- Ueberpruefung, ob ein gueltiges Studienjahr angegeben wurde
        IF NOT check_studienjahr THEN
            DBMS_OUTPUT.PUT_LINE('Das Package besitzt kein gueltiges Studienjahr!');
            RETURN;
        END IF;

        -- ID des Vortragenden ermitteln
        BEGIN
            SELECT personal_tw04n166.personen_id INTO mylektor_id
            FROM personal_tw04n166
            JOIN personen ON personal_tw04n166.personen_id = personen.personen_id
            WHERE personen.name = myname;

            EXCEPTION
                WHEN NO_DATA_FOUND THEN
                    DBMS_OUTPUT.PUT_LINE('Der Vortragende "' || myname || '" konnte nicht gefunden werden!');
                    RETURN;
        END;

        -- ID des Faches ermitteln
        BEGIN
            SELECT fach_id INTO myfach_id
            FROM faecher
            WHERE kbz = mykbz;

            EXCEPTION
                WHEN NO_DATA_FOUND THEN
                    DBMS_OUTPUT.PUT_LINE('Das Fach "' || mykbz || '" konnte nicht gefunden werden!');
                    RETURN;
        END;

        -- Ueberpruefung, ob der Vortragende bereits dem Fach zugeordnet ist
        DECLARE
            zuordnung_exists INT := 0;
        BEGIN
            SELECT COUNT(*) INTO zuordnung_exists
            FROM unterricht_tw04n166
            WHERE personen_id = mylektor_id AND fach_id = myfach_id;

            IF zuordnung_exists > 0 THEN
                DBMS_OUTPUT.PUT_LINE('Der Vortragende "' || myname || '" ist dem Fach "' || mykbz || '" bereits zugeteilt!');
                RETURN;
            END IF;

            EXCEPTION
                WHEN NO_DATA_FOUND THEN null;
        END;

        -- Anzahl der Vortragenden ermitteln
        BEGIN
            SELECT COUNT(personen_id) INTO lektor_summe
            FROM unterricht_tw04n166
            WHERE fach_id = myfach_id AND studienjahr = p_studienjahr;

            --DBMS_OUTPUT.PUT_LINE('Summe: ' || lektor_summe);
           
            IF lektor_summe > 3 THEN    -- max. Anzahl kontrollieren
                DBMS_OUTPUT.PUT_LINE('Die maximale Anzahl der Vortragenden (4) vom Fach "' || mykbz || '" ist bereits erreicht!');
                RETURN;
            END IF;

            EXCEPTION
                WHEN OTHERS THEN
                    DBMS_OUTPUT.PUT_LINE('Fehler beim Ermitteln der Anzahl der Vortragenden zum Fach "' || mykbz || '"!');
        END;

        -- Tupel in die Unterricht-Tabelle einfuegen
        DECLARE
            max_id INT := 0;--unterricht_tw04n166.unterricht_id%TYPE;
            myreihung unterricht_tw04n166.reihung%TYPE;
        BEGIN
            -- hoechsten PK-Wert in der Tabelle unterricht_tw04n166 fuer das Einfuegen vormerken und dann um eins erhoehen (neuer Index fuer den PK)
            SELECT MAX(unterricht_id) INTO max_id
            FROM unterricht_tw04n166;

            max_id := max_id + 1;
            myreihung := lektor_summe + 1;

            -- Zuordnung erstellen
            INSERT INTO unterricht_tw04n166(unterricht_id, personen_id, fach_id, studienjahr, reihung)
            VALUES (max_id, mylektor_id, myfach_id, p_studienjahr, myreihung);

            -- Stunden updaten
            update_stunden(mylektor_id);

            EXCEPTION
                WHEN OTHERS THEN
                    DBMS_OUTPUT.PUT_LINE('Fehler beim Erstellen der Zuordnung zwischen dem Vortragenden "' || myname || '" und dem Fach "' || mykbz || '"!');
        END;

    END assign_lektor_to_fach;

    -- Prozedur, die die Anzahl der im Studienjahr unzugeordneten Faecher ausgibt
    PROCEDURE print_unassigned_faecher
    IS
        summe_gesamt INT := 0;
        summe_assigned INT := 0;
        diff INT := 0;
    BEGIN

        -- Ueberpruefung, ob ein gueltiges Studienjahr angegeben wurde
        IF NOT check_studienjahr THEN
            DBMS_OUTPUT.PUT_LINE('Das Package besitzt kein gueltiges Studienjahr!');
            RETURN;
        END IF;

        SELECT COUNT(*) INTO summe_gesamt   -- alle Faecher
        FROM faecher;

        SELECT DISTINCT COUNT(faecher.kbz) INTO summe_assigned  -- zugeordnete Faecher
        FROM faecher
        JOIN unterricht_tw04n166 ON faecher.fach_id = unterricht_tw04n166.fach_id
        WHERE unterricht_tw04n166.studienjahr = p_studienjahr;

        diff := summe_gesamt - summe_assigned;
        DBMS_OUTPUT.PUT_LINE('Summe der unzugeordneten Faecher im Jahr ' || p_studienjahr || ': ' || diff);

        EXCEPTION
            WHEN OTHERS THEN
                DBMS_OUTPUT.PUT_LINE('Fehler beim ermitteln der unzugeordneten Stunden vom Studienjahr ' || p_studienjahr || '!');

    END print_unassigned_faecher;

    -- Prozedur, um die Arbeitstabelle, mit der die Lehrfaecherverteilung generiert werden kann, mit den notwendigen Daten des aktuelle Studienjahres zu fuellen
    PROCEDURE fill_arbeitstabelle
    IS
    BEGIN
    
        -- Ueberpruefung, ob ein gueltiges Studienjahr angegeben wurde
        IF NOT check_studienjahr THEN
            DBMS_OUTPUT.PUT_LINE('Das Package besitzt kein gueltiges Studienjahr!');
            RETURN;
        END IF;

        -- alte Eintraege des Studienjahres zuerst entfernen
        DELETE FROM arbeit_tw04n166 WHERE studienjahr = p_studienjahr;

        -- Arbeitstabelle fuellen
        INSERT INTO arbeit_tw04n166(personen_id, fach_id, semester, studienjahr, stunden)
        SELECT u.personen_id, u.fach_id, u.semester, u.studienjahr, faecher.stunden
        FROM unterricht_tw04n166 u
        JOIN faecher ON u.fach_id = faecher.fach_id
        WHERE u.studienjahr = p_studienjahr;

        EXCEPTION
            WHEN OTHERS THEN
                DBMS_OUTPUT.PUT_LINE('Fehler beim Fuellen der Arbeitstabelle!');
        
    END fill_arbeitstabelle;

    -- Prozedur, um die Stunden aus der Arbeitstabelle in die Kreuztabelle einzufuegen
    PROCEDURE create_verteilung
    IS
        CURSOR GET_FAECHER IS
            SELECT DISTINCT arbeit_tw04n166.fach_id, faecher.kbz
            FROM arbeit_tw04n166
            JOIN faecher ON arbeit_tw04n166.fach_id = faecher.fach_id
            WHERE studienjahr = p_studienjahr;

         CURSOR GET_VORTRAGENDE IS
            SELECT DISTINCT personen_id
            FROM arbeit_tw04n166;

         result_faecher GET_FAECHER%ROWTYPE;
         mylektor_id arbeit_tw04n166.personen_id%TYPE;
         mystunden arbeit_tw04n166.stunden%TYPE;

         TYPE stunden_array IS TABLE OF FLOAT INDEX BY BINARY_INTEGER;      -- Array mit allen Stunden eines Faches (5 Lektoren)
         lektor_stunden stunden_array;
         i INT := 0;    -- Indexvariable fuer das Array 
    BEGIN

        -- Ueberpruefung, ob ein gueltiges Studienjahr angegeben wurde
        IF NOT check_studienjahr THEN
            DBMS_OUTPUT.PUT_LINE('Das Package besitzt kein gueltiges Studienjahr!');
            RETURN;
        END IF;

        DELETE FROM kreuztabelle_tw04n166;  -- Tabelle leeren

        -- alle Faecher durchlaufen
        OPEN GET_FAECHER;
        LOOP
            FETCH GET_FAECHER INTO result_faecher;
            EXIT WHEN GET_FAECHER%NOTFOUND;

            i := 0;     -- Indexvariable fuer das Array zuruecksetzen

            -- alle Lektoren durchlaufen
            OPEN GET_VORTRAGENDE;
            LOOP
                FETCH GET_VORTRAGENDE INTO mylektor_id;
                EXIT WHEN GET_VORTRAGENDE%NOTFOUND;

                BEGIN 
                    -- Stunden ermitteln
                    SELECT stunden INTO mystunden
                    FROM arbeit_tw04n166
                    WHERE fach_id = result_faecher.fach_id AND personen_id = mylektor_id;

                    -- wenn beim Fach zu dem Lektor keine Stunden gefunden wurden, Stunden auf 0 setzen
                    EXCEPTION
                        WHEN NO_DATA_FOUND THEN
                            mystunden := 0;
                END;

                -- Stunden des aktuellen Lektors ins Array schreiben
                i := i + 1;
                lektor_stunden(i) := mystunden;
            END LOOP;
            CLOSE GET_VORTRAGENDE;

            -- Werte in die Kreuztabelle einfuegen
            INSERT INTO kreuztabelle_tw04n166
            VALUES(result_faecher.fach_id, result_faecher.kbz, lektor_stunden(1), lektor_stunden(2), lektor_stunden(3), lektor_stunden(4), lektor_stunden(5));

        END LOOP;
        CLOSE GET_FAECHER;

        EXCEPTION
            WHEN OTHERS THEN
                DBMS_OUTPUT.PUT_LINE('Die Lehrfaecherverteilung konnte nicht erstellt werden!');

    END create_verteilung;

END unterricht_pkg_tw04n166;