Vous êtes sur la page 1sur 29

Ministère de l'Enseignement Supérieur et de la Recherche Scientifique

Université de Gabes
*-*-*-*-*
Institut Supérieur de l’Informatique de Médenine

Fascicule de travaux pratiques


SGBD avancé

Réalisé par :

Dr Imed ABBASSI
Enseignant chercheur à ISIM
ENIT, UR-OASIS, Université de Tunis El Manar, Tunis
imed.abbassi@enit.utm.tn

1
PRÉFACE

Le présent fascicule de travaux pratiques (TP) de SGBD avancé est à l’intention des étudiants de la
première année en master professionnel en Ingénierie des Logiciels et Connaissances de l’Institut Supé-
rieur de l'Informatique de Medenine (ISIM).

L’objectif de ce fascicule est d’étudier et matérialiser les concepts de PL/SQL présentés dans le cours
avec le SGBD Oracle.

Le fascicule comporte cinq TP avec leurs corrections qui sont réparties comme suit :
• TP 1 : Initiation à l’Oracle 10g et création d’une base de données.
• TP 2 : Interrogation de bases de données.
• TP 3 : La manipulation des blocs PL/SQL et des curseurs.
• TP4 : La manipulation des sous-programmes PL/SQL (les procédures et les fonctions stockées
et temporaires).
• TP 5 : La manipulation des packages, la gestion des exceptions et les triggers.

Dans ces TP, nous utilisons les outils suivants :


• Database 10g Express Edition
• Oracle SQL developer

2
Institut Supérieur d’Informatique Matière : SGBD avancé
de Médenine
TP n°1
Enseignant : Dr ABBASSI Imed Groupe : MP1 ILC

Partie I:
L’objectif de cette partie est de savoir créer un compte utilisateur sous Oracle 10g. Ce compte sera utilisateur tout
au long de ce TP. Pour cela, il faut suivre les étapes suivantes :
1) Accédez à la page d’accueil de la base de données.
2) Se connectez en tant qu’administrateur :
- Username: system
- Password: Isimed@2018
3) Créez votre propre compte (un nouvel utilisateur BD). Pour cela :
4) Cliquez sur l’icône Administration, ensuite cliquez sur utilisateurs de bases de données.
5) Donnez un nom à votre propre compte et définissez les privilèges requis.
6) Cliquez sur le bouton « Créer ».
7) Saisir un login et un mot de passe et cocher toutes les informations nécessaires.
8) Se déconnecter (cliquer sur le Bouton « Déconnexion » dans le coin supérieur droit de la page)
et reconnecter avec votre propre login et mot de passe que vous venez de créer.
9) Pour changer un mot de passe oublié, on peut taper les commandes suivantes à travers l'invite
de commandes :
- Tapez connect / as sysdba;
- Ensuite, tapez alter user {system|username} identified by new_password ;

Partie II:

On considère une base de données nommé TP1 dont le schéma relationnel est comme suit :
- EMP (Matr, NomE, Poste, DateEmb, Sup#, Salaire, Comm, NumDept#)
- DEPT(NumDept, NomDept, Lieu)
- PROJET (CodeP, NomP)
- PARTICIPATION (Matr #, CodeP#, Fonction)
Où :
- Tout attribut souligné de chaque relation désigne une clé primaire, tandis que celui précédé par le
symbole # indique une clé étrangère.
- L’attribut « Sup » désigne le matricule du supérieur direct de l’employé. Cet attribut peut être
NULL. Il s’agit d’une clé étrangère de la table EMP.
- Les types des attributs sont décrits comme suit :
o CodeP varchar(4)
o NomP varchar(15)
o NumDept number(5)
o NomDept varchar(15)

3
o Lieu varchar(20)
o Matr umber(4)
o NomE varchar(15)
o Poste varchar(20)
o DateEmb date
o Sup number(4)
o Salaire number(8,3)
o Comm number(8,3)
o Fonction varchar(15)

Question 1: Définissez les tables de la base de données sans introduire les contraintes d’intégrité.
Question 2: Remplissez les tables DEPT et EMP avec les données décrites par les tableaux ci-dessous:
DEPT
NumDept NomDept Lieu
10 Financier Sousse
20 Personnel Tunis
30 Administratif Sfax
40 Juridique Sousse

PROJET
CodeP NomP
P01 Sports
P02 Commercialisation
P03 Conception

EMP
Matr NomE Poste DateEmb Sup Salaire Comm NumDept
1020 Belhadj Commercial 06/01/02 1050 6000 2000 20
1030 Zarrouk DAF 01/06/02 1050 10000 5000 10
1040 Kallel Secrétaire 02/03/01 1030 2500 10
1050 Zouari DG 01/01/99 20000 8000 20

PARTICIPATION
Matr CodeP Fonction
1020 P02 Chef
1050 P02 Trésorier
1030 P01 Programmeur
1040 P01 Commercial

Question 3: Testez l’insertion de tuples incohérents vis-à-vis des contraintes d’intégrité:


a) L'Insertion d'un nouvel employé attaché à un département qui n’existe pas.
b) L’insertion d'un département qui dispose du même identifiant d’un autre existant dans la base.
Question 4: Suite à ces insertions, que peut-on dire sur la cohérence des données dans la base créée ?
Question 5: Ajoutez à toutes les tables les contraintes d’intégrité concernant les clés primaires.
Question 6: Corrigez ou supprimer les tuples incorrects.
Question 7: Ajoutez à toutes les tables les contraintes d’intégrité concernant les clés étrangères.

4
Question 8: Écrivez un script (évolution.sql) qui contient les instructions nécessaires pour ajouter les
colonnes suivantes (avec ALTER TABLE). Le contenu de ces colonnes sera modifié ultérieurement.
Table Nom, type et signification des nouvelles colonnes
EMP nbProjets NUMBER(2): Le nombre de projets d’un employé.
DEPT NbEmps NUMBER(2):Le nombre d’employés d’un département.
Projet durée NUMBER(2) : La durée de réalisation d’un projet (nombre de mois).

Question 9: Vérifiez la structure et le contenu de chaque table avec DESC et SELECT.


Question 10: Dans ce même script (évolution.sql), ajoutez les instructions nécessaires pour:
• augmenter la taille de la colonne nomE de la table EMP à VARCHAR(30).
• diminuer la taille de la colonne codeP de la table Projet à VARCHAR(3).
• tenter de diminuer la taille de la colonne nomP de la table Projet à VARCHAR(14).
Question 11: Pourquoi la commande n’est-elle pas possible ?
Question 12: Vérifiez par DESC la nouvelle structure des deux tables.

