Vous êtes sur la page 1sur 7

Module : Implémentation Oracle Durée : 3H Semestre : 3

Enoncés
1) Considérez le schéma relationnel suivant.

 Employe (eid:integer, enom:string, age:integer, salaire:real)


 Travail (#eid:integer, #depid:integer, pct_temps:integer)
 Department (depid:integer, budget:real, #responsable_id:integer)

Un employé peut travailler dans plus d'un département ; le champ pct_temps de la relation Travail
indique le pourcentage de temps pendant lequel un employé donné, travaille dans un service donné.
Exprimez les exigences suivantes en utilisant des déclencheurs :
a) Les employés doivent gagner un salaire minimum de 1000$.
b) Le pourcentage total du temps de travail pour un employé doit être inférieur à 100%. Un
responsable doit toujours avoir un salaire plus élevé que n'importe quel employé qu'il dirige.
c) Chaque fois qu'un employé reçoit une augmentation, le salaire du responsable doit être
augmenté du même montant.
d) Chaque fois qu'un employé reçoit une augmentation, le salaire du responsable doit être
augmenté au moins autant. De plus, chaque fois qu'un employé reçoit une augmentation, le
budget du département doit être augmenté pour être supérieur à la somme des salaires des
employés du département.

2) Considérez le schéma relationnel pour une base de données contenant des informations sur les
employés d'une entreprise :

 Employes (id_employe, nom, prenom, date_embauche, id_departement#, salaire)


 Departements (id_departement, nom_departement, chef_departement)

a) Créez une vue qui affiche les informations suivantes pour chaque employé : nom, prénom,
département, salaire, nombre total d'années d'expérience dans l'entreprise (calculé à partir de la
date d'embauche) et le nom du chef de département.
b) Créez une vue qui affiche le nombre d'employés par département, ainsi que le salaire moyen par
département.
c) Créez une procédure stockée qui calcule le salaire moyen par département, et stocke les
résultats dans un tableau associatif où la clé est le nom du département, et la valeur est le salaire
moyen. Ce code doit contenir aussi un curseur.
d) Répondez à la question (3) en utilisant une fonction.

Corrigé
1) Les employés doivent gagner un salaire minimum de 1000$. VOIR LA RÉPONSE
CREATE OR REPLACE TRIGGER quest_1
BEFORE INSERT OR UPDATE ON Employe FOR EACH ROW
BEGIN
IF :NEW.salaire < 1000 THEN
RAISE_APPLICATION_ERROR(-20005,'Les employés doivent gagner un salaire minimum de 1000$.');
END IF;
END;
-Le pourcentage total du temps de travail pour un employé doit être inférieur à 100%. VOIR LA
RÉPONSE

1 CREATE OR REPLACE TRIGGER quest_2

2 AFTER INSERT OR UPDATE ON Travail FOR EACH ROW

DECLARE
3
pct NUMBER;
4
BEGIN
5
SELECT SUM(pct_temps) INTO pct FROM Travail WHERE eid=:NEW.eid;
6
IF pct >=100 THEN
7
RAISE_APPLICATION_ERROR(-20005,'Le pourcentage total du temp de travail
8 pour un employé doit être inférieur à 100');
9 END IF;

10 END;

-Un responsable doit toujours avoir un salaire plus élevé que n'importe quel employé qu'il ou elle
dirige.

1 CREATE OR REPLACE TRIGGER quest_3

2 AFTER INSERT OR UPDATE ON Travail FOR EACH ROW

DECLARE
3
SAL REAL;
4
BEGIN
5
SELECT E.salaire INTO SAL FROM Departement D INNER JOIN EMPLOYE E ON E.eid=D.responsable_
6
IF :NEW.salaire > SAL THEN
7 RAISE_APPLICATION_ERROR(-20005,'Un responsable doit toujours avoir un salaire plus
8 END IF;
9
END;
10

c) Chaque fois qu'un employé reçoit une augmentation, le salaire du responsable doit être
augmenté du même montant. VOIR LA RÉPONSE
?

1 CREATE OR REPLACE TRIGGER quest_4

2 AFTER UPDATE ON EMPLOYE FOR EACH ROW


WHEN NEW.salaire>OLD.salaire
3
DECLARE
4
DEP NUMBER;
5
RESP NUMBER;
6
DIFF REAL;
7 BEGIN

8 DIFF:=:NEW.salaire-:OLD.salaire;
9 SELECT T.depid INTO DEP FROM Travail T INNER JOIN Employe E ON E.eid=T.eid

1 SELECT responsable_id INTO RESP FROM Departement WHERE depid=DEP;


0 UPDATE Employe SET salaire=salaire+DIFF WHERE eid = RESP;
END;
1
1

1
2
Chaque fois qu'un employé reçoit une augmentation, le salaire du responsable doit être augmenté au moins
1
3 autant. De plus, chaque fois qu'un employé reçoit une augmentation, le budget du département doit être augmenté
somme des salaires des employés du département. VOIR LA RÉPONSE

CREATE OR REPLACE TRIGGER quest_5

AFTER UPDATE ON EMPLOYE FOR EACH ROW

FOLLOWS quest_4

WHEN NEW.salaire>OLD.salaire

DECLARE
DEP NUMBER;

BUDG REAL;

DIFF REAL;

SOMME REAL;
BEGIN
DIFF:=:NEW.salaire-:OLD.salaire;
SELECT T.depid INTO DEP FROM Travail T INNER JOIN Employe E ON E.eid=T.eid
WHERE E.eid=:NEW.eid;
SELECT budget INTO BUDG FROM Departement WHERE depid=DEP;
SELECT SUM(E.salaire) INTO SOMME FROM Travail T INNER JOIN Employe E ON E.eid=T.eid
WHERE T.depid=DEP;
IF SOMME>BUDG THEN
UPDATE Employe SET salaire=salaire+(SOMME-BUDG) WHERE eid = RESP;
END IF;
END;

2) Cette requête affichera les détails des employés avec le nombre total d'années d'expérience dans
l'entreprise et le nom du chef de département pour chaque employé.
a)
CREATE VIEW Vue_Employes_Expérience AS
SELECT e.nom, e.prenom, e.departement, e.salaire,
TRUNC(MONTHS_BETWEEN(SYSDATE, e.date_embauche) / 12) AS annees_experience,
d.chef_departement
FROM Employes e
JOIN Departements d ON e.departement = d.id_departement;
```
Après avoir créé cette vue, vous pouvez interroger la vue pour obtenir les informations demandées,
comme ceci :
```sql
SELECT * FROM Vue_Employes_Expérience;
b)
une vue qui affiche le nombre d'employés par département, ainsi que le salaire moyen par
département.
CREATE VIEW Vue_Statistiques_Departements AS
SELECT d.nom_departement, COUNT(e.id_employe) AS nombre_employes, AVG(e.salaire) AS
salaire_moyen
FROM Employes e
JOIN Departements d ON e.departement = d.id_departement
GROUP BY d.nom_departement;
Après avoir créé cette vue, vous pouvez interroger la vue pour obtenir les statistiques sur les
départements, comme ceci :
SELECT * FROM Vue_Statistiques_Departements;

