Vous êtes sur la page 1sur 5

Interrogation ABD N° 1 Dimanche 15/04/2018

Corrigé type
Exercice 1 :

Nous considérons la base de données d’Oracle stockée dans le compte Scott :


Emp(EmpNo, EName, Job, Mgr, Hiredate, Sal , Comm, DeptNo)

Dept(DeptNo, DName, Loc)

1. Ecrire un bloc PL/SQL affichant le nombre de lignes de la table Scott.Emp. Il contiendra


la commande SQL SELECT assignant une valeur à une variable (ou commande PL/SQL
SELECT … INTO maVariable FROM …;).
2. Ecrire une fonction (mémorisée) get_nb_job de paramètre un numéro de département et
qui retourne le nombre de métiers (différents) de ce département. On pourra typer le
numéro de département par Scott.Emp.DeptNo%TYPE.
On utilisera la commande SQL :
CREATE [OR REPLACE] FUNCTION [schéma.]fonction[(argument typeDonnée,…)]
RETURN typeDonnée IS/AS blocPL/SQL sans LeMotDECLARE;
Puis appeler cette fonction stockée en utilisant un bloc PL/SQL.
Qu’indique la vue USER_OBJECTS ? La fonction créée et le bloc PL/SQL sont-ils des
procédures stockées dans votre compte (stored procedure ou plus précisément stored
function) ?
3. Copier dans votre compte la table Dept de Scott. Lui ajouter la colonne nbjob, qui
contiendra le nombre des métiers de chaque département. On mettra à jour nbjob à partir
de la table Scott.Emp en utilisant la fonction stockée définie dans la question précédente.
Réponses :
1. Un bloc PL/SQL affichant le nombre de lignes de la table Scott.Emp (3 pt)

DECLARE
vnb_emp NUMBER(2);
BEGIN
SELECT COUNT(*) INTO vnb_emp FROM scott.emp ;
dbms_output.put_line('Nbr. total des employés : ' || vnb_emp );
END ;

2. Fonction get_nb_job (3 pt)


CREATE OR REPLACE FUNCTION get_nb_job ( p_deptno IN
Scott.Emp.DeptNo%TYPE
) RETURN number
IS
Vnbjob number (2);
BEGIN
SELECT COUNT(DISTINCT job) INTO vnbjob FROM scott.emp
WHERE deptno = p_deptno;
RETURN vnbjob;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Invalid department number ' || p_deptno);
RETURN 0;
END;
Utilisation dans un bloc PL/SQL (3 pt)
DECLARE
CURSOR c_dept IS
SELECT * FROM scott.dept ORDER BY deptno;
BEGIN
DBMS_OUTPUT.put_line('N°dept ' || ' Nom ' || ' Nbr de Jobs');
FOR vdept IN c_dept
LOOP
DBMS_OUTPUT.put_line(vdept.deptno|| ' ' vdept.dname ||' '|| get_nb_job (vdept.deptno));
END LOOP;
END;

3. Créer la table dept à partir de celle de Scott (1 pt)


CREATE TABLE dept AS SELECT * FROM scott.dept ;
Ajouter la colonne nbjob (1 pt)
ALTER TABLE dept ADD COLUMN nbjob NUMBER(2) ;
Mise à jour nbjob (3 pt)
DECLARE
CURSOR c_dept IS
SELECT * FROM dept FOR UPDTAE OF nbjob;
BEGIN
FOR vdept IN c_dept
LOOP
UPDATE dept SET nbjob = get_nb_job (vdept.deptno) WHERE CURRENT OF c_dept;
END LOOP;
END;
Exercice 2 :
Soit le schéma relationnel suivant:
Employé (Nom, Prénom, DNais, Adresse, NoEmp, Salaire, NoDep, Supérieur)
Supérieur REFERENCE Employé.NoEemp
N°Dep REFERENCE Département.NoDep
Département (NomD, NoDep, Directeur)
Directeur REFERENCE Employé.NàEmp
Projet (NomP, NoPro, Lieu, NoDep)
N°Dep REFERENCE Département.NoDep
Travaille (NoEmp, NoPro, Heures)
NoPro REFERENCE Projet.NoPro
NoEmp REFERENCE Employé.NoEmp
Précisions: L’attribut "Supérieur" dans la relation "Employé" contient le numéro
employé du supérieur direct de l’employé. Chaque employé appartient à un
département et travaille sur zéro, un ou plusieurs projets. Chaque projet est
rattaché à un département qui – attention – peut être différent de celui des
employés travaillant sur ce projet.
Exprimer en SQL les requêtes suivantes :
1. Date de naissance et adresse de Mustafa Mahmoud.
2. Nom et adresse des employés qui travaillent au département de recherche.
3. Nom et prénom des employés dont le supérieur est Mustafa Mahmoud.
4. Nom des employés qui travaillent plus de 10 heures sur un projet à Ouargla.
5. Nom des projets sur lesquels travaillent Omar Salhi et Mohamed Rassim.
Attention le "et" du français signifie ici que l’un ou l’autre, ou les deux,
doivent travailler au projet.
6. Nom des projets sur lesquels travaillent à la fois Omar Salhi et Mohamed
Rassim.
7. Nom et prénom des employés qui ne travaillent sur aucun projet.
8. Numéro des projets qui ont au moins un participant de chaque département.
9. Nom des employés qui ne travaillent pas sur un projet à Ouargla.
10. Nom des employés qui ne travaillent que sur des projets à Ouargla.
11. Pour chaque département donner son nom et le nombre d'employés qui y
travaillent.
12. Liste des numéros de départements qui ont moins de projets que la moyenne
(une vue).