5
Institut Supérieur d’Informatique Matière : SGBD avancé
de Médenine
Correction du TP n°1
Enseignant : Dr ABBASSI Imed Groupe : MP1 ILC

Partie II:

Question 1:
--EMP (Matr, NomE, Poste, DateEmb, Sup, Salaire, Comm, NumDept#)
CREATE TABLE DEPT(
NumDept Numeric(5) not null,
NomDept varchar(15),
Lieu varchar(20)
);
--DEPT(NumDept, NomDept, Lieu)
CREATE TABLE EMP(
Matr Numeric(4) not null,
NomE varchar(15),
Poste varchar(20),
DateEmb date,
Sup Numeric(4),
Salaire Numeric(8,3),
Comm Numeric(8,3),
NumDept Numeric(5) not null
);
--PROJET (CodeP, NomP)
CREATE TABLE PROJET(
CodeP varchar(4) not null,
NomP varchar(25)
);
--PARTICIPATION (Matr #, CodeP#, Fonction)
CREATE TABLE PARTICIPATION(
Matr Numeric(4) not null,
CodeP varchar(4) not null,
Fonction varchar(15)
);

Question 2:
INSERT INTO DEPT VALUES (10,'Financier','Sousse');
INSERT INTO DEPT VALUES (20,'Personnel','Tunis');
INSERT INTO DEPT VALUES (30,'Administratif','Sfax');
INSERT INTO DEPT VALUES (40,'Juridique','Sousse');
INSERT INTO EMP VALUES (1020,'Belhadj','Commercial','06/01/02',1050,6000,2000,20);
INSERT INTO EMP VALUES (1030,'Zarrouk','DAF','01/06/02',1050,10000,5000,10);
INSERT INTO EMP VALUES (1040,'Kallel','Secrétaire','02/03/01',1030,2500,NULL,10);
INSERT INTO EMP VALUES (1050,'Zouari','DG','01/01/99',NULL,20000,8000,20);
INSERT INTO PROJET VALUES ('P01','Sports');
INSERT INTO PROJET VALUES ('P02','Commercialisation');
INSERT INTO PROJET VALUES ('P03','Conception');
INSERT INTO PARTICIPATION VALUES(1020,'P02','Chef');
INSERT INTO PARTICIPATION VALUES(1050,'P02','Trésorier');
INSERT INTO PARTICIPATION VALUES(1030,'P01','Programmeur');

6
INSERT INTO PARTICIPATION VALUES(1040,'P01','Commercial');

Question 3:
-- Insertion d'un nouvel employé attaché à un département qui n’existe pas
INSERT INTO EMP VALUES (1070,'Belhadj','Commercial','06/01/02',NULL,6000,2000,80);
/* Insertion un département qui dispose du même identifiant d’un autre existant dans
la base. */
INSERT INTO EMP VALUES (1070,'Belhadj','Commercial','06/01/02',1090,6000,2000,80);

Question 4:
Il est claire que l’état de la base de données est incohérent à cause de l’absence
de vérification des contraintes d’intégrité (clés primaires et clés étrangères).
Question 5:
ALTER TABLE DEPT ADD CONSTRAINT pkeyDEPT PRIMARY KEY(NumDept);
ALTER TABLE EMP ADD CONSTRAINT pkeyEMP PRIMARY KEY(Matr);
ALTER TABLE PARTICIPATION ADD CONSTRAINT pkeyPART PRIMARY KEY(Matr,CodeP);
ALTER TABLE PROJET ADD CONSTRAINT pkeyProjet PRIMARY KEY(CodeP);

Question 6: Il s’agit de supprimer les tuples ajoutés dans la question 3.


DELETE FROM EMP WHERE MATR=1070;
DELETE FROM EMP WHERE MATR=1020 AND NUMDEPT=20 AND POSTE='Commercial';

Question 7:
ALTER TABLE EMP ADD CONSTRAINT fkeyEMP FOREIGN KEY(NumDept) REFERENCES DEPT(Num-
Dept);
ALTER TABLE PARTICIPATION ADD CONSTRAINT fkeyPART1 FOREIGN KEY(Matr) REFERENCES
EMP(Matr);
ALTER TABLE PARTICIPATION ADD CONSTRAINT fkeyPART2 FOREIGN KEY(CodeP) REFERENCES
PROJET(CodeP);
ALTER TABLE EMP ADD CONSTRAINT fkSup FOREIGN KEY (Sup) REFERENCES EMP(Matr);

Question 8:
ALTER TABLE EMP ADD (nbProjets NUMERIC(2) DEFAULT 0);
ALTER TABLE DEPT ADD nbEmps NUMERIC(2) DEFAULT 0;
ALTER TABLE Projet ADD durée NUMERIC(2);

Question 9:
DESC EMP;
DESC DEPT;
DESC Projet;
SELECT * FROM EMP;
SELECT * FROM DEPT;
SELECT * FROM Projet;

Question 10:
ALTER TABLE EMP MODIFY nomE VARCHAR(30);
ALTER TABLE Projet MODIFY nomP VARCHAR(14);
ALTER TABLE Projet MODIFY codeP VARCHAR(3);

7
Question 11:
Une erreur est survenue lors de l’exécution de la deuxième commande SQL (modification
de la colonne nomP de la table Projet). En effet, lorsque la table n’est pas vide,
il n’est pas possible de diminuer la taille de certains attributs. Il est possible
de trouver des tuples dont la taille des valeurs d’attribut à modifier est plus
grande que nouvelle taille (dans notre cas, la nouvelle taille est 14). Il y a des
projets existants dont le nom dépasse le 14. Pour cette raison SQL n’autorise pas
ce type de modification de la structure.
Question 12:
DESC EMP;
DESC Projet;

8
Institut Supérieur d’Informatique Matière : SGBD avancé
de Médenine
TP n°2
Enseignant : Dr ABBASSI Imed Groupe : MP1 ILC

On considère la base de données du TP1 et composé des relations suivantes :

- EMP (Matr, NomE, Poste, DateEmb, Sup, Salaire, Comm, NumDept#)


- DEPT(NumDept, NomDept, Lieu)
- PROJET (CodeP, NomP)
- PARTICIPATION (Matr #, CodeP#, Fonction)

Question 1: Écrivez un script nommé requêtesSimples.sql, permettant d’extraire, à l’aide d’ins-


tructions SELECT, les données suivantes:
Q1. La liste des employés.
Q2. Le nombre des employés de chaque département.
Q3. Le nombre des employés participés à chaque projet.
Q4. Les noms des employés dont la deuxième lettre du nom est un E.
Q5. Le poste des employés ayant un salaire supérieur à 13000 DT.
Q6. Les noms des employés, dont le salaire inférieur à la commission.
Q7. Les noms des employés qui ne touchent pas de commission.

Question 2: Écrivez un script nommé requêtesModification.sql, permettant de réaliser les


tâches suivantes:
Q1. Créer un nouveau département : 50, Comptabilité, Tunis
Q2. Créer un nouveau département : 60, Direction
Q3. Changer la ville du département 60 à Sousse.
Q4. Promouvoir les PDG, dans le département 60.
Q5. Augmenter de 10% le salaire de tous les employés du département 10.
Q6. Ajouter l’employé M. Pascal qui vient d’être recruté comme un commercial au salaire de
1200DT et d’être enregistré sous le matricule 8010 dans le département 30.
Question 3: Écrivez un script nommé requêtesJointure.sql, permettant d’effectuer les requêtes
suivantes:
Q1. Noms des employés et lieu où ils travaillent.
Q2. Noms et Lieux des départements dans lesquels des employés touchent une commission.
Q3. Noms des supérieurs directs de chaque employé qui a un supérieur (nom des employés qui ont
un supérieur, suivi du nom du supérieur).
Q4. Noms des projets où sont inscrits des employés des départements de Sousse.

9
Institut Supérieur d’Informatique Matière : SGBD avancé
de Médenine
Correction du TP n°2
Enseignant : Dr ABBASSI Imed Groupe : MP1 ILC

Question 1:
--Q1-
select * from emp;
--Q2-
select NumDept, count(matr) as Nombre_emp from emp group by NumDept;
--Q3-
select CodeP, count(matr) as Nombre_emp from PARTICIPATION group by CodeP;
--Q4-
select nomE from emp where nomE like '_E%';
--Q5-
select distinct poste from emp where salaire > 13000;
--Q6-
select nomE from emp where salaire < comm;
--Q7-
select nomE from emp where comm is NULL ;

Question 2:
--Q1
insert into dept (NumDept, NomDept, lieu) VALUES (50 , 'Comptabilité', 'Tu-
nis');
--Q2
insert into dept (NumDept, NomDept) VALUES (60,'Direction');
--Q3
update Dept set lieu='Sousse' where NumDept = 60;
--Q4
update emp set poste='PDG', Numdept = 60 ;
--Q5
update emp set salaire=salaire*1.1 where Numdept = 60 ;
--Q6

10
insert into emp(Matr, NomE, Poste, Salaire, NumDept) values (8010, 'Pas-
cal', 'Commercial',1200,30)

Question 3:
--Q1
select NomE, Lieu from emp, dept where emp.NumDept=dept.NumDept;
--Q2
select distinct Lieu from emp, dept where emp.NumDept=dept.NumDept and emp.comm is
not null;
--Q3
select e.NomE, s.NomE from emp e, emp s where e.Sup = s.Matr;
--Q4
select distinct NomP
from emp, dept, participation, projet
where participation.CodeP = projet.CodeP
and emp.Matr = participation.Matr
and emp.NumDept = dept.NumDept
and dept.Lieu = 'Sousse';
--Avec des sous-interrogations:
select NomP from projet
where CodeP in
(select codeP from participation
where Matr in
(select Matr from emp
where NumDept in
(select NumDept from dept
where Lieu = 'Sousse')));

11
Institut Supérieur d’Informatique Matière : SGBD avancé
de Médenine
TP n°3
Enseignant : Dr ABBASSI Imed Groupe : MP1 ILC

Soit la base de données échantillon distribuée avec Oracle et décrite par son contenu ci-dessous :
- DEPT (DEPTNO, DNAME, LOC)
- EMP (EMPNO, ENAME, FONCTION, HIREDATE, SAL, COMM, #DEPTNO)
On notera que :
- Les clés primaires sont soulignées
- Les clés étrangères sont précédées par le symbole dièse (#).
- La création explicite d’un point de restauration (SAVEPOINT) avant le début d’une transaction
de modification de la base de données est fortement recommandée. Celle-ci est réalisée en
utilisant la commande suivante : SAVEPOINT SPi;
Question 1: Définissez en utilisant l’outil SQL*Plus d’oracle les tables DEPT et EMP. N’oubliez pas à définir
les clés primaires et étrangères en tant que contraintes nommées.
Question 2 : Remplissez les tables DEPT et EMP avec les données décrites par les tableaux ci-dessous:
a) Données de la table EMP
DEPTNO DNAME LOC
10 Financier Tunis
20 Recherche Sousse
30 Commercial Tunis
40 Informatique Sfax
50 Génie industriel Tunis
60 Génie mécanique Monastir
b) Données de la table DEPT:
EMPNO ENAME FONCTION HIREDATE SAL COMM DEPTNO
7369 Sassi Kamel Ouvrier 17/12/80 250 NULL 20
7499 Ben Saleh Med Vendeur 20/02/81 500 250 30
7521 Jebali Ali Vendeur 22/02/81 550 500 30
7566 Touati Med Directeur 02/04/81 1500 NULL 20
7654 Mefteh Moez Vendeur 28/09/81 500 1400 30
7698 Ajili Sadok Directeur 01/05/81 1400 NULL 30
7782 Sabri Saber Directeur 09/06/81 1550 NULL 10
7788 Hani Monia Chercheur 09/11/81 1000 NULL 20
7839 Hmida Sami PDG 17/11/81 3000 NULL 10
7844 Hafsa Moncef Vendeur 08/09/81 500 NULL 30
7876 Halima Kais Ouvrier 23/09/81 220 NULL 20
7900 Nafti Hamdi Ouvrier 03/12/81 240 NULL 30
7902 Kassem Saleh Chercheur 03/12/81 950 NULL 20
7934 Youssef Salem Ouvrier 23/01/82 250 NULL 10

Question 3 : Changez la localisation (LOC) du département commercial de Tunis à Ben Arous.

12
Question 4 : Dans EMP, augmentez de 10 % le salaire (SAL) des vendeurs dont la commission (COMM) est
supérieure à 50 % du salaire.
Question 5 : Dans EMP, attribuez aux employés en poste avant le ‘01-01-82’ (HIREDATE) et ayant une commis-
sion non spécifiée (NULL) une commission égale à la moyenne des commissions.
Question 6 : Annulez les trois mises à jour précédentes.
Question 7 : Écrivez un bloc PL/SQL qui:
- déclare un curseur explicite paramétré (P_Deptno et P_Fonction) ramenant les identifiants, les
noms et les salaires des employés travaillant dans le département P_Deptno et ayant la fonc-
tion P_Fonction.
- affiche les lignes des curseurs.
a) Proposez une première version utilisant une boucle LOOP.
b) Proposez une deuxième version utilisant une boucle FOR.
Question 8 : Écrivez un bloc PL/SQL qui permet de trouver l’employé le mieux payé.
a) Proposez une première version utilisant une boucle LOOP.
b) Proposez une deuxième version utilisant une boucle FOR.
Question 9 : Écrivez un bloc PL/SQL qui permet de trouver les employés dont les rémunérations (SAL+COMM
éventuelle) sont supérieures à 1000.
a) Proposez une première version utilisant une boucle LOOP.
b) Proposez une deuxième version utilisant une boucle FOR.
Question 10 : Écrivez un bloc PL/SQL qui calcule le total de toutes les rémunérations (SAL+COMM éventuelle)
des employés du département 20. Ce bloc doit également calculer le nombre d’employés dont le salaire est supé-
rieur à 800 et le nombre de ceux ayant des commissions supérieures à leur salaire.
a) Proposez une première version utilisant une boucle LOOP.
b) Proposez une deuxième version utilisant une boucle FOR.
Question 11 : Étendez la table DEPT par une nouvelle colonne NBEMP NUMBER(2) représentant le nombre
d’employés (0 par défaut).
Question 12 : Écrivez un bloc PL/SQL qui met à jour la colonne NBEMP pour tous les départements.
a) Proposer une première version avec un curseur implicite de mise à jour de la table DEPT.
b) Proposer une deuxième version avec un curseur explicite de mise à jour de la table DEPT.

