Vous êtes sur la page 1sur 6

Cours : BDD Avancées : BDDR et SQL

TP : N°2 Prof : A. Benmakhlouf Site Web : www.cours-informatique.be.ma

TP4 : Base de données Relationnelles sous Oracle :


Langage PL/SQL (les Exceptions, les Packages et les Déclencheurs)
Objectifs :

• Manipuler une base de données par des requêtes avancées en utilisant des programme PL/SQL.
• Automatiser le traitement des données par des déclencheurs.
• Savoir gérer les exceptions et les erreurs dans les programmes PL/SQL

Travail à faire : Dans les exercices qui suivent nous allons utiliser la même BDD du TP1 « GestionDesentes »

Exo-1

a- Créer une vue (CAANN) qui permet de calculer le Montant des ventes par année.
b- Créer une fonction stockée qui permet de renvoyer le montant des ventes pour une année dont la valeur
est transmise en argument. La fonction doit aussi gérer le cas où il n’y a pas de ventes réalisées pendant
l’année choisie (Montant des ventes = 0).
c- Créer un programme pour afficher les Montant des ventes pendant les années 2004…2018

create or REPLACE FUNCTION CA_ANN(x number) RETURN number as


CA number;
ANN number;
begin
select * into ANN, CA
from CAANN
where ANN=x;
RETURN CA;
EXCEPTION
WHEN NO_DATA_FOUND THEN
CA:=0;
RETURN CA;
end;

set serveroutput on;


begin
dbms_output.put_line('ANNEE'||' | '||'Nombre'||' |');
dbms_output.put_line('-----------------------------------');
for i in 2004 .. 2018 loop
dbms_output.put_line(i||' | '||To_Char(CA_ANN(i),'999999.99')||' |');
end loop;
END;

Exo2 : Nous voulons stocker dans une table de base de données les clients (Année code, société, CA) qui
ont réalisé le meilleur chiffre d’affaires entre deux année ANN1 et ANN2. pour cela :

1
Cours : BDD Avancées : BDDR et SQL
TP : N°2 Prof : A. Benmakhlouf Site Web : www.cours-informatique.be.ma

1- Créer un package « Pack » contenant :


a- Un type « Str » enregistrement pour stocker le id client, le nom de la société et le chiffre d’affaire
du client
b- Une fonction stockée prenant comme paramètre un entier qui représente une année et revoie un
enregistrement qui correspond au client qui a réalisé le meilleur chiffre d’affaires. la fonction doit
renvoyer l’enregistrement (valeur_ANN, 0, aucunclient, 0) s’il n y a pas de vente réalisée pendant
l’année ANN (voir exemple).
Function CA_CL_Max(ANN integer) Return Str;
c- Une procédure stockée qui a comme paramètre d’entrée deux années ANN1 et ANN2 et stocke
dans une table de base de données ‘Table_Max_CA_ANN’ les clients qui ont réalisé le plus grand
CA entre les années ANN1 et ANN2
Procedure CA_CL(ANN1 integer, ANN2 integer);

2- Créer un programme PLSQL qui appelle la procédure CA_CL() pour les années [2014..2025]. Ci-
dessous les données insérées dans une table de la BDD :

create table Max_CA_CL_ANN(AN Integer, Code Integer, NomClient Varchar2(100), CA


float);

create or replace Package Pack is


type Str is Record (code integer, Nom clients.societe%type, CA float);
Function CA_CL_Max(ANN integer) Return Str;
Procedure CA_CL(ANN1 integer, ANN2 integer);
end;

create or replace Package Body Pack is


Function CA_CL_Max(ANN integer) Return Str is
S Str;
begin
select * into S from (
select clients.idclient, societe, sum(prixunitaire*quantite*(1-remise/100))
FROM Clients, Commandes, Lignecommandes, Produits
WHERE clients.idclient=Commandes.Idclient
2
Cours : BDD Avancées : BDDR et SQL
TP : N°2 Prof : A. Benmakhlouf Site Web : www.cours-informatique.be.ma

AND commandes.idcommande=Lignecommandes.Idcommande
AND Lignecommandes.Idproduit=Produits.Idproduit
AND Extract(year from datecommande)=ANN
Group by clients.idclient, societe
order by sum(prixunitaire*quantite*(1-remise/100)) DESC)
where rownum=1;
Return S;
exception
when no_data_found then
S.code:=0000;
S.nom:='aucun client';
S.CA:=0;
return S;
end CA_CL_Max;
Procedure CA_CL(ANN1 integer, ANN2 integer) as
R Str;
begin
for i in ANN1..ANN2 loop
R:=CA_CL_Max(i);
insert into Max_Ca_Cl_Ann values (i, R.code, R.Nom, R.CA);
end loop;
end CA_CL;
end;

begin
for i in 2010..2020 loop
Pack.CA_CL(i);
end loop;
end;

Exo2 :

Créer un trigger qui permet de vérifier la disponibilité du produit avant chaque insertion d’une nouvelle ligne
de commande dans une commande déjà crée. Ce trigger doit aussi faire la mise à jour du stock si le produit
est disponible.

create or replace TRIGGER TRIGGER1


BEFORE INSERT ON détailsCommandes
for EACH ROW
BEGIN
declare
Qt number;
begin
select PRODUITS."UNITÉSENSTOCK"+"UNITÉSCOMMANDÉES" into Qt
3
Cours : BDD Avancées : BDDR et SQL
TP : N°2 Prof : A. Benmakhlouf Site Web : www.cours-informatique.be.ma

From produits
where RéfProduit=:New.RéfProduit;
if :New.Quantité>Qt then
RAISE_APPLICATION_ERROR(-20000,'Quantité en stock insuffisante');
else
update PRODUITS
set "UNITÉSENSTOCK"="UNITÉSENSTOCK"-:New.Quantité
where RéfProduit=:New.RéfProduit;
end if;
end;
END;

insert into "DÉTAILSCOMMANDES" values(10250, 2, 2, 0);

Exo4:

1- Créer une fonction stockée qui prend en paramètre un entier qui représente le numéro du mois et renvoi
la saison correspondante : Saison(Mo integer) Return Varchar2
Les saisons en fonction des mois sont données par :

Hiver : 12  2
Printemps : 3  6
Eté : 7  9
Automne : 10  11

2- Créer la vue CA_Prod_Saison qui permet de calculer le Montant des ventes par produit et par saison.
3- Créer une fonction stockée MaxSaison(X varchar2) return CA_Prod_Saison%rowtype qui
permet de renvoyer le produit qui a réalisé le plus grand montant des ventes pendant la saison qui sera
transmise en argument de cette fonction.

create or replace function saison(Mo integer) Return Varchar2 as


Sa Varchar2(20);
begin
if (Mo<=2) then
Sa:='Hiver';
elsif (Mo<=6) then
Sa:='Printemps';
elsif (Mo<=9) then
Sa:='Eté';
elsif (Mo<=11) then
Sa:='Automne';
else
Sa:='Hiver';
end if;
4
Cours : BDD Avancées : BDDR et SQL
TP : N°2 Prof : A. Benmakhlouf Site Web : www.cours-informatique.be.ma

Return Sa;
end;

create or replace view CA_Prod_Saison as select saison(extract(month from


datecommande)) as Saison,
produits.idproduit, designation, sum(prixunitaire*quantite*(1-remise/100)) as CA
FROM commandes, Produits, Lignecommandes
where Commandes.Idcommande=Lignecommandes.Idcommande
AND Produits.Idproduit=Lignecommandes.Idproduit
group by saison(extract(month from datecommande)), produits.idproduit, designation
order by saison(extract(month from datecommande));

create or replace function MaxSaison(X varchar2) return CA_Prod_Saison%rowtype as


R CA_Prod_Saison%rowtype;
begin
select * into R from CA_Prod_Saison
where Saison=X
AND rownum=1
order by CA;
Return R;
exception
when no_data_found then
R.saison:=X;
R.idproduit:=0;
R.designation:='pas de produit';
R.CA:=0;
return R;
end;

set SERVEROUTPUT ON;


declare
L CA_Prod_Saison%rowtype;
begin
L:=Maxsaison('Hiver');
dbms_output.put_line(
L.Saison||' '||
L.idproduit||' '||
L.designation||' '||
L.CA);
end;

Exo5 :
Créer une Procédure stockée qui charge en mémoire, dans une collection T(), tous les
clients avec pour chacun deux les commandes qui a réalisé. Cette collection sera indicée
par le « idclient » : T(idclient). Cette procédure doit aussi afficher un client avec ces
commandes en fixant l’indice de la collection. Ce dernier sera un paramètre d’entrée de la
procédure (voir figure). Ci-dessous un exemple d’exécution de cette procédure :
5
Cours : BDD Avancées : BDDR et SQL
TP : N°2 Prof : A. Benmakhlouf Site Web : www.cours-informatique.be.ma

create or replace PROCEDURE Table_client(N clients.idclient%type) as


type strcom is RECORD (
numcom commandes.idcommande%type,
datecom commandes.datecommande%type,
numcl commandes.idclient%type);
type tabcom is table OF strcom
index by BINARY_INTEGER;
type strcl is record (
numcl clients.idclient%type,
nom clients.societe%type,
comcl tabcom);
type tabcl is table of strcl
index by BINARY_INTEGER;
Tcl tabcl;
i0 clients.idclient%type;
cursor curcl is
select idclient, societe from clients;
cursor curcom is
select idcommande, datecommande, idclient from commandes
where idclient=i0;
j integer;
type Tabnb is table of integer
index by binary_integer;
Tnb Tabnb;
begin
for ncl in curcl loop
Tcl(ncl.idclient).numcl:=ncl.idclient;
Tcl(ncl.idclient).nom:=ncl.societe;
j:=0;
i0:=ncl.idclient;
for ncom in curcom loop
Tcl(ncl.idclient).comcl(j).numcom:=ncom.idcommande;
Tcl(ncl.idclient).comcl(j).datecom:=ncom.datecommande;
Tcl(ncl.idclient).comcl(j).numcl:=ncom.idclient;
j:=j+1;
end loop;
Tnb(ncl.idclient):=j;
end loop;
dbms_output.put_line(Tcl(N).numcl||' '||
Tcl(N).nom);
for k in 0..Tnb(N)-1 loop
dbms_output.put_line(Tcl(N).comcl(k).numcom||' '||
Tcl(N).comcl(k).datecom||' '||
Tcl(N).comcl(k).numcl);
end loop;
end;
6

Vous aimerez peut-être aussi