Académique Documents
Professionnel Documents
Culture Documents
b Ecrire le bloc PL/SQL qui permet d'inialiser deux variables de type varchar2 qui contiennent
respectivement votre nom et votre prénom et de l'afficher.
C. Ajouter le bloc PL/SQL, précédent l'affichage du nombre de caractère que contient votre
nom et votre prénom (opérateur length) et de vérifier si votre nom ou votre prénom
contient la lettre 'C' dans la troisième position. Utiliser deux variables pour réaliser ceci.
Declare
v_nom varchar2(20):= 'ZAMMIT CHATTI';
v_prenom varchar2(10) :='Sami';
BEGIN
dbms_output.put_line('taille nom:'||length(v_nom)||',prenom
taille:'||length(v_prenom));
if(v_nom like '--c%') or (v_prenom like '__c%') then
dbms_output.put_line('CONTIENT ');
else
dbms_output.put_line('NE CONTIENT PAS c');
end if;
END;
1
d Ecrire le bloc PL/SQL qui permet de réaliser une boucle qui permet d'afficher 10 premiers
entiers avec 10(utiliser les trois types de boucles, FOR, WHILE et LOOP)
--While--
set serveroutput on;
Declare
v_cpt number(2):= 1;
BEGIN
END;
--for--
set serveroutput on;
Declare
v_cpt number(2):= 1;
BEGIN
FOR v_cpt in 1..10 LOOP
dbms_output.put_line(v_cpt);
END LOOP;
END;
-- do while--
set serveroutput on;
Declare
v_cpt number(2):= 1;
BEGIN
v_cpt:= 1;
LOOP
dbms_output.put_line(v_cpt);
v_cpt:= v_cpt+1;
EXIT WHEN v_cpt>10;
END LOOP;
END;
2
3—Manipulation basique des tables
A-- Ecrire le bloc PL/SQL qui permet d’afficher les informations de l’employé KRUNAL :
B ecrire le bloc qui permet d'afficher les informations de l'employé qui est de la ville de
TORONTO
Il y a plusieurs employés dans la ville de TORONTO notre variable ne peut supporter qu'une
seule ligne
C Écrire Le bloc PL/SQL qui permet d'afficher les n premiers entiers avec n la taille de la table
emp
BEGIN
select count(*) into v_nb_emp from emp;
WHILE v_cpt<=v_nb_emp LOOP
dbms_output.put_line(v_cpt);
v_cpt:= v_cpt+1;
END LOOP;
END;
3
D Écrire le bloc Pl/SQL qui permet d'afficher les employés de EMP en utilisant leurs
identifiants:
BEGIN
select count(*) into v_nb_emp from emp;
WHILE v_cpt<=v_nb_emp LOOP
select * into v_info from emp where eno='E'||v_cpt;
dbms_output.put_line(v_info.eno||' '||v_info.ename||' '||v_info.title||' '||v_info.city);
v_cpt:= v_cpt+1;
END LOOP;
END;
E Écrire le bloc PL/SQL qui permet d'afficher les durées de travail (table works) paires de
chaque employé sans utiliser where
BEGIN
select count(*) into v_nb_emp from works;
WHILE v_cpt<=v_nb_emp LOOP
select * into v_info from works where eno='E'||v_cpt;
if mod(v_info.dur,2)=0 then
dbms_output.put_line(v_info.eno||' '||v_info.pno||' '||v_info.dur);
end if;
v_cpt:= v_cpt+1;
END LOOP;
END;
4
F- Ecrire le bloc PL/SQL qui permet d'insérer 5 employés de E9 à E13 qui sont des
programmeurs à NEW YORK. Les noms sont identiques à leurs identifiants.
(Utilisation d'une boucle)
G. écrire le bloc PL/SQL qui permet de modifier l'emploie des 5 employés de NEW YORK de
PROGRAMMER à Support STAFF.
BEGIN
UPDATE emp
SET title='SUPPORT STAFF' WHERE city='NEW YORK';
END;
5
TD 2
A. Ecrire le bloc PL/SQL qui permet de parcourir et afficher tous les employés avec la boucle FOR (explicite-
curseur à déclarer).
declare
cursor c_emp is
select * from emp;
begin
for v_emp in c_emp loop
dbms_output.put_line('eno :'||v_emp.eno);
dbms_output.put_line('ename :'||v_emp.ename);
dbms_output.put_line('title :'||v_emp.title);
dbms_output.put_line('city :'||v_emp.city);
end loop;
end;
B. Ecrire le bloc PL/SQL qui permet de parcourir et afficher tous les employés avec la boucle WHILE.
declare
cursor c_emp is
select * from emp;
v_emp c_emp%rowtype;
begin
open c_emp;
fetch c_emp into v_emp;
DECLARE
CURSOR c_emp_to_be_raised(p_title emp.title%TYPE) IS
SELECT * FROM emp WHERE title = p_title;
BEGIN
FOR cRowEmp IN c_emp_to_be_raised('PROGRAMMER') LOOP
dbms_Output.Put_Line(cRowEmp .ename ||' ' ||cRowEmp.title||'... should be raised ;)');
END LOOP;
END;
D. Ecrire le bloc PL/SQL qui permet d’afficher les employés avec leur salaire en utilisant une jointure.
declare
cursor c_emp is
select * from emp join pay using (title);
v_emp c_emp%rowtype;
begin
for v_emp in c_emp loop
dbms_output.put_line('eno :'||v_emp.eno);
dbms_output.put_line('ename :'||v_emp.ename);
dbms_output.put_line('title :'||v_emp.title);
dbms_output.put_line('city :'||v_emp.city);
dbms_output.put_line('salary :'||v_emp.salary);
end loop;
end;
E. EcrireleblocPL/SQL qui permet de modifier les salaires des employés (table PAY) de la manière suivante
o Si le salaire dépasse la moyenne le diminuer par10%
o Sinonl’augmenterpar10%
declare
cursor c_pay is
select * from pay;
average number(10,2);
begin
select avg(SALARY) into average from pay;
dbms_output.put_line('average :'||average);
for vpay in c_pay loop
if (vpay.salary>average) then
update pay set salary=salary*0.9 where title=vpay.title;
else
update pay set salary=salary*1.1 where title=vpay.title;
end if;
end loop;
end;
select * from pay
F. Ecrire le bloc PL/SQL qui permet de calculer la moyenne des salaires pour chaque
ville (avec l’utilisation de group by).
declare
cursor c_emp is
select city,avg(salary) as avg_salary from emp join pay using (title) group by city;
begin
for v_salary in c_emp loop
dbms_output.put_line('salaire de la ville :'||v_salary.city ||' est : '||v_salary.avg_salary);
end loop;
end;
g) Ecrire le bloc PL/SQL qui permet de calculer la moyenne des salaires pour chaque
ville (sans l’utilisation de group by).
declare
cursor c_city is
select distinct city from emp;
--cursor c_emp is
-- select * from emp join pay using (title);
average number(10,2);
begin
for v_city in c_city loop
--dbms_output.put_line('salaire de la ville :'||v_city.city );
select avg(salary) into average from emp join pay using (title) where city=v_city.city;
dbms_output.put_line('salaire de la ville :'||v_city.city ||' est : '||average);
end loop;
end;
h) Ecrire le bloc PL/SQL qui permet d’afficher les noms des employés qui travaillent à
LONDON en utilisant FETCH.
DECLARE
CURSOR c_emp IS SELECT eno, ename FROM emp where city='LONDON';
v_id emp.eno%TYPE;
v_nom emp.ename%TYPE;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp into v_id, v_nom;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_id || '' || v_nom);
END LOOP;
CLOSE c_emp;
END;
DECLARE
CURSOR c_emp(ville emp.city%type)
IS SELECT eno, ename FROM emp where city=ville;
v_id emp.eno%TYPE;
v_nom emp.ename%TYPE;
BEGIN
OPEN c_emp('LONDON');
LOOP
FETCH c_emp into v_id, v_nom;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_id || '' || v_nom);
END LOOP;
CLOSE c_emp;
END;
TD 3
a. Écrire une fonction PL/SQL qui permet de retourner le maximum entre deux entiers.
BEGIN
if nb1>nb2
then return nb1;
else
return nb2;
end if;
END;
/
-- correction du prof
create or replace function maximum_num(val1 in number,val2 in number)
return number
IS
v_nb number;
Begin
v_nb:=0;
IF val1>=val2 THEN
v_nb := val1;
ELSE
v_nb := val2;
END IF;
return v_nb;
End;
/
b. Écrire une fonction qui permet de retourner le nombre d’employés.
-- correction du prof
CREATE OR REPLACE FUNCTION nombre_employees
RETURN NUMBER
IS
e_nb NUMBER;
CURSOR c_nb_emp IS SELECT count(*) FROM EMP;
BEGIN
OPEN c_nb_emp;
FETCH c_nb_emp INTO e_nb;
CLOSE c_nb_emp;
RETURN e_nb;
END;
/
C. Écrire une fonction qui permet de retourner le nombre de programmeurs qui travaillent sur un projet Pi.
-- correction du prof
CREATE OR REPLACE FUNCTION nombre_programmeurs_projet(name_proj in varchar2)
RETURN NUMBER
IS
e_nb NUMBER;
CURSOR c_nb_emp IS select count(*) from emp join works using(ENO) where PNO=name_proj and
TITLE='PROGRAMMER';
BEGIN
OPEN c_nb_emp;
FETCH c_nb_emp INTO e_nb;
CLOSE c_nb_emp;
RETURN e_nb;
END;
/
d. En supposant que le salaire perçu par un employé durant tout un projet est égal le salaire correspondant à son
titre
--multiplié par la durée sur le projet. Écrire une fonction qui permet de déduire l’argent qui doit être ajouté au
budget d’un projet
--donné pour subvenir à la totalité du coût du projet en termes de salaires.
BEGIN
select sum(salary*dur) into v_budget_projet from works, emp, pay where emp.eno =works.eno
and emp.title=pay.title and pno=PI;
select budget into v_budget_prevu from proj where PNO=PI;
v_diff:= v_budget_prevu-v_budget_projet;
if v_diff<0 then v_diff:=-v_diff;
else v_diff:=0;
end if;
return v_diff;
END;
/
DECLARE
V_COMPL NUMBER(10);
BEGIN
return to_ret;
END;
e. Utiliserla fonction précédemment déclarée pour écrire une procédure PL/SQL qui permet
de rétablir les budgets nécessaires pour chaque projet.
BEGIN
BEGIN
-- correction du prof
END;
/
f. Ecrire
une procédure PL/SQL qui permet d’ajouter un MANAGER sur les projets qui ne
possèdent pas un manager.
v_num_project VARCHAR(20);
BEGIN
OPEN c_project;
FETCH c_project INTO v_num_project;
INSERT INTO EMP
VALUES(eno,ename,title,city);
INSERT INTO WORKS
VALUES(eno,v_num_project,laduree);
END;
-- correction du prof
v_dur works.dur%type;
BEGIN
select * into manager_to_insert from EMP where ENO = (select min(ENO) from EMP where TITLE='MANAGER');
--GET A MANAGER IN EMP
a) Ecrire le bloc PL/SQL qui permet d’afficher les informations de l’employé BUTTERS. Gérer
ensuite l’exception remontée par ce bloc.
DECLARE
v_emp emp%rowtype;
BEGIN
SELECT * into v_emp from emp where upper(ename)='BUTTERS';
DBMS_OUTPUT.PUT_LINE('voici les informations : ' || v_emp.title);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Il n y a pas ce nom');
END;
/
-- correction du prof
declare
v_emp emp%rowtype;
begin
select * into v_emp from emp where ename='BUTTERS';
dbms_output.put_line('eno :'||v_emp.eno);
dbms_output.put_line('ename :'||v_emp.ename);
dbms_output.put_line('title :'||v_emp.title);
dbms_output.put_line('city :'||v_emp.city);
exception
when NO_DATA_FOUND then
dbms_output.put_line('no employee named BUTTERS found !');
end;
/
b) Dans la question 2.b TD1, le bloc PL/SQL remonte une exception puisque la requête select
... into retourne plusieurs valeurs. Modifier la procédure de telle manière à ce que le bloc
affiche le nombre de lignes retournées en utilisant un traitement d’exceptions.
Rappel question 2.b : Ecrire le bloc PL/SQL qui permet d’afficher les informations de
l’employé qui est de la ville ‘TORONTO’. Pourquoi ça ne marche pas ?
DECLARE
v_emp emp%rowtype;
v_excp number;
BEGIN
SELECT * into v_emp from emp where upper(city)='TORONTO';
DBMS_OUTPUT.PUT_LINE('voici les informations : ' || v_emp.title);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Il n y a pas ');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('IL Y A BEAUCOUP DEMPLOYÉS');
select count(*) into v_excp from emp where upper(city)='TORONTO';
DBMS_OUTPUT.PUT_LINE(v_excp);
END;
/
-- correction du prof
declare
v_emp emp%rowtype;
v_count number(10);
begin
select * into v_emp from emp where CITY='Toronto';
dbms_output.put_line('eno :'||v_emp.eno);
dbms_output.put_line('ename :'||v_emp.ename);
dbms_output.put_line('title :'||v_emp.title);
dbms_output.put_line('city :'||v_emp.city);
exception
when TOO_MANY_ROWS then
select count(*) into v_count from emp where CITY='Toronto';
dbms_output.put_line('number of rows is: '|| v_count);
end;
/
c) Ecrire un bloc PL/SQL qui parcours la table des salaires des employés (PAY) en utilisant les
curseurs. Ce bloc doit générer une exception dès qu’il trouve un salaire dépassant le seuil de
10000. L’exception doit être déclarée d’une manière explicite.
DECLARE
cursor c_emp_salaire is (select emp.ename, pay.salary from emp,pay where pay.title=emp.title);
v_emp_salaire c_emp_salaire%rowtype;
emp_riche exception;
BEGIN
open c_emp_salaire;
loop
fetch c_emp_salaire into v_emp_salaire;
exit when c_emp_salaire %NOTFOUND;
if v_emp_salaire.salary > 10000 then
raise emp_riche ;
end if;
end loop;
EXCEPTION
when emp_riche then
dbms_output.put_line('OUI ' || v_emp_salaire.ename || ' GAGNE BCP ');
end;
d) Ecrire un bloc PL/SQL qui permet de générer une exception s’il existe au moins un
employé qui n’est pas affecté a aucun projet.
declare
nb_sans_proj number(10);
emp_sans_proj exception;
begin
select count(*) into nb_sans_proj from (select eno from emp where eno not in(select eno from works));
if nb_sans_proj>0 then
raise emp_sans_proj;
end if;
exception
when emp_sans_proj then
dbms_output.put_line('il existe un employé sans projet');
end;
-- correction du prof
declare
v_count number(10);
EMPLOYEE_WITH_NO_WORK exception;
begin
select count(*) into v_count from
(select distinct eno from emp where eno not in (select eno from works));
if v_count>0 then
raise EMPLOYEE_WITH_NO_WORK;
end if;
exception
when EMPLOYEE_WITH_NO_WORK then
dbms_output.put_line('there is at least one employee without work');
end;
/