13
Institut Supérieur d’Informatique Matière : SGBD avancé
de Médenine
Correction du TP n°3
Enseignant : Dr ABBASSI Imed Groupe : MP1 ILC

Question 1:
-- Création de la table DEPT
CREATE TABLE DEPT (
DEPTNO NUMBER(10) NOT NULL,
DNAME VARCHAR2(20),
LOC VARCHAR2(20),
CONSTRAINT pkeyDEPT PRIMARY KEY(DEPTNO)
);
-- Création de la table EMP
CREATE TABLE EMP(
EMPNO NUMBER(10) NOT NULL,
ENAME VARCHAR2(20),
FONCTION VARCHAR2(20),
HIREDATE DATE,
SAL REAL,
COMM REAL,
DEPTNO NUMBER(10) NOT NULL,
CONSTRAINT pkeyEMP PRIMARY KEY(EMPNO),
CONSTRAINT kkeyEMP FOREIGN KEY(DEPTNO) REFERENCES DEPT(DEPTNO)
);

Question 2 :
-- Script SQL d’insertion des données de la table DEPT
BEGIN
INSERT INTO DEPT VALUES(10,'Financier','Tunis');
INSERT INTO DEPT VALUES(20,'Recherche','Sousse');
INSERT INTO DEPT VALUES(30,'Commercial','Tunis');
INSERT INTO DEPT VALUES(40,'Informatique','Sfax');
INSERT INTO DEPT VALUES(50,'Génie industriel','Tunis');
INSERT INTO DEPT VALUES(60,'Génie mécanique','Monastir');
END ;
-- Script SQL d’insertion des données de la table EMP
BEGIN
INSERT INTO EMP VALUES (7369,'Sassi Kamel','Ouvrier','17-12-80',250,NULL,20);
INSERT INTO EMP VALUES (7499,'Ben Saleh Med','Vendeur','20-02-81',500,250,30);
INSERT INTO EMP VALUES (7521,'Jebali Ali','Vendeur','22-02-81',550,500,30);
INSERT INTO EMP VALUES (7566,'Touati Med','Directeur','02-04-81',1500,NULL,20);
INSERT INTO EMP VALUES (7654,'Mefteh Moez','Vendeur','28-09-81',500,1400,30);
INSERT INTO EMP VALUES (7698,'Ajili Sadok','Directeur','01-05-81',1400,NULL,30);
INSERT INTO EMP VALUES (7782,'Sabri Saber','Directeur','09-06-81',1550,NULL,10);
INSERT INTO EMP VALUES (7788,'Hani Monia','Chercheur','09-11-81',1000,NULL,20);