Réponses :
1. SELECT DNais, Adresse FROM Employé
WHERE Nom=' Mahmoud ' AND Prénom=' Mustafa ' ;

2. SELECT Nom, Adresse FROM Employé


WHERE NoDep = (SELECT NoDep FROM Département WHERE
NomD='Recherche' ) ;
(autre solution)
SELECT Nom, Adresse FROM Employé, Département
WHERE Employé.NoDep=Département.NoDep AND NomD='Recherche'
;
3. SELECT E.Nom, E.Prénom FROM Employé E, Employé MM
WHERE MM. Nom=' Mahmoud ' AND MM.Prénom=' Mustafa ' AND
E.Supérieur=MM.NoEmp;
(autre solution)
SELECT Nom, Prénom FROM Employé WHERE superieur=(SELECT
NoEmp FROM Employé WHERE Nom=' Mahmoud ' AND Prénom='
Mustafa ') ;
4. SELECT Nom FROM Employé, Travaille, Projet
WHERE Employé.NoEmp=Travaille.NoEmp AND
Travaille.NoPro=Projet.NoPro
AND Lieu='Ouargla' AND Heures>10;

5. SELECT NomP FROM Employé, Travaille, Projet


WHERE Employé. NoEmp =Travaille. NoEmp AND
Travaille.NoPro=Projet.NoPro
AND ((Nom= Salhi ' AND Prénom=' Omar ') OR (Nom=' Rassim ' AND
Prénom=' Mohamed ')) ;

6. SELECT NomP FROM Employé, Travaille, Projet


WHERE Employé.NoEmp =Travaille. NoEmp AND
Travaille.NoPro=Projet.NoPro AND Nom= Salhi ' AND Prénom=' Omar '
INTERSECT
(SELECT NomP FROM Employé, Travaille, Projet
WHERE Employé. NoEmp =Travaille. NoEmp AND
Travaille.NoPro=Projet.NoPro AND Nom=' Rassim ' AND
Prénom=' Mohamed ') ;

7. SELECT Nom, Prénom FROM Employé


WHERE NOT EXISTS (SELECT * FROM Travaille
WHERE Employé. NoEmp =Travaille. NoEmp) ;
(autre solution)
SELECT Nom, Prénom FROM Employé
WHERE NoEmp NOT IN (SELECT NoEmp FROM Travaille) ;

8. SELECT NoPro FROM Projet


WHERE EXISTS (SELECT * FROM Département
WHERE EXISTS (SELECT * FROM Employé, Travaille
WHERE Employé. NoEmp =Travaille. NoEmp AND
Travaille.NoPro=Projet.NoPro AND
Employé.NoDep=Département.NoDep
));

9. SELECT Nom FROM Employé


WHERE NOT EXISTS (SELECT * FROM Travaille, Projet
WHERE Employé. NoEmp =Travaille. NoEmp
AND Travaille.NpPro=Projet.NpPro AND Lieu=' Ouargla ' ) ;

10. SELECT Nom FROM Employé


WHERE NOT EXISTS (SELECT * FROM Travaille, Projet
WHERE Employé. NoEmp =Travaille. NoEmp
AND Travaille.N°Pro=Projet.N°Pro AND Lieu#' Ouargla ' )
AND EXISTS (SELECT * FROM Travaille
WHERE Employé. NoEmp =Travaille. NoEmp) ;
(autre solution)
SELECT Nom FROM Employé
WHERE ' Ouargla ' = ALL (SELECT Lieu FROM Travaille, Projet
WHERE Employé. NoEmp =Travaille. NoEmp
AND Travaille.NoPro=Projet.NoPro ) ;

11. SELECT NomD, COUNT(NoEmp) FROM Employé, Département


WHERE Employé.NoDep=Département.NoDep
GROUP BY NomD ;

12. CREATE OR REPLACE VIEW DepPro (NoDep, NbPro)


AS SELECT NoDep, COUNT(NoPro)
FROM Projet
GROUP BY NoDep
HAVING COUNT (NoPro) < ( SELECT AVG(NoPro) FROM Projet) ;