Vous êtes sur la page 1sur 8

Cours : BDD Avancées : BDDR et SQL

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

TP2 : Oracle : Base de données Relationnelles et Langage PL/SQL


Objectifs :

• Manipuler une base de données par des requêtes avancées en utilisant des programme PL/SQL.
• Créer et utiliser des procédures et des fonctions stockées dans la BDD.

Travail à faire :

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

Exo-1 : Créer un programme PL/SQL qui permet de calculer et afficher le nombre de commande du mois
dernier. Le programme doit résoudre le problème lié au mois de « janvier ».

set serveroutput on;


DECLARE
An number;
M number;
nb number;
BEGIN
if EXTRACT(MONTH from sysdate)=1 THEN
M:=12;
An:=EXTRACT(year from sysdate)-1;
else
M:=EXTRACT(MONTH from sysdate)-1;
An:=EXTRACT(year from sysdate);
end if;
SELECT count(Ncommande) into nb
FROM COMMANDES
group by EXTRACT(MONTH from datecommande), EXTRACT(year from
datecommande)
having EXTRACT(MONTH from datecommande)=M
AND EXTRACT(year from datecommande)=An;
DBMS_OUTPUT.PUT_LINE(nb);
END;

Exo-2 :

1- Créer une procédure stockée qui permet de faire une mise à jour des champs « datecommande » et
« Alivreravant » pour les commandes 10248, 10251, 10253. Cette mise a jour doit insérer des dates
qui correspondent au mois dernier de la date actuelle.

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

CREATE OR REPLACE PROCEDURE Change as


BEGIN
update commandes
set DATECOMMANDE='12/09/2018',
alivreravant='12/09/2018'
where Ncommande=10248;
update commandes
set DATECOMMANDE='10/09/2018',
alivreravant='12/09/2018'
where Ncommande=10251;
update commandes
set DATECOMMANDE='10/09/2018',
alivreravant='12/09/2018'
where Ncommande=10253;
end change;

2- Créer un programme PL/SQL qui permet de calculer et afficher les commandes réalisée le mois dernier
quel que soit la date actuelle. Le programme doit résoudre le problème lié au mois de « janvier » :

set serveroutput on;


DECLARE
An number;
M number;
x commandes%rowtype;
CURSOR cur_com is
SELECT * INTO x
FROM COMMANDES
WHERE EXTRACT(MONTH from datecommande)=M
AND EXTRACT(year from datecommande)=An;
BEGIN
if EXTRACT(MONTH from sysdate)=1 THEN
M:=12;
An:=EXTRACT(year from sysdate)-1;
else
M:=EXTRACT(MONTH from sysdate)-1;
An:=EXTRACT(year from sysdate);
end if;
2
Cours : BDD Avancées : BDDR et SQL
TP : N°1 Prof : A. Benmakhlouf Site Web : www.cours-informatique.be.ma

open cur_com;
FETCH cur_com into x;
while cur_com%found
loop
DBMS_OUTPUT.PUT_LINE(x.NCOMMANDE||' '||x.datecommande);
FETCH cur_com into x;
end loop;
CLOSE cur_com;
END;

Exo-3 :

a- Créer une fonction qui prend en argument un Montant « Mt » et renvoie une commission « Com ».
Cette dernière sera calculée de la manière suivante :
• si le Mt < 1000 pas de commission
• SI le Mt est compris entre 1000 et 10 000 la commission est de 10% du Mt
• si le Mt >= 10 000 la commission est de 20% du Mt.

b- Créer un programme PL/SQL qui permet de stocker en mémoire tous les employés (NEMPLOE,
NOM) avec pour chacun d’eux son chiffre d’affaire « CA » ainsi que sa commission « CO ».

create or replace FUNCTION fcom(CA in number) RETURN number as


x number;
begin
if CA<1000 then
x:=CA*0;
elsif CA<=10000 then
x:=CA*0.1;
else
x:=CA*0.2;
end if;
RETURN x;
end;

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