14
INSERT INTO EMP VALUES (7839,'Hmida Sami','PDG','17-11-81',3000,NULL,10);
INSERT INTO EMP VALUES (7844,'Hafsa Moncef','Vendeur','08-09-81',500,NULL,30);
INSERT INTO EMP VALUES (7876,'Halima Kais','Ouvrier','23-09-81',220,NULL,20);
INSERT INTO EMP VALUES (7900,'Nafti Hamdi','Ouvrier','03-12-81',240,NULL,30);
INSERT INTO EMP VALUES (7902,'Kassem Saleh','Chercheur','03-12-81',950,NULL,20);
INSERT INTO EMP VALUES (7934,'Youssef Salem','Ouvrier','23-01-82',250,NULL,10);
END;

Question 3 :
BEGIN
SAVEPOINT SP1;
UPDATE DEPT
SET LOC='Ben Arous'
WHERE DNAME= 'Commercial';
END ;

Question 4 :
BEGIN
SAVEPOINT SP2;
UPDATE EMP
SET SAL=SAL+SAL*0.1
WHERE FONCTION='Vendeur' AND COMM >= SAL*0.5;
END;

Question 5 : Dans EMP, attribuez aux employés en poste avant le ‘01-01-82’ (HIREDATE) et ayant une commis-
sion non spécifiée (NULL) une commission égale à la moyenne des commissions.
BEGIN
SAVEPOINT SP3;
UPDATE EMP
SET COMM= (SELECT AVG(COMM) FROM EMP WHERE COMM IS NOT NULL)
WHERE COMM IS NULL;
END;

Question 6 : Annulez les trois mises à jour précédentes.


ROLLBACK TO SAVEPOINT SP1;
Question 7 :
--une première version utilisant une boucle LOOP.
DECLARE
CURSOR v_emp_cursor(P_Deptno EMP.Deptno%TYPE, P_Fonction EMP.FONCTION%TYPE)
IS
SELECT EMP.Empno, EMP.FONCTION, EMP.SAL FROM EMP
WHERE EMP.Deptno=P_Deptno AND EMP.FONCTION LIKE P_Fonction;
emp_record v_emp_cursor%ROWTYPE;
BEGIN
OPEN v_emp_cursor(20,'Ouvrier');
DBMS_OUTPUT.PUT_LINE(RPAD('No.Emp',10)||RPAD('FONCTION',10)||LPAD('SALAIRE',10));
LOOP
FETCH v_emp_cursor INTO emp_record;
EXIT WHEN v_emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(RPAD(emp_record.Empno,10)||RPAD(emp_record.FONC-
TION,10)||LPAD(emp_record.SAL,10));
END LOOP;