c) créer une procédure stockée qui calcule le salaire moyen par département, et stocke les résultats
dans un tableau associatif où la clé est le nom du département et la valeur est le salaire moyen.
CREATE OR REPLACE PROCEDURE CalculerSalaireMoyenParDepartement IS
TYPE SalaireMoyenParDepartement IS TABLE OF NUMBER INDEX BY VARCHAR2(100);
salaire_moyen SalaireMoyenParDepartement;
CURSOR c_departements IS
SELECT d.nom_departement, AVG(e.salaire) AS salaire_moyen
FROM Employes e
JOIN Departements d ON e.departement = d.id_departement
GROUP BY d.nom_departement;
BEGIN
OPEN c_departements;
LOOP
FETCH c_departements BULK COLLECT INTO salaire_moyen;
EXIT WHEN c_departements%NOTFOUND;
END LOOP;
CLOSE c_departements;
FOR i IN 1..salaire_moyen.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('Département : ' || salaire_moyen(i).EXTEND);
DBMS_OUTPUT.PUT_LINE('Salaire moyen : ' || salaire_moyen(i));
END LOOP;
END;
/

CREATE OR REPLACE PROCEDURE calculer_salaire_moyen


IS
CURSOR departements_cursor IS
SELECT id_departement, nom_departement
FROM Departements;
salaire_moyen_departement NUMBER;
TYPE salaire_moyen_tab IS TABLE OF NUMBER INDEX BY VARCHAR2(100);
salaire_moyen_table salaire_moyen_tab;
BEGIN
FOR dept_rec IN departements_cursor
LOOP
SELECT AVG(salaire)
INTO salaire_moyen_departement
FROM Employes
WHERE id_departement# = dept_rec.id_departement;

salaire_moyen_table(dept_rec.nom_departement) := salaire_moyen_departement;
END LOOP;

-- Vous pouvez maintenant utiliser le tableau associatif "salaire_moyen_table" pour obtenir le


salaire moyen par département.
END;
/

CREATE OR REPLACE FUNCTION calculer_salaire_moyen RETURN SYS_REFCURSOR


IS
salaire_moyen_cursor SYS_REFCURSOR;
salaire_moyen_table SYS_REFCURSOR;
BEGIN
OPEN salaire_moyen_cursor FOR
SELECT nom_departement, AVG(salaire) AS salaire_moyen
FROM Employes e
JOIN Departements d ON e.id_departement# = d.id_departement
GROUP BY nom_departement;

RETURN salaire_moyen_cursor;
END;
/
Vous pouvez appeler cette fonction dans une requête SQL pour obtenir le salaire moyen par département. Par
exemple :

DECLARE
salaire_moyen_result SYS_REFCURSOR;
nom_departement Departements.nom_departement%TYPE;
salaire_moyen Employes.salaire%TYPE;
BEGIN
salaire_moyen_result := calculer_salaire_moyen();
LOOP
FETCH salaire_moyen_result INTO nom_departement, salaire_moyen;
EXIT WHEN salaire_moyen_result%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Le salaire moyen pour le département ' || nom_departement || ' est de ' ||
salaire_moyen);
END LOOP;
CLOSE salaire_moyen_result;
END;
/

Vous aimerez peut-être aussi