SET SERVEROUTPUT ON
DECLARE
type Str is record
(Code EMPLOYéS.NEMPLOYé%type,
NOM char(10),
CA Number(10,2),
CO Number(10,2));
type Table_emp is table of Str
index by BINARY_INTEGER;
TC Table_emp;
i NUMBER :=0;
nb number;
cursor CA_emp is
select EMPLOYéS.NEMPLOYé, Nom, SUM(PrixUnitaire*Quantité*(1-Remise)) as CA
FROM ((employés INNER JOIN COMMANDES on
EMPLOYéS.NEMPLOYé=COmmandes.NEMPLOYE)
INNER JOIN "DÉTAILSCOMMANDES" ON
COMMANDES.NCOMMANDE=DÉTAILSCOMMANDES.Ncommande)
INNER JOIN Produits ON
DÉTAILSCOMMANDES.réfproduit=Produits."RÉFPRODUIT"
GROUP by EMPLOYéS.NEMPLOYé, Nom;
BEGIN
open CA_emp;
FETCH CA_emp into TC(i).CODE, TC(i).NOM, TC(i).CA;
while CA_emp%found
loop
TC(i).CO:=FCOM(TC(i).CA);
i:=i+1;
FETCH CA_emp into TC(i).CODE, TC(i).NOM, TC(i).CA;
end loop;
nb:=i-1;
for i in 0..nb loop
DBMS_OUTPUT.PUT_LINE(TC(i).CODE||' | '||TC(i).NOM||' |
'||TO_CHAR(TC(i).CA, '999999.99')||' | '||TC(i).CO);
end loop;
END;

NB : pour donner un certain format à un nombre on doit le convertir on char « TO_CHAR() » on


utilise. On fixe le nombre de chiffre avant et après la virgule par les symboles 9 ou 0 :

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

o Avec « 9 » affiche les chiffres du nombre et complète les chiffres manquants de la partie
entière par espace.
o Avec « 0 » affiche les chiffres du nombre et complète les chiffres manquants de la partie
entière par 0.
exemple :
TO_CHAR(123.5, '999999.99') affiche “ 123.50”
TO_CHAR(123.5, '000999.99') affiche “000123.50”
TO_CHAR(123.5, '999999.99') affiche “ 123.50”
TO_CHAR(123.5, '99.99') affiche “########”

Exo-4 : Même question que l’exo-3 mais cette fois il faut insérer les résultats dans un tableau créer par le
même programme PL/SQL.

SET SERVEROUTPUT ON
Drop table CA_EMP;
create table CA_EMP(Num number, NomE varchar2(10), Mt number, Com
number);
DECLARE
CodeE number;
NomE char(10);
Mt Number(10,2);
Com Number(10,2);
nb number;
cursor CA_emp is
select EMPLOYéS.NEMPLOYé, Nom, SUM(PrixUnitaire*Quantité*(1-Remise)) as CA
FROM ((employés INNER JOIN COMMANDES on
EMPLOYéS.NEMPLOYé=COmmandes.NEMPLOYE)
INNER JOIN "DÉTAILSCOMMANDES" ON
COMMANDES.NCOMMANDE=DÉTAILSCOMMANDES.Ncommande)
5
Cours : BDD Avancées : BDDR et SQL
TP : N°1 Prof : A. Benmakhlouf Site Web : www.cours-informatique.be.ma

INNER JOIN Produits ON


DÉTAILSCOMMANDES.réfproduit=Produits."RÉFPRODUIT"
GROUP by EMPLOYéS.NEMPLOYé, Nom
order by EMPLOYéS.NEMPLOYé;
BEGIN
open CA_emp;
FETCH CA_emp into CodeE, NomE, Mt;
while CA_emp%found
loop
Com:=FCOM(Mt);
insert into CA_EMP(Num, NomE, Mt, Com) values (CodeE, NomE, Mt, Com);
FETCH CA_emp into CodeE, NomE, Mt;
end loop;
END;

Exo-5 : Nous voulons dans cet exercice de mettre dans un autre compte Oracle une base de données réduite
composée des commandes et leurs détails des clients d’un pays donné. Pour cela :

Action-1 : créer un autre compte utilisateur dans Oracle puis accorder lui tous les privilèges.

Action-2 : créer dans la BDD de ce nouveau compte les tables « Commandes » et « détailsCommandes » de
même structure des tables de la BDD initales « GestionDesVentes ».

Action-3 : créer deux procédures stockées COM_Pays(P Clients.Pays%ROW) et DCOM_Pays(P


Clients.Pays%ROW) qui permettent de stocker dans les tables de la BDD du nouveau utilisateur les
commandes et les détails des clients d’un certain pays. Le nom de ce dernier sera saisi comme paramètre à
l’appelle des deux procédures.

NB : pour éviter d’écrire dans les procédures tous les attributs des deux tables « Commandes » et
« détailsCommandes », utiliser le type de variable « RECCORD »

create or replace procedure Com_Pays(P in Clients.pays%type) as


CURSOR COM is
select *
from Commandes
where CODECLIENT IN (select codeclient from clients where PAYS=P);
type Str is RECORD (L COMMANDES%rowtype);
LCom Str;
begin
open COM;
fetch COM into LCom.L;
while COM%found
6
Cours : BDD Avancées : BDDR et SQL
TP : N°1 Prof : A. Benmakhlouf Site Web : www.cours-informatique.be.ma

loop
insert into userBDDFrance.COMMANDES values LCom.L;
fetch COM into LCom.L;
end loop;
commit;
end Com_Pays;

Procédure avec l’utilisation d’une semi-jointure


create or replace procedure DCom_Pays(P in Clients.pays%type) as
CURSOR DCOM is
select * from "DÉTAILSCOMMANDES"
where NCommande IN (select Ncommande from userBDDFrance.Commandes);
type Str is RECORD (L DÉTAILSCOMMANDES%rowtype);
LDCom Str;
begin
open DCOM;
fetch DCOM into LDCom.L;
while DCOM%found
loop
insert into userBDDFrance.DÉTAILSCOMMANDES values LDCom.L;
fetch DCOM into LDCom.L;
end loop;
commit;
end DCom_Pays;

Procédure avec l’utilisation d’une jointure

create or replace procedure DCom_Pays(P in Clients.pays%type) as


CURSOR DCOM is
select DÉTAILSCOMMANDES.Ncommande, Réfproduit, Quantité, Remise
from clients, Commandes, "DÉTAILSCOMMANDES"
where clients.CODECLIENT=Commandes.CODECLIENT
AND Commandes.NCOMMANDE=DÉTAILSCOMMANDES.Ncommande
AND PAYS=P;
type Str is RECORD (L DÉTAILSCOMMANDES%rowtype);
LDCom Str;
begin
open DCOM;
fetch DCOM into LDCom.L;
while DCOM%found
loop
7
Cours : BDD Avancées : BDDR et SQL
TP : N°1 Prof : A. Benmakhlouf Site Web : www.cours-informatique.be.ma

insert into userBDDFrance.DÉTAILSCOMMANDES values LDCom.L;


fetch DCOM into LDCom.L;
end loop;
commit;
end DCom_Pays;

begin
Com_Pays('France');
DCom_Pays('France');
end;