15
CLOSE v_emp_cursor;
END;

-- Une deuxième version utilisant une boucle FOR.


SET SERVEROUTPUT ON;
DECLARE
CURSOR v_emp_cursor(P_Deptno EMP.Deptno%TYPE, P_Fonction EMP.FONCTION%TYPE)
IS
SELECT EMP.Empno, EMP.FONCTION, EMP.SAL FROM EMP
WHERE EMP.Deptno=P_Deptno AND EMP.FONCTION LIKE P_Fonction;
BEGIN
DBMS_OUTPUT.PUT_LINE(RPAD('No.Emp',10)||RPAD('FONCTION',10)||LPAD('SALAIRE',10));
FOR emp_record IN v_emp_cursor(20,'Ouvrier') LOOP
DBMS_OUTPUT.PUT_LINE(RPAD(emp_record.Empno,10)||RPAD(emp_record.FONC-
TION,10)||LPAD(emp_record.SAL,10));
END LOOP;
END;

Question 8 :
--une première version utilisant une boucle LOOP.
DECLARE
CURSOR v_emp_cursor IS SELECT * FROM EMP;
emp_record v_emp_cursor%ROWTYPE;
v_salaire_max EMP.SAL%TYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE(RPAD('No.Emp',10)||RPAD('ENAME',15)||RPAD('FONC-
TION',10)||LPAD('SALAIRE',10));
SELECT MAX(SAL) INTO v_salaire_max FROM EMP;
OPEN v_emp_cursor;
LOOP
FETCH v_emp_cursor INTO emp_record;
EXIT WHEN v_emp_cursor%NOTFOUND;
IF emp_record.SAL=v_salaire_max THEN
DBMS_OUTPUT.PUT_LINE(RPAD(emp_record.Empno,10)||RPAD(emp_rec-
ord.ENAME,15)||RPAD(emp_record.FONCTION,10)||LPAD(emp_record.SAL,10));
END IF;
END LOOP;
CLOSE v_emp_cursor;
END;

-- Une deuxième version utilisant une boucle FOR.


SET SERVEROUTPUT ON;
DECLARE
CURSOR emp_cursor IS SELECT EMPNO, ENAME, FONCTION, SAL FROM EMP;
v_salaire_max EMP.SAL%TYPE;
BEGIN
SELECT MAX(SAL) INTO v_salaire_max FROM EMP;
DBMS_OUTPUT.PUT_LINE(RPAD('No.Emp',10)||RPAD('ENAME',15)||RPAD('FONC-
TION',10)||LPAD('SALAIRE',10));
FOR emp_record IN emp_cursor LOOP
IF emp_record.SAL=v_salaire_max THEN
DBMS_OUTPUT.PUT_LINE(RPAD(emp_record.Empno,10)||RPAD(emp_rec-
ord.ENAME,15)||RPAD(emp_record.FONCTION,10)||LPAD(emp_record.SAL,10));

16
END IF;
END LOOP;
END;

Question 9 :

--Une première version utilisant une boucle LOOP.


DECLARE
CURSOR v_emp_cursor IS SELECT * FROM EMP;
emp_record v_emp_cursor%ROWTYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE(RPAD('No.Emp',10)||RPAD('FONC-
TION',10)||RPAD('SALAIRE',15)||LPAD('COMM',15));
OPEN v_emp_cursor;
LOOP
FETCH v_emp_cursor INTO emp_record;
EXIT WHEN v_emp_cursor%NOTFOUND;
IF (emp_record.SAL+emp_record.COMM) >= 1000 THEN
DBMS_OUTPUT.PUT_LINE(RPAD(emp_record.Empno,10)||RPAD(emp_record.FONC-
TION,10)||RPAD(emp_record.SAL,15)||LPAD(emp_record.COMM,15));
END IF;
END LOOP;
CLOSE v_emp_cursor;
END;

-- Une deuxième version utilisant une boucle FOR.


SET SERVEROUTPUT ON;
DECLARE
CURSOR v_emp_cursor IS SELECT * FROM EMP;
BEGIN
DBMS_OUTPUT.PUT_LINE(RPAD('No.Emp',10)||RPAD('FONC-
TION',10)||RPAD('SALAIRE',15)||LPAD('COMM',15));
FOR emp_record IN v_emp_cursor LOOP
IF (emp_record.SAL+emp_record.COMM) >= 1000 THEN
DBMS_OUTPUT.PUT_LINE(RPAD(emp_record.Empno,10)||RPAD(emp_record.FONC-
TION,10)||RPAD(emp_record.SAL,15)||LPAD(emp_record.COMM,15));
END IF;
END LOOP;
END;

Question 10 :

--Une première version utilisant une boucle LOOP.


SET SERVEROUTPUT ON;
DECLARE
CURSOR v_emp_cursor (P_Deptno EMP.DEPTNO%TYPE)
IS SELECT EMPNO,FONCTION,SAL,COMM FROM EMP WHERE DEPTNO=P_Deptno;
emp_record v_emp_cursor%ROWTYPE;
v_nombre_emp_comm NUMBER(10):=0;
v_nombre_emp_sal NUMBER(10):=0;
v_rem REAL:=0;
BEGIN

17
OPEN v_emp_cursor(30);
LOOP
FETCH v_emp_cursor INTO emp_record;
EXIT WHEN v_emp_cursor%NOTFOUND;
IF (emp_record.COMM IS NOT NULL) THEN
v_rem:=v_rem+(emp_record.SAL+emp_record.COMM);
END IF;
IF (emp_record.SAL) >= 800 THEN
v_nombre_emp_sal:=v_nombre_emp_sal+1;
END IF;
IF (emp_record.COMM IS NOT NULL AND emp_record.COMM >= emp_record.SAL) THEN
v_nombre_emp_comm:=v_nombre_emp_comm+1;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('La valeur totale des rémunérations est '||v_rem);
DBMS_OUTPUT.PUT_LINE('Le nombre d''employés dont le salaire est supérieur à 800
est '||v_nombre_emp_sal);
DBMS_OUTPUT.PUT_LINE('Le nombre d''employés ayant des commissions supérieures à
leur salaire est '||v_nombre_emp_comm);
CLOSE v_emp_cursor;
END;

-- Une deuxième version utilisant une boucle FOR.


SET SERVEROUTPUT ON;
DECLARE
CURSOR v_emp_cursor (P_Deptno EMP.DEPTNO%TYPE) IS SELECT * FROM EMP WHERE
DEPTNO=P_Deptno;
v_nombre_emp_comm NUMBER(10):=0;
v_nombre_emp_sal NUMBER(10):=0;
v_rem REAL:=0;
BEGIN
FOR emp_record IN v_emp_cursor (20) LOOP
IF (emp_record.COMM IS NOT NULL) THEN
v_rem:=v_rem+(emp_record.SAL+emp_record.COMM);
END IF;
IF (emp_record.SAL) >= 800 THEN
v_nombre_emp_sal:=v_nombre_emp_sal+1;
END IF;
IF (emp_record.COMM IS NOT NULL AND emp_record.COMM >= emp_record.SAL) THEN
v_nombre_emp_comm:=v_nombre_emp_comm+1;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('La valeur totale des rémunérations est '||v_rem);
DBMS_OUTPUT.PUT_LINE('Le nombre d''employés dont le salaire est supérieur à 800
est '||v_nombre_emp_sal);
DBMS_OUTPUT.PUT_LINE('Le nombre d''employés ayant des commissions supérieures à
leur salaire est '||v_nombre_emp_comm);
END;

Question 11 :
ALTER TABLE DEPT ADD (NBEMP NUMBER(2) DEFAULT 0);

Question 12 :

-- Solution 1 avec un curseur implicite de mise à jour

18
BEGIN
SAVEPOINT SP4;
UPDATE DEPT
SET NBEMP=(SELECT COUNT(*) FROM EMP WHERE DEPT.DEPTNO=EMP.DEPTNO);
END;

-- Solution 2 avec un curseur explicite de mise à jour


DECLARE
CURSOR v_dept_cursor IS SELECT * FROM DEPT FOR UPDATE OF NBEMP NOWAIT;
BEGIN
FOR dept_record IN v_dept_cursor
LOOP
UPDATE DEPT
SET NBEMP=(SELECT COUNT(*) FROM EMP WHERE dept_record.DEPTNO=EMP.DEPTNO)
WHERE CURRENT OF v_dept_cursor;
END LOOP;
END;

19
Institut Supérieur d’Informatique Matière : SGBD avancé
de Médenine
TP n°4
Enseignant : Dr ABBASSI Imed Groupe : MP1 ILC

Soit la base de données échantillon distribuée avec Oracle et décrite par son contenu ci-dessous :
- DEPT (DEPTNO, DNAME, LOC)
- EMP (EMPNO, ENAME, FONCTION, HIREDATE, SAL, COMM, #DEPTNO)
On notera que :
- Les clés primaires sont soulignées
- Les clés étrangères sont précédées par le symbole dièse (#).
Partie I :
Suppose que la table DEPT et EMP n’ont pas de clés primaires, le serveur Oracle n’est pas en mesure
de vérifier l’unicité des colonnes DEPTNO et EMPNO.
Question 1: Proposez une fonction stockée PKEY_DEPTNO_CHECKER qui permet d’implanter le
contrôle de l’unité de la colonne DEPTNO durant l’insertion d’un nouveau département. La fonction
retourne 1 en cas de violation de la règle d’unicité de la colonne DEPTNO, et 0 sinon.
a) Proposez une première version utilisant un curseur explicite.
b) Proposez une deuxième version utilisant un curseur implicite.
Question 1: Proposez un bloc PL/SQL qui permet de tester la fonction PKEY_DEPTNO_CHECKER.
Question 2: Proposez une fonction stockée PKEY_EMP_CHECKER qui permet d’implanter le con-
trôle de l’unité de la colonne EMPNO durant l’insertion d’un nouveau département. La fonction re-
tourne 1 en cas de violation de la règle d’unicité de la colonne EMPNO, et 0 sinon.
a) Proposez une première version utilisant un curseur explicite.
b) Proposez une deuxième version utilisant un curseur implicite.
Question 3: Proposez un bloc PL/SQL qui permet de tester la fonction PKEY_EMP_CHECKER.
Question 4: Sous SQL*Plus d’oracle, ajoutez la contrainte déclarative PRIMARY KEY aux tables
DEPT et EMP.
Question 5: Supprimer les fonctions stockées PKEY_DEPTNO_CHECKER et
PKEY_EMP_CHECKER du dictionnaire de données d’Oracle.
Question 6: Proposez un bloc PL/SQL permettant d’insertion d’un département tout en prévoyant une
exception qui tient compte de la présence de la contrainte de l’unité de la colonne DEPTNO.

20
Question 7: Proposez un bloc PL/SQL permettant d’insertion d’un employé tout en prévoyant une ex-
ception qui tient compte de la présence de la contrainte de l’unité de la colonne EMPNO.

Partie II :
Dans cette partie, on suppose que les tables DEPT et EMP ne sont pas liées par une contrainte d’intégrité
référentielle déclarative (FOREIGN KEY). On souhaite implanter cette règle par un sous-programme
PL/SQL.
Question 1: Proposez une fonction stockée FKEY_EMP_CHECKER qui permet la simulation de la
contrainte FOREIGN KEY lors d’une opération d’insertion d’un employé. La fonction doit retourner 1
en cas de violation de règle d’intégrité référentielle de la table EMP, et 0 sinon.
Question 2: Proposez un bloc PL/SQL qui permet de tester la fonction FKEY_EMP_CHECKER.
Question 3: Sous SQL*Plus d’oracle, ajoutez la contrainte d’intégrité référentielle déclarative à la table
EMP.
Question 4: Supprimer la fonction stockée FKEY_EMP_CHECKER du dictionnaire de données
d’Oracle.
Question 5 : Proposez un bloc PL/SQL permettant d’insertion d’un employé tout en prévoyant une
exception qui tient compte de la présence de la contrainte d’intégrité référentielle déclarative de la table
EMP.

21
Institut Supérieur d’Informatique Matière : SGBD avancé
de Médenine
Correction du TP n°4
Enseignant : Dr ABBASSI Imed Groupe : MP1 ILC

Partie I :
Question 1:
-- une première version utilisant un curseur explicite.
create or replace FUNCTION PKEY_DEPT_CHECKER(P_DEPTNO NUMBER) RETURN BOOLEAN
IS
V_DEPTNO NUMBER;
BEGIN
SELECT DEPTNO INTO V_DEPTNO FROM DEPT WHERE DEPTNO=V_DEPTNO;
RETURN true;
EXCEPTION
WHEN NO_DATA_FOUND THEN RETURN false;
END PKEY_DEPT_CHECKER;

-- une deuxième version utilisant un curseur implicite


create or replace FUNCTION PKEY_DEPT_CHECKER(P_DEPTNO NUMBER) RETURN BOOLEAN
IS
v_dept DEPT%ROWTYPE;
existe BOOLEAN:=FALSE;
CURSOR C IS SELECT * FROM DEPT WHERE DEPTNO = P_DEPTNO;
BEGIN
OPEN C;
FETCH C INTO v_dept;
IF(C%FOUND) THEN
existe:=TRUE;
END IF;
CLOSE C;
RETURN existe;
END PKEY_DEPT_CHECKER;

Question 2:
SET SERVEROUTPUT ON;
BEGIN
IF (PKEY_DEPT_CHECKER(80)) THEN
DBMS_OUTPUT.PUT_LINE('Le département existe');
ELSE
DBMS_OUTPUT.PUT_LINE('Le département n''existe pas');
END IF;
END;

Question 3: la solution est fortement similaire à celle proposée dans la question 1.

Question 4:

22
SET SERVEROUTPUT ON;
BEGIN
IF (PKEY_EMP_CHECKER(7830)) THEN
DBMS_OUTPUT.PUT_LINE('L''employé existe');
ELSE
DBMS_OUTPUT.PUT_LINE(' L''employé département n''existe pas');
END IF;
END;

Question 5:
ALTER TABLE DEPT ADD CONSTRAINT PKEY_DEPT PRIMARY KEY (DEPTNO);
ALTER TABLE EMP ADD CONSTRAINT PKEYEMP PRIMARY KEY (EMPNO);

Question 6:
DROP FUNCTION PKEY_DEPTNO_CHECKER;
DROP FUNCTION PKEY_EMP_CHECKER;

Question 7:
SET SERVEROUTPUT ON;
BEGIN
INSERT INTO DEPT VALUES(10,'Financier','Tunis');
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE('Insertion rejetée: Département existe déjà.');
END;

Question 8:
SET SERVEROUTPUT ON;
BEGIN
INSERT INTO EMP VALUES (7698,'Ajili Sadok','Directeur','01-05-81',1400,NULL,30);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE('Insertion rejetée: employé existe déjà.');
END;

Partie II :
Question 1:
create or replace FUNCTION FKEY_EMP_CHECKER(P_DEPTNO NUMBER)
RETURN BOOLEAN
IS
V_DEPTNO NUMBER;
BEGIN
SELECT DEPTNO INTO V_DEPTNO FROM DEPT WHERE DEPTNO=V_DEPTNO;
RETURN true;
EXCEPTION
WHEN NO_DATA_FOUND THEN RETURN false;
END KKEY_EMP_CHECKER;

23
Question 2:
SET SERVEROUTPUT ON;
BEGIN
IF (FKEY_EMP_CHECKER(80)) THEN
DBMS_OUTPUT.PUT_LINE('La contrainte d''intégrité est respectée.');
ELSE
DBMS_OUTPUT.PUT_LINE('La contrainte d''intégrité non respectée.');
END IF;
END;

Question 3: la solution est similaire à celle proposée dans la question 5 de la partie I.


Question 4: la solution est similaire à celle proposée dans la question 6 de la partie I.
Question 5:
SET SERVEROUTPUT ON;
BEGIN
INSERT INTO EMP VALUES (7898,'Ajili Sadok','Directeur','01-05-81',1400,NULL,70);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE('Insertion rejetée: employé existe déjà.');
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Insertion rejetée: le département n''existe pas.');
END;

24
Institut Supérieur d’Informatique A.U. 201 8/2019
de Médenine
TP n°5
Enseignant : Dr ABBASSI Imed Groupe : MP1 ILC

Soit la base de données échantillon distribuée avec Oracle et décrite par son contenu ci-dessous :
- DEPT (DEPTNO, DNAME, LOC, NBE)
- EMP (EMPNO, ENAME, FONCTION, HIREDATE, SAL, COMM, #DEPTNO)
Notez bien que la colonne NBE doit être initialisée à 0.

Question 1: Proposez une procédure stockée permettant d’insérer un nouveau département.


Question 2: Proposez une procédure stockée permettant d’insérer un nouvel employé.
Question 3: Proposez une procédure stockée qui détermine l’employé le mieux payé d’un département
quelconque tout en prévoyant des exceptions possibles.
Question 4: Proposez une procédure stockée qui permet de trouver les employés qui ont un salaire
supérieur à une valeur passée en paramètre. Ce bloc doit tenir compte des exceptions possibles.
Question 5: Proposez une procédure stockée qui affiche les rémunérations des employés, et qui tient
compte des exceptions possibles.
Question 6: Proposez une procédure stockée qui permet de trouver les employés dont les rémunérations
(SAL+COMM éventuelle) sont supérieures à une valeur passée en paramètre. Ce bloc doit tenir compte
des exceptions possibles.
Question 7: Proposez un package PKG_Gestion_EMP qui permet contient les sous-programmes sui-
vants :
a) Une fonction de recherche d’un employé dont l’identifiant est passé en paramètre.
b) Une procédure d’insertion d’un nouvel employé.
c) Une procédure de suppression d’un employé.
d) Une procédure de mise de l’état d’un employé.

Question 8: Proposez un package PKG_Gestion_DEPT qui permet contient les sous-programmes sui-
vants :
a) Une fonction de recherche d’un département dont l’identifiant est passé en paramètre.
b) Une procédure d’insertion d’un nouveau département.
c) Une procédure de suppression d’un département.
d) Une procédure de modification d’un département.
Question 9: Proposez un trigger nommé TRG_UPDATE_NBEMP permettant de mettre à jour automa-
tiquement la colonne NBEMP de la table DEPT.

25
Institut Supérieur d’Informatique A.U. 201 8/2019
de Médenine
Correction de TP n°5
Enseignant : Dr ABBASSI Imed Groupe : MP1 ILC

Question 1:
CREATE OR REPLACE PROCEDURE INSERER_DEPT(P_deptno IN NUMBER,
P_DNAME IN VARCHAR2,
P_LOC IN VARCHAR2,
STATUS OUT BOOLEAN
)
IS
BEGIN
INSERT INTO DEPT VALUES(P_deptno,P_DNAME,P_LOC);
STATUS:=TRUE;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
STATUS:=FALSE;
END INSERER_DEPT;

Question 2:
CREATE OR REPLACE PROCEDURE INSERER_EMP(P_EMPNO IN NUMBER,
P_ENAME IN VARCHAR2,
P_FONCTION IN VARCHAR2,
P_HIREDATE IN DATE,
P_SAL IN NUMBER,
P_COMM IN NUMBER,
P_DEPTNO IN NUMBER,
STATUS OUT BOOLEAN
)
IS
BEGIN
INSERT INTO EMP VALUES (P_EMPNO,P_ENAME,P_FONCTION,P_HIRE-
DATE,P_SAL,P_COMM,P_DEPTNO);
STATUS:=TRUE;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN STATUS:=FALSE;
WHEN OTHERS THEN STATUS:=FALSE;
END INSERER_EMP;

Question 3:
CREATE OR REPLACE PROCEDURE EMP_MIEUX_PAYE (deptid IN NUMBER)
IS
v_emp EMP%ROWTYPE;
sal_max EMP.SAL%TYPE;
BEGIN
SELECT max(SAL) INTO sal_max FROM EMP WHERE DEPTNO=deptid;
SELECT * INTO v_emp FROM EMP WHERE SAL=sal_max;
DBMS_OUTPUT.PUT_LINE(RPAD('No.Emp',10)

26
||RPAD('FONCTION',10)
||LPAD('SALAIRE',10));
DBMS_OUTPUT.PUT_LINE(RPAD(v_emp.empno,10)
||RPAD(v_emp.FONCTION,10)
||LPAD(v_emp.SAL,10));
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Le département n''existe pas');
END EMP_MIEUX_PAYE;

Question 4:
CREATE OR REPLACE PROCEDURE EMP_WITH_SUP_SAL (P_SAL IN NUMBER)
IS
CURSOR C IS SELECT * FROM EMP WHERE SAL> P_SAL;
BEGIN
DBMS_OUTPUT.PUT_LINE(RPAD('Empno',10)
||RPAD('NAME',10)
||RPAD('FONCTION',10)
||LPAD('SAL',10)
);
FOR rec IN C LOOP
DBMS_OUTPUT.PUT_LINE(RPAD(rec.Empno,10)
||RPAD(rec.ENAME,10)
||RPAD(rec.FONCTION,10)
||LPAD(rec.SAL,10)
);
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE ('Il n''existe aucun employé ayant un salaire
supérieur à 800.');
END EMP_WITH_SUP_SAL;

Question 5:
CREATE OR REPLACE PROCEDURE REM_EMP
IS
CURSOR C IS SELECT * FROM EMP;
BEGIN
DBMS_OUTPUT.PUT_LINE(RPAD('Empno',10)
||RPAD('NAME',10)
||RPAD('FONCTION',10)
||LPAD('REM',10)
);
FOR rec IN C LOOP
DBMS_OUTPUT.PUT(RPAD(rec.Empno,10)
||RPAD(rec.ENAME,10)
||RPAD(rec.FONCTION,10)
);
IF (rec.COMM IS NOT NULL) THEN
DBMS_OUTPUT.PUT_LINE(LPAD((rec.SAL+rec.COMM),10));
ELSE
DBMS_OUTPUT.PUT_LINE(LPAD((rec.SAL),10));
END IF;

27
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE ('Il n''existe aucun employé ayant un salaire
supérieur à 800.');
END;

Question 6: la solution est similaire à la procédure proposée dans la question 4.

Question 7:
--La spécification du package PKG_Gestion_EMP
CREATE OR REPLACE PACKAGE PKG_Gestion_EMP IS
FUNCTION CHECK_EMP(empid IN NUMBER) RETURN BOOLEAN;
PROCEDURE INSERER_EMP(P_EMPNO IN NUMBER,
P_ENAME IN VARCHAR2,
P_FONCTION IN VARCHAR2,
P_HIREDATE IN DATE,
P_SAL IN NUMBER,
P_COMM IN NUMBER,
P_DEPTNO IN NUMBER,
STATUS OUT BOOLEAN
);
PROCEDURE SUPPRIMER_EMP (empid IN NUMBER, STATUS OUT BOOLEAN);
END PKG_Gestion_EMP;
-- L’implémentation du package PKG_Gestion_EMP:
create or replace PACKAGE BODY PKG_Gestion_EMP IS
FUNCTION CHECK_EMP(empid IN NUMBER) RETURN BOOLEAN
IS
V_DEPTNO NUMBER;
BEGIN
SELECT DEPTNO INTO V_DEPTNO FROM DEPT WHERE DEPTNO=empid;
RETURN true;
EXCEPTION
WHEN NO_DATA_FOUND THEN RETURN false;
END;
PROCEDURE INSERER_EMP(P_EMPNO IN NUMBER,P_ENAME IN VARCHAR2,P_FONCTION IN VAR-
CHAR2,P_HIREDATE IN DATE, P_SAL IN NUMBER,P_COMM IN NUMBER, P_DEPTNO IN NUMBER)
IS
BEGIN
IF (CHECK_EMP(P_EMPNO)=TRUE) THEN
INSERT INTO EMP VALUES (P_EMPNO,P_ENAME,P_FONCTION,P_HIRE-
DATE,P_SAL,P_COMM,P_DEPTNO);
END IF;
END;
PROCEDURE SUPPRIMER (empid IN NUMBER)
IS
BEGIN
IF (CHECK_EMP(empid)=TRUE) THEN
DELETE FROM EMP WHERE EMPNO=empid;
END IF;
END;
END PKG_Gestion_EMP;

28
Question 8: la solution est similaire à la procédure proposée dans la question 7.
Question 9:
CREATE OR REPLACE TRIGGER TRG_UPDATE_NBEMP
AFTER INSERT OR DELETE OR UPDATE ON EMP
FOR EACH ROW
BEGIN
IF (INSERTING) THEN
UPDATE DEPT SET NBEMP=NBEMP+1 WHERE DEPTNO=:NEW.DEPTNO;
ELSIF (UPDATING) THEN
UPDATE DEPT SET NBEMP=NBEMP-1 WHERE DEPTNO=:OLD.DEPTNO;
UPDATE DEPT SET NBEMP=NBEMP+1 WHERE DEPTNO=:NEW.DEPTNO;
ELSE
UPDATE DEPT SET NBEMP=NBEMP-1 WHERE DEPTNO=:OLD.DEPTNO;
END IF;
END TRG_UPDATE_NBEMP;

29

Vous aimerez peut-être aussi