/*
A
Nom et prénom : [Votre nom]
Groupe : [Votre groupe]
Salle TP : [Votre salle]
Nom du voisin de gauche : [Nom]
Nom du voisin de droite : [Nom]
*/ 




-- Exercice 1 : 4pts

1- Lister tous les emprunts en cours une date_retour qui a une valeur nulle. Vous devez afficher le titre du livre, le nom et le prenom de l'auteur et le membre_id.
2- Afficher tous les livres qui ont été empruntés pour une durée supérieure à 25 jours


-- 1. Liste des emprunts en cours (date_retour NULL)

SELECT l.titre, a.nom, a.prenom, e.membre_id
FROM Emprunts e
JOIN Livres l ON e.livre_id = l.livre_id
JOIN Auteurs a ON l.auteur_id = a.auteur_id
WHERE e.date_retour IS NULL;


-- 2. Livres empruntés >25 jours (supposant date_retour renseignée)

SELECT l.titre, a.nom, a.prenom
FROM Emprunts e
JOIN Livres l ON e.livre_id = l.livre_id
JOIN Auteurs a ON l.auteur_id = a.auteur_id
WHERE (e.date_retour - e.date_emprunt) > 25;




-- Exercice 2 : 2pts

Créer une séquence Livres_seq qui a pour première valeur 12 et s'incrémente de 1.


CREATE SEQUENCE Livres_seq START WITH 12 INCREMENT BY 1;




-- Exercice 3 : 5pts

Créer une procédure AjouterLivre(p_titre VARCHAR2, p_auteur_id INT, p_annee_publication INT, p_genre VACHAR2. p_stock INT) qui permet d'ajouter un nouveau livre à la bibliothèque.
- Servez-vous de la séquence précédemment créée pour l'insertion de Livre_id.
- Traitez le cas où l'auteur du livre à insérer n'existe pas dans la table Auteurs.


CREATE OR REPLACE PROCEDURE AjouterLivre(
    p_titre VARCHAR2,
    p_auteur_id INT,
    p_année_publication INT,
    p_genre VARCHAR2,
    p_stock INT
) IS
    v_auteur_count INT;
BEGIN
    -- Vérifier si l'auteur existe
    SELECT COUNT(*) INTO v_auteur_count FROM Auteurs WHERE auteur_id = p_auteur_id;
    IF v_auteur_count = 0 THEN
        RAISE_APPLICATION_ERROR(-20001, 'L''auteur n''existe pas.');
    END IF;

    -- Insertion avec la séquence
    INSERT INTO Livres (livre_id, titre, auteur_id, année_publication, genre, stock)
    VALUES (Livres_seq.NEXTVAL, p_titre, p_auteur_id, p_année_publication, p_genre, p_stock);
END;
/




-- Exercice 4 : 4pts

Créer une fonction fn_nombre_livres_empruntes(p_membre_id INT) qui retourne le nombre de livres empruntés par un membre.
Pour chaque membre présent dans la table Emprunt, afficher le nombre de livres empreintés.


CREATE OR REPLACE FUNCTION fn_nombre_livres_empruntes(p_membre_id INT)
RETURN INT IS
    v_count INT;
BEGIN
    SELECT COUNT(*) INTO v_count
    FROM Emprunts
    WHERE membre_id = p_membre_id AND date_retour IS NULL;
    RETURN v_count;
END;
/

-- Afficher pour chaque membre dans Emprunts
SELECT DISTINCT membre_id, fn_nombre_livres_empruntes(membre_id) AS nombre_emprunts
FROM Emprunts;




-- Exercice 5 : 5pts

Créer un trigger trg_decremente_stock_emprunt qui permettra de gérer le stock des livres ; il s'exécutera avant l'insertion d'un nouvel emprunt et devra faire les vérifications ci-dessous:
- Il vérifie que le stock est supérieur à 0: si c'est le cas, il décrémente de 1.
- Une personne ne peut pas empreinte plus de 2 livres.
- Si le stock est égal à 0, le trigger lève une erreur et empêche l'emprunt.


CREATE OR REPLACE TRIGGER trg_decremente_stock_emprunt
BEFORE INSERT ON Emprunts
FOR EACH ROW
DECLARE
    v_stock INT;
    v_emprunts_count INT;
BEGIN
    -- Vérifier le stock
    SELECT stock INTO v_stock
    FROM Livres
    WHERE livre_id = :NEW.livre_id;

    IF v_stock <= 0 THEN
        RAISE_APPLICATION_ERROR(-20002, 'Stock épuisé.');
    END IF;

    -- Vérifier le nombre d'emprunts du membre
    SELECT COUNT(*) INTO v_emprunts_count
    FROM Emprunts
    WHERE membre_id = :NEW.membre_id AND date_retour IS NULL;

    IF v_emprunts_count >= 2 THEN
        RAISE_APPLICATION_ERROR(-20003, 'Limite de 2 emprunts atteinte.');
    END IF;

    -- Décrémenter le stock
    UPDATE Livres
    SET stock = stock - 1
    WHERE livre_id = :NEW.livre_id;
END;
/




-- Cas de tests


-- Test Exercice 1.1 :
-- INSERT INTO Emprunts (emprunt_id, livre_id, membre_id, date_emprunt, date_retour) VALUES (1, 101, 1, SYSDATE - 10, NULL);
-- Résultat attendu : L'emprunt apparaît dans la liste.


-- Test Exercice 1.2 :
-- INSERT INTO Emprunts (emprunt_id, livre_id, membre_id, date_emprunt, date_retour) VALUES (2, 102, 2, SYSDATE - 30, SYSDATE);
-- Résultat attendu : Le livre apparaît dans la liste.


-- Test Exercice 3 :
-- EXEC AjouterLivre('Nouveau Livre', 999, 2024, 'Roman', 5); -- Doit échouer si l'auteur 999 n'existe pas.


-- Test Exercice 5 :
-- INSERT INTO Emprunts (emprunt_id, livre_id, membre_id, date_emprunt) VALUES (3, 103, 3, SYSDATE); -- Doit échouer si stock = 0 ou si le membre a déjà 2 emprunts.