Vous êtes sur la page 1sur 7

Correction liste des exercices

Schéma relationnel de la base :


abonne (num_abonne, nom, prenom,email,type_abonnee)
livre (cote,titre,nb_livre_total,nb_livre_disponible)
emprunter (#num_abonne,#cote,date_emprunt, date_retour)
sanctions (#num_abonne,#cote,date_deb_sanction, date_fin_sanction)

NB : Dans la relation abonnee le champ type_abonnee détermine si l’abonné est un étudiant


ou un enseignant.
La durée de d’emprunt d’un livre pour un enseignant est de 7 jours.
La durée de d’emprunt d’un livre pour un étudiant est de 3 jours.
La valeur de la date système sous oracle est : sysdate.

Exercice 2:

Ecrire un bloc PL/SQL qui affiche toutes les opérations d’emprunts effectués par les abonnées
entre deux dates données (les deux dates seront choises par le développeur). Vous allez
afficher les numéros, nom et prénom de chaque abonné suivi des livres empruntés. Vous allez
afficher le cote du livre emprunté, la date de début emprunt et la date de retour.

Declare

CURSOR c_ab IS

SELECT * FROM abonne;

CURSOR c_emp (p_num number) IS

SELECT cote, date_emprunt, date_retour FROM emprunter WHERE num_abonne=p_num ;

V_date_deb date ;

V_date_fin date ;

BEGIN

V_date_deb = to_date(’01/10/2019’,DD/MM/YYYY);

V_date_fin = to_date(’31/10/2019’,DD/MM/YYYY);

For v_ab IN c_ab loop

DBMS_OUTPUT.PUT_LINE(‘Abonne N°: ’||v_ab.num_abonne||’Nom: ’||v_ab.nom||’Prénom:


’||v_ab.prenom);

For v_emp IN c_emp (v_ab.abonne) loop

If (v_emp.date_emprunt BETWEEN v_date_deb AND v_date_from) then


DBMS_OUTPUT.PUT_LINE(‘Livre: ’||v_emp.cote||’Date emprunt:
’||v_emp.date_emprunt||’Retour: ’||v_emp.date_retour);

End if;

End loop;

End loop;

End;

Exercice 4:

Ecrire un bloc PL/SQL qui affiche toutes les opérations d’emprunts effectués par les
abonnées et qui ont entrainé des retards. Vous allez afficher les numéros, nom et prénom de
chaque abonné suivi des livres empruntés et non rendus dans les délais. Vous allez afficher le
cote du livre emprunté, la date de début emprunt et la date de retour si le livre est rendu.
Un abonné est en retard si la date du jour (sysdate) est supérieure à la date d’emprunt plus la
durée d’emprunt et le champ date retour est vide (NULL) OU la date de retour est supérieure
à la date emprunt plus la durée.

Declare

CURSOR c_ab IS

SELECT * From abonne;

CURSOR c_emp (p_num number) IS

SELECT cote, date_emp, date_retour

From emprunter e, abonne a

Where e.num abonne = a.num_abonne

AND type_abonne = ‘etudiant’

AND date_retour > date_emprunt + 3

OR (date_retour=NULL AND sysdate > date_emprunt + 3)

AND e.num_abonne = p_num

UNION

SELECT cote, date_emprunt, date_retour

From abonne a, emprunter e

WHERE a.num_abonne = e.num_abonne

AND type_abonne = ‘enseignant’ AND date_retour > date_emprunt + 7

OR (date_retour = NULL AND sysdate > date_emprunt + 7) AND e.num_abonne = p_num ;


BEGIN

For v_ab IN c_ab loop

DBMS_OUTPUT.PUT_LINE(‘Abonne N°: ’||v_ab.num_abonne||’Num: ’||v_ab.nom);

For v_emp IN c_emp (v_ab.num_abonne) loop

DBMS_OUTPUT.PUT_LINE(‘Livre’||v_emp.cote||’Date emprunt: ’||v_emp.date_emprunt||’Date


retour: ’||v_emp.date_retour);

End loop;

End loop;

End;

Exercice 5:

Ecrire une fonction qui prend en paramètre le numéro d'un abonné et retourne le nombre de
fois ou il n'a pas rendu un livre dans les délais.
Un abonné est en retard si la date du jour (sysdate) est supérieure à la date d’emprunt plus la
durée d’emprunt et le champ date retour est vide (NULL) OU la date de retour est supérieure
à la date emprunt plus la durée.

Create OR replace function nb_retard(p_num number) return number IS

V_delai number;

V_count number;

V_type varchar(30);

BEGIN

SELECT type_abonne INTOv_type From abonne WHERE num_abonne=p_num;

If(v_type = ‘etudiant’) then v_delai:=3;

Else v_delai := 7;

End if;

SELECT count(*) INTO v_count FROM emprunter

WHERE num_abonne=p_num

AND date_retour > date_emprunt + v_delai OR (date_retour = NULL AND sysdate > date_emprunt +
v_delai);

Return (v_count);

End;
Exercice 6:

Ecrire une fonction qui prend en paramètre le cote d'un livre et retourne le numéro de l'abonné
qui l'a emprunté le plus.

Create OR replace function abonnePlusEmprunt(p_cote varchar2) return number IS

CURSOR c_numAbonne IS

SELECT num_abonne, count(*)

From emprunter

Where cote = p_cote

GROUP BY num_abonne

ORDER BY count(*) DESC;

V_nbr_emp, v_num_abonne number;

BEGIN

Open c_numAbonne;

Fetch c_numAbonne INTO v_numAbonne, v_nbr_emp;

Close c_numAbonne;

Return v_numAbonne;

End;

Exercice 7:

Ecrire une procédure qui prend en paramètre le cote d'un livre et détermine le nom et prénom
de l'abonné qui l'a emprunté le plus.

create or replace procedure ab_emprunt_plus(p_cote in varchar2, p_nom out varchar2, p_prenom


out varchar2)

return number is

cursor c_emp is

select num_abonne,nom,prenom,count(*) nb_emp

from emprunter e,abonne a

where e.num_abonne=a.num_abonne and cote=p_cote

group by num_abonne,nom,prenom
order y nb_emp desc;

v_num number;

v_nb number;

begin

open c_emp;

fetch c_emp into v_num,p_nom,p_prenom,v_nb;

close c_emp;

end;

Exercice 8:

Ecrire une fonction qui prend en paramètre le cote d'un livre et retourne le nombre de fois ou
il a été à l'origine d'une sanction.

create or replace function nombre_sanctions(p_cote varchar2)

return number is

nb_sanction number;

begin

select count(*) into nb_sanction

from sanctions

where cote=p_cote;

return nb_sanction;

end;

Exercice 9:

Ecrire une fonction qui prend en paramètre le numéro d'un abonné et retourne le nombre de
fois ou il a été sanctionné.

create or replace function nb_sanction_ab(p_num number)

return number is

nb_sanction number;

begin
select count(*) into nb_sanction

from sanctions

where num_abonne=p_num;

return nb_sanction;

end;

Exercice 10:

Ecrire une procédure qui prend en paramètres deux dates et détermine le cote du livre le plus
emprunté entre ces deux dates ainsi que numéro de l'abonné qui a réalisé le plus d'empreints.

create or replace procedure emprunt_plus_deux_date(p_date1 date,p_date2 date,p_cote out


varchar2, p_num out number) is

cursor c_emp1 is

select num_abonne,count(*) nb_emp

from emprunter e

where date_emprunt between p_date1 and p_date2

group by num_abonne

order y nb_emp desc;

cursor c_emp2 is

select cote,count(*) nb_emp

from emprunter

where date_emprunt between p_date1 and p_date2

group by cote

order y nb_emp desc;

v_nb number;

begin

open c_emp1;

fetch c_emp into p_num,v_nb;

close c_emp1;
open c_emp2;

fetch c_emp into p_cote,v_nb;

close c_emp2;

end;

Exercice 11:

Ecrire un bloc PL/SQL qui affiche les opérations d'empreint relatives au livre le plus
emprunté.

CURSOR c_liv IS SELECT cote, count(*) FROM Emprunter GROUP BY cote ORDER BY DESC;

CURSOR c_emp (p_cote varchar2) IS SELECT * FROM Emprunter WHERE cote = p_cote;

V_cote varchar2(50);

V_count number;

BEGIN

OPEN c_liv

Fetch c_liv INTO v_cote, v_count ;

Close c_liv;

For v_emp IN c_emp (v_cote) loop

DMBS_OUTPUT.PUT_LINE(‘Abonne: ‘ ||v_emp.nom_abonne || ‘Date emprunt’||v_emp.date_emp


|| ‘Date retour’ ||v_emp.date_retour);
End loop;
End;