Vous êtes sur la page 1sur 18

Réponses Version 2017-03-06

Projet GPC-2010
André Gamache Département IFT-GLO, Université Laval
Solutions
Usinage et assemblage d’unités de logement pour le compte de promoteurs immobiliers

1 Dirige >
1..* SiteChantier
ClientPromo Finance > * Chef
* 0..1 1
noSC* : int nasC* :int
Associe matCP* : int
villeSC : varchar anServC : int
noAs* :int nomCP : varchar Supervise > lesTel : varray
nomAs adrCP : varchar 1..* 0..3 0..1
capAs : <<Projet>> ChangerChef()
(interface)
noP* : int
Proprio >

CompteBanque
livraisonP :Date
Usine
totalBudgetP : real noCB* : int
noU* : int margeP : real soldeCB : real
villeU : varchar dateOuvCB : Date
… dateFinCB : Date
PayerPar>
1 ….
(c,d) 1
1..*
Coordonne * ProjetCourant ProjetTermine

stDepensePC : real totalDepensesPT : real


cumulPayePC : real
ChargeProjet
margeDispPC : real
noCP* : varchar
nomCP varchar … *

* indique un attribut primaire (partie de clé)

Modèle de Gestion-Projet-Chantier (GPC)

NB Les interfaces sont incomplètes.

Réponses

Etape 1 : Transformez le diagramme de classe UML en un modèle navigationnel qui tient compte le plus
possible des contraintes notamment le sens du parcours des associations du diagramme de classe.
Gardez le nom des attributs et des associations.

Avec les étapes suivantes, vous implantez le modèle graduellement, par sous-modèles tel que présenté dans
l’étape en incluant les règles de gestion et les contraintes (contrainte d’attribut, de table et des triggers s’il y
a lieu) qui sont pertinentes. Lors de l’intégration, des contraintes supplémentaires devront être ajoutées.

© A. Gamache BDOO, Département d’informatique et de génie logiciel, faculté des Sciences et de génie, Université Laval,
Québec, Qc, Canada, G1K 7P4. Courriel : andre.gamache@ift.ulavala.ca
2

Etape 1 :

Le modèle navigationnel GPC du diagramme de classe est le suivant :

ClientPromo
matCP* : int
nomCP : varchar
adrCP : varchar
lesChantiers
lesAssocies Chef
SiteChantier nasC*:int
Associe anServC : int
noSC* : int
lesTel : varray
villeSC : varchar
noAs
leChefDirige
nomAs
leChefSuper
capAs

<<Projet>> ChangerChef()
(interface)
noP* : int
livraisonP :Date
Usine totalBudgetP : real CompteBanque
Proprio
margeP : real noCB* : int
noU* : int  leClient soldeCB : real
villeU : varchar  leProjet dateOuvCB : Date
dateFinCB : Date

(c,d)

ProjetCourant ProjetTermine
ChargeProjet
stDepensePC : real totalDepensesPT : real

noCP* : varchar cumulPayePC : real


nomCP : varchar margeDispPC : real
refPC refCB
refUs
(interface)

Les opérations des classes du diagramme DC-UML ne sont pas incluses. L’implantation de ce modèle est
faite par étapes successives dont l’aboutissement fournira le schéma total.

Etape 2
Supervision et direction de chantier (une partie du diagramme de classe)
Chaque chantier est dirigé par un chef mandaté par le ou les clients-promoteurs qui fiancent le chantier.
L’avancement des travaux des chantiers est aussi supervisé par un chef senior mandaté par les clients-
promoteurs impliqués dans le financement d’un chantier. Ce superviseur, choisi parmi les chefs de
chantier voit à informer les différents clients promoteurs sur l’avancement des travaux des chantiers qu’ils
financent. Un chef senior peut superviser jusqu’à 3 chantiers en cours. S’il dirige un chantier, il le
supervise obligatoirement. Les deux autres chantiers ne sont pas nécessairement sous sa direction.

Voici le diagramme de classe UML de départ :

© A. Gamache BDOO 2
3

SiteChantier Dirige >


Chef
0..1 1
noSC* : int
nasC* :int
villeSC : varchar
0..3 0..1 anServC : int
Supervise >

ChangerChef()

Le modèle navigationnel partiel correspondant est le suivant :

Chef

nas* :int
SiteChantier
anServ : int
noSC* : int
villeSC : varchar
leChefDirige
leChefSuper

ChangerChef()

Questions :
2.1 Formulez et implantez (sans les interfaces) le schéma objet correspondant à ce modèle. Créez les
tables nécessaires.

Create type Chef_t as Object(


nasC int,
anServC int )
/
Create type SiteChantier_t as Object(
noSC int,
villeSC varchar2(50),
leChefDirige REF chef_t,
leChefSuper REF chef_t ) /

2.2 Prenez en compte les contraintes pertinentes à ce modèle dans le DDL seulement. N’implémentez
pas à ce stade les contraintes formulées pour implémenter les multiplicités des deux associations.

Les contraintes se définissent que sur les tables.

Create table Chef of chef_t (


Constraint pk_nas Primary Key (nasC),
Constraint c_nas check(nasC>79 AND nasC<100),
Constraint c1_nas check (nasC IS NOT NULL)
)

© A. Gamache BDOO 3
4

Create table SiteChantier of siteChantier_t (


Constraint pk_noSC Primary Key (noSC),
Constraint c1_noSC check (noSC>99 AND noSC<1000),
Constraint c2_noSC check (noSC IS NOT NULL)
);

2.3 Implémentez explicitement la contrainte de non Null pour leChefDirige et celle du Null possible pour
leChefSuper, Ces deux contraintes ciblent le chef et sont ajoutées sans recréer la table.
Un attribut de référence doit être non null et tandis que l’autre peut-être null.

Alter table SiteChantier add Constraint c3_leChefDirige Check( leChefDirige IS NOT NULL) ;

2.4 Les multiplicités 0..1 et 0..3 des associations sont implémentées par des triggers d’objet BEFORE
INSERT lesquels triggers sont associés aux objets de la table-objet SiteChantier.
/* pour la multiplicité 0,1 de Dirige */
Create or Replace trigger tr_leChefDirige BEFORE Insert ON SiteChantier
for each row
Declare
res number := 0;
chefexiste Exception ;
autreErreur Exception ;
Begin
Select Count(*) into res From SiteChantier sc Where sc.leChefDirige = :new.leChefDirige;
If res != 0 then Raise chefexiste ; Else raise autreErreur ;
End If;
End;
Exception
When chefExiste then Raise_Application_Error(-20100, ‘le chef existe déjà’) ;
When autreErreur then Raise_Application_Error (20105, ‘erreur activée non traitée
spécifiquement’) ;
End ;
/
/* pour la multiplicité 0,3 */
Create or replace trigger tr_leChefSuper BEFORE Insert On SiteChantier
for each row
Declare
res number := 0;
Begin
Select count(*) into res From SiteChantier sc Where sc.leChefSuper = :new.leChefSuper;
If res = 3 then Raise_Application_Error ( - 20205, 'déjà 3 superviseurs pour ce site') ;
Else Null ;
End If;
End;
/

© A. Gamache BDOO 4
5

2.5 Ajoutez au moins 5 objets pour illustrer les validations des attributs et le déclenchement des triggers.

insert into Chef values(chef_t(80,10)); insert into Chef values(chef_t(81,11));


insert into Chef values(chef_t(82,13)); insert into Chef values(chef_t(83,11));
insert into Chef values(chef_t(84,11)); insert into Chef values(chef_t(85,16));
insert into Chef values(chef_t(86,17)); insert into Chef values(chef_t(87,18));
insert into Chef values(chef_t(88,19));

/* Insertions dans la table SiteChantier Déclenchement du trigger tr_leChefDirige


Comme l’application est un bloc PL/SQL qui ne récupère pas l’erreur, la pseudo application
s’arrête et un message approprié est affiché. */

Insert into SiteChantier values(SiteChantier_t(200,'Québec', (select REF(x) From Chef x where


x.nasC =80), (select REF(x) From Chef x where x.nasC = 80)));

Insert into SiteChantier values (SiteChantier_t(201,'Chisinau',(select REF(x) From Chef x where


x.nasC =80), (select REF(x) From Chef x where x.nasC =80)));

/* insertions pour déclencher le trigger tr_leChefSupervise */

Insert into SiteChantier values (SiteChantier_t(210,'Rabat',(select REF(x) From Chef x where


x.nasC=80), (select REF(x) From Chef x where x.nasC=80)));

Insert into SiteChantier values(SiteChantier_t(206,'Montréal',(select REF(x) From Chef x where


x.nasC=81), (select REF(x) From Chef x where x.nasC=80)));

Insert into SiteChantier values(SiteChantier_t(207,'Paris',(select REF(x) From Chef x where


x.nasC=84), (select REF(x) From Chef x where x.nasC =84)));

Insert into SiteChantier values(SiteChantier_t(208,'Paris',(select REF(x) From Chef x where


x.nasC=84), (select REF(x) From Chef x where x.nasC =85)));

ERREUR Ó la ligne 1 :
ORA-20100: lien ayant déjà un chef-dirigeant pour ce Site
ORA-06512: "ANGAMW.TR_LECHEFDIRIGE", ligne 7
ORA-04088: erreur lors d'exécution du déclencheur 'ANGAMW.TR_LECHEFDIRIGE'

Idem pour l’autre déclencheur.

2.6 Expliquez brièvement comment il sera possible de rechercher tous les sites-chantiers supervisés par
un chef particulier (le nasC sera fourni) et donnez un exemple de clause SQL pour y arriver. Exécuter la
clause pour obtenir un résultat significatif.
Pour y arriver, il faut utiliser l’oid du chef dont le nasC est connu. Cet oid sera comparé avec l’oid
de la référence leChefDirige de la table SiteChantier.

Select noSC, villeSC From SiteChantier sc

© A. Gamache BDOO 5
6

Where sc.leChefDirige = (Select ref(c ) from Chef c where c.nasC =80) ;

select nosc, villesc, deref(leChefdirige).nas from sitechantier;


select nosc, villesc, deref(leChefSuper).nas from sitechantier;

2.7 Écrivez un trigger pour valider que parmi les chantiers supervisés par un chef se trouve aussi un
chantier qu’il dirige. Ce trigger du genre Before est fusionné avec le trigger qui vérifie qu’un même chef
supervise jusqu’à un maximum de 3 chantiers.

Etape 3
Agrégation forte
Une partie du diagramme de classe UML de GPC est donné ci-dessous pour représenter les clients
promoteurs immobiliers et leurs associés. 1Un client corporatif peut avoir plusieurs associés investisseurs
qui amènent un capital limité dans le financement des chantiers. Le diagramme UML modélise avec une
agrégation forte ou dite de composition.

0..* ClientPromo :
Associe : matCP* : int
nomCP : varchar
noAs* :int adrCP : varchar
nomAs
capAs : real
modifnomClientPromo()
ajoutClientPromo()
augmenteCapital()

Le modèle navigationnel partiel correspondant est le suivant :

ClientPromo :
matCP* : int
nomCP : varchar
adrCP : varchar
lesAssocies

Associe : associe_t

noAs : int
nomAs :
capAs : int
augmenteCapital()

modifNomClient()
ajoutClientPromo

Le modèle navigationnel comprend un lien interne multiple et son interface composée de signatures.
modifNomClient() : méthode pour modifier le nom d’un client-.
ajoutClientPromo :`méthode pour ajouter un nouveau client–promoteur.

© A. Gamache BDOO 6
7

AugmenteCapital() : méthode pour augmenter de 10% le capital d’un associé. Cette méthode devra être
appelée par un objet-colonne.

Questions :
3.1 Expliquez brièvement la sémantique de l’agrégation forte dans ce petit modèle. Quel impact cette
agrégation sous-tend-elle lors des traitements.

Comme le stipule le scénario, lorsqu’un Client-promoteur cesse ses activités alors le lien avec ses
associes disparaît automatiquement. En implantant la composition avec une classe interne, en
supprimant un objet Client-Promoteur, ses associés sont aussi supprimés sans autres opérations.

3.2 Implémentez ce modèle (sans l’interface) : types et tables ainsi que les contraintes pertinentes à ce
modèle avec le DDL et si nécessaire, avec les triggers.

Create or replace Type associe_t as Object (noAs int, nomAs varchar2(30), capAs int)
/
Create OR Replace Type lesAssocies_t AS TABLE OF associe_t
/
Create Type clientPromo_t as Object (matCP int, nomCP varchar2(30), adrCP varchar2(30),
lesAssocies lesAssocies_t)
/
La contrainte se définit au niveau de la table, et ici au niveau de la table imbriquée, APRES la
création de la table contenante.

Create Table ClientPromo of clientPromo_t (


Constraint pk_clientPromo Primary Key (matCP),
Constraint c_matC Check (matCP >=10000 AND matCP <=10500))
NESTED TABLE lesAssocies STORE AS TablelesAssocies;

Les contraintes sur les attributs de l’objet-colonne ou de la table imbriquée s’appliquent sur la
table physique créée pour stocker les objets de la table imbriquée.
Dans ce cas-ci la table physique est connue car elle a été nommée par la création de la table
principale : TablelesAssocies

Alter Table TablelesAssocies ADD Constraint c1_noAs Check(noAs>=5000 AND noAs<=6000) ;


Alter Table TablelesAssocies ADD Constraint c2_capAs Check(capAs <=1000000) ;

3.3 Ajoutez quelques objets pour illustrer les instances possibles pour cette base correspondant au
modèle navigationnel. Une instance possible est définie comme un état valide de la base qui vérifie toutes
les contraintes.

Insert into ClientPromo values (clientPromo_t(10034, 'Etienne','Ste-Foy', lesAssocies_t (


associe_t (5002,'Kerris', 110000),
associe_t(5003,'Ana', 120000),
associe_t(5003,'Pierre', 830000)

© A. Gamache BDOO 7
8

)));

3.4 Formulez les deux signatures des méthodes, augmenteCapital pour augmenter le capital d’un associé
d’un pourcentage et modifNomClient() pour modifier le nom d’un client-promoteur. Ajoutez les deux
signatures à la classe externe ClientPromo..

Alter type clientPromo_t ADD Member Procedure modifNomClientPromo Cascade ;

Alter type clientPromo_t ADD Member Procedure augmenteCapitalAsso (capital In real) Cascade ;

3.5 Implémentez le body de la méthode ModifNomClient.


Notez l’absence du CASCADE :

Create OR Replace Type Body ClientPromo_t AS


MEMBER Procedure modifNomClientPromo
IS
clientP clientPromo_t ;
BEGIN
/* Select value(cp) into clientP from ClientPromo Where matCP = self.matCP ;
clientP.nomCP := self.nomCP ; */
Update ClientPromo cp set cp.nomCP = self.nomCP Where cp.matCP = self.matCP ;
end;
Member Procedure augmenteCapitalAsso (capital In real)
IS
Begin
Null ;
End ;
End ;
/
3.6 Écrivez un applicatif sous la forme d’un bloc PL/SQL pour modifier le nom d’un client déjà inscrit dans
la base en utilisant la méthode appropriée.

Declare
cp clientPromo_t ;
Begin
cp := NEW clientPromo_t ( 10034, ‘Jacques’, null, lesAssocies_t(associe_t(null, null, null))) ;
cp.modifNomClientPromo ; -- appel de la méthode
End ;
/

3.7 Écrivez un applicatif (bloc anonyme) en PL\SQL pour lancer l’exécution d’une procédure PL/SQL
appelée MajNomClient incluse dans un package nommé MAJ pour modifier le nom d’un client que vous
avez inscrit au préalable dans la base.

© A. Gamache BDOO 8
9

NB Il faut donc créer le package PL/SQL MAJ comprenant une procédure. Cette dernière sera appelée
(via le package) par un applicatif avec le <nom de la proc>.

La spécification du package :
Create or Replace Package Maj as
Procedure MajNomClient (mat IN int, nouvN IN varchar) ;
End Maj ;
/
Create or Replace package body MAJ as
Procedure MajNomClient (mat IN int, nouvN IN varchar) is
Begin
Update ClientPromo set nomCP = nouvN Where matCP = mat ;
End ;
End ;
/
L’applicatif est donc un bloc PL/SQL pouvant être aussi simple que :

Begin
MAJ.MajNomClient (10034, ‘Marie’) ;
End ;
/
Cependant, pour l’exécuter comme un énoncé SQL il faut faire un Execute :

sqlplus: Execute MAJ.MajNomClient (10034, 'Marie') ;

ProcÉdure PL/SQL terminÚe avec succÞs.

© A. Gamache BDOO 9
10

Etape 4
Le DC-UML ci-dessous représente les projets qui sont terminés, leur financement ainsi que leur
propriétaire. Une partie du modèle a été faite dans une étape précédente.
Pour les projets en cours, les charges mensuelles sont payées sous certaines conditions par un compte
bancaire associé à chaque projet.

Un projet courant se termine en se transformant (par un applicatif) en projet terminé lequel appartient à un
client promoteur.
1
ClientPromo
*
1
Associe matCP* : int
nomCP : varchar
noAs*
adrCP : varchar
nomAs
capAs augmenteCapitalAsso
modifNomClientPromo

<<Projet>>
noP* : int
CompteBanque
livraisonP :Date
Proprio totalBudgetP : noCB* : int
real soldeCB : real
margeP : real dateOuvCB : Date

PayerPar dateFinCB : Date


1
(c,d) 1

ProjetCourant ProjetTermine
stDepensePC : real totalDepensesPT : real
cumulPayePC : real
margeDispPC : real

© A. Gamache BDOO 10
11

Le modèle navigationnel augmenté mais toujours partiel est le suivant :

ClientPromo
matCP* : int
nomCP : varchar
adrCP : varchar

lesAssocies

associe_t

noAs
nomAs
capAs

<<Projet>> CompteBanque
AugmenteCapital
noP* : int noCB* : int
ModifNomClientPromo
livraisonP :Date soldeCB : real
totalBudgetP : real dateOuvCB : Date
Proprio
margeP : real dateFinCB : Date
refClient
refProjet …

(c,d)

ProjetCourant ProjetTermine

stDepensePC : real totalDepensesPT : real


cumulPayePC : real
margeDispPC : real
refCB

(interface)

Questions :
N.B. Lorsqu’il est demandé de développer une méthode, il faut aussi démontrer qu’elle s’exécute
correctement.

4.1 Donnez le schéma objet et créez les tables de ce modèle, incluant les contraintes pertinentes.
Les types :

Create type Projet_t as Object (noP int, livraisonP Date, totalBudgetP real, margeP real)
NOT INSTANTIABLE NOT FINAL
/
Create type compteBanque_t as Object (
noCB int,
soldeCB real,

© A. Gamache BDOO 11
12

dateOuvCB Date,
dateFinCB Date) FINAL INSTANTIABLE
/

Create or replace type projetCourant_t UNDER projet_t (


stDepensePC real,
cumulPayePC real,
margeDispPC real,
refCB REF compteBanque_t
) INSTANTIABLE FINAL
/

Create type ProjetTermine_t UNDER projet_t (


totalDepensesPT Real
) INSTANTIABLE FINAL
/

Create or Replace type Proprio_t as Object (


refClient REF clientPromo_t,
refProjet REF projetTermine_t) INSTANTIABLE FINAL
/
Le type ClientPromo_t est déjà créé et présent dans le dictionnaire du SGBD.

Les tables-objets :
Il y a 4 tables à créer : ProjetCourant, ProjetTermine, CompteBanque et Proprio. Les attributs
hérités n’ont pas à être décrits. Cependant les contraintes de chaque table doivent l’être même si
elles le sont avec des attributs hérités.

Create table ProjetCourant of projetCourant_t (


Constraint pk_ProjetCourant Primary Key (noP),
Constraint c1_noP check (noP>=1000 AND noP<=4999),
Constraint c2_noP check (noP IS NOT NULL)
);

Create table ProjetTermine of projetTermine_t (


Constraint pk_projetTermine Primary Key (noP),
Constraint c3_noP check(noP>=1000 AND noP<=4999),
Constraint c4_noP check (noP IS NOT NULL)
);
Create table CompteBanque of compteBanque_t (
Constraint pk_CompteBanque Primary Key (noCB),
Constraint c1_noCB check (noCB>=10000 AND noCB <=15000),
Constraint c2_noCB check (noCB IS NOT NULL)
);

© A. Gamache BDOO 12
13

Create table Proprio of proprio_t ;

Aucune clé primaire n’est déclarée pour la table Proprio bien que pour chaque objet Proprio soit
distinct lorsqu’il y une valeur combinée de deux oids. En l’absence d’un oid sur ProjetTerminé, les
2 attributs ne peuvent pas jouer le rôle de clé.

4.2 Expliquez comment il faut implémenter la contrainte disjoint de la spécialisation de la classe abstraite
Projet.
La classe abstraite <<Projet>> permet l’héritage des attributs et des signatures. Elle ne peut pas
être instanciée (NOT INSTANTIABLE) mais elle est spécialisée (NOT FINAL). Il ne pourra donc pas
y avoir d’objet du type projet_t.

Pour valider le disjoint, il faut vérifier que tout projet peut-être soit dans une ou l’autre des tables
mais pas dans les deux. La somme des objets dans les deux tables correspond à la somme des
projets.

Create or Replace trigger tr_DisjointProjetCourant AFTER insert or UPDATE of noP on


ProjetCourant For each row
Declare
nbP int;
invalideDisjoint Exception;
Begin
Select Count(*) into nbP From ProjetTermine pt where pt.noP = :NEW.noP;
if nbP!= 0 then raise invalideDisjoint;
End if;
Exception
When InvalideDisjoint Then Raise_application_Error(-21002,'Projet présent comme terminé');
End;
/
Vérification si un projet terminé n’est pas un projet courant.

Create or Replace trigger tr_DisjointProjetTermine After INSERT or UPDATE of noP on


ProjetTermine For each row
Declare
nbP int;
invalideDisjoint Exception;
Begin
Select Count(*) into nbP From ProjetCourant p where p.noP= :New.noP;
if nbP!= 0 then raise invalideDisjoint;
End if;
Exception
When InvalideDisjoint Then Raise_application_Error(-21002,'Projet encore inscrit’ );
End;
/

© A. Gamache BDOO 13
14

4.3 Surchargez le constructeur de clientPromo_t pour créer un nouveau client-promoteur qui n’aura
jamais d’associés.
En surchargeant ce constructeur, tout clientPromo créé avec ce constructeur ne pourra jamais
avoir d’associés. Si cela change par la suite, la mise ne sera pas possible autrement qu’en
recréant cet objet avec son constructeur implicite autorisant les associés.

ALTER TYPE clientPromo_t ADD


CONSTRUCTOR FUNCTION clientPromo_t (mat IN int, nom IN varchar2, adres IN varchar2)
RETURN SELF AS RESULT;
/

CREATE OR REPLACE TYPE BODY clientPromo_t AS


CONSTRUCTOR FUNCTION clientPromo_t (mat IN int, nom IN varchar2, adres IN varchar2)
RETURN SELF AS RESULT
IS
BEGIN
SELF.matCP := mat;
SELF.nomCP := nom ;
SELF.adrCP := adres ;
Self.lesAssocies := null ; -- enemble des associés est null
RETURN;
END;
END;
/

4.4 Ajoutez une méthode Member Ajout de type procedure dans le type projetCourant_t afin d’ajouter un
projetCourant avec le no, la date de livraison et le budget total fournis par l’appel de la méthode

Alter type projetCourant_t ADD


MEMBER procedure Ajout CASCADE ;

La clause CASCADE est nécessaire si la classe abstraite a été spécialisée. Avec CASCADE, la
nouvelle procédure devient visible par les sous-classes.

4.5 Modifiez le type pour ajouter le body de la méthode Ajout du type ProjetCournt_t de manière à insérer
un projet courant qui initialise automatiquement les autres attributs. Ces derniers sont null ou zéro sauf la
marge disponible qui est initialisée automatiquement comme 10% du budget total.

Create or Replace type body projetCourant_t AS


MEMBER procedure Ajout (no int, livraison Date, totalBud real)
IS
BEGIN
Self.noP := no ;
Self.livraisonP := livraison ;
Self.totalBudgetP := totalBud ;

© A. Gamache BDOO 14
15

Self.margeP := totalBud /10 ;


Self.stDepensePC := 0 ;
Self.cumulPayePC := 0 ;
Self.margeDispPC := totalBud /10 ;
Self.refCB := null ;
Insert into ProjetCourant values(self) ;
END ;
END ;
/

4.6 Formulez une méthode Static supp() dans le type ProjetCourant_t, signature et corps pour supprimer
un projet-courant. Expliquez comment elle est appelée dans une application. Dans quelles opérations
une telle méthode est utilisée.

Avec une méthode STATIC, le self n’est pas disponible et la méthode est appelée par son nom.
L'usage du SELF est donc interdit puisqu'il n'y a pas d'objet appelant. Une telle méthode est utile
pour les suppressions des objets dans les tables objets, sans avoir à créer un objet complet non
persistant pour appeler la méthode STATIC, il suffit d’avoir la clé, soit dans ce cas-ci le no de
projet à supprimer.

Signature de la méthode Supp :


Alter type projetCourant_t ADD STATIC Procedure Supp (no int);

Le corps de la méthode :

Create or Replace type body projetCourant_t AS


STATIC Procedure Supp (no int)
IS
comp int ;
BEGIN
Select count(*) into comp from ProjetCourant where noP = no ;
If comp = 1 then
Delete ProjetCourant where noP = no ;
End if ;
End ;
End ;
/
NB Le body du type est créé ou remplacé en ENTIER et non partiellement comme peut le laisser
supposé le ALTER Type.

4.7 Formulez une méthode (fonction) MAP mesureRisq pour comparer deux projets courants sur la base
du risque associé à chacun, mesuré par la différence entre le budget total et la marge consentis par la
banque à chaque projet. Une différence similaire pour 2 projets indique que les deux projets sont aussi
similaires sur la base du risque. Le projet avec le plus grand risque est celui dont la différence est la plus
grande pour le risque associé à deux objets.

© A. Gamache BDOO 15
16

Fonction sans liste de paramètres qui retourne un type simple : Char, varchar2 Real, Number et
Date. La valeur retournée pour chaque objet permet de vérifier une relation d'ordre entre les
objets. Chaque objet correspond à une valeur unique formée à partir des attributs de l'objet et qui
le positionne sur un axe linéaire. Une méthode MAP doit être définie obligatoirement à la racine
d’une hiérarchie.

Alter type projet_t ADD Map Member Function mesureRisq Return real Cascade;

Create or Replace Type Body projet_t AS


MAP MEMBER FUNCTION mesureRisq RETURN real
IS bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
diff real;
BEGIN
diff := self.totalBudgetP - self.margeP;
Return diff;
End mesureRisq ;
End;
/
Exemple d’appel de la fonction MAP dans un bloc PL/SQL :

DECLARE -- Applicatif
p1 projetCourant_t ;
p2 projetCourant_t ;
BEGIN
p1 := projetCourant_t (1100, null , 200000, 10000, 0, 0, 10000, null); -- projet plus risqué
p2 := projetCourant_t (1101, null , 100000, 50000, 0, 0, 50000, null);
IF p1 >p2 Then DBMS_OUTPUT.PUT_LINE(' *****p1 PLUS risqué que p2 ******');
ELSE DBMS_OUTPUT.PUT_LINE('****** p1 MOINS risqué que p2 *******');
END IF;
END;
/

****************************************

© A. Gamache BDOO 16
17

4.8 Formulez une méthode ORDER compareProjet() pour tester la similarité relative de deux projets
courants. Deux projets courants sont similaires si la date de livraison de chacun est à un mois près et
leur budget égaux à 10% près.

La méthode ORDER compareProjet() doit être programmée pour retourner un entier comme résultat pour
indiquer la similarité de 2 projetCourants:
-1 l'objet du paramètre est plus petit que celui qui l'appelle;
0 si les 2 objets sont égaux
+1 l'objet du paramètre est plus grand que celui qui l'appelle;

Alter type Projet_t ADD ORDER MEMBER FUNCTION CompareProjet (u Projetc_t) Return integer
cascade;

Create or Replace Type body Projet_t AS


ORDER MEMBER FUNCTION CompareProjet (u IN projet_t) Return integer IS
BEGIN
IF self.totalBudgetP = u.totalBudgetP and self.margeP = u.margeP THEN Return 0;
ELSIF self.totalBudgetP < u.totalBudgetP and self.margeP < u.margeP Then Return -1;
ELSIF self.totalBudgetP > u.totalBudgetP and self.margeP > u.margeP Then Return +1;
ELSE return 9; - - les projets ne sont pas comparables
End if;
End CompareProjetc;
End;
/

Supposons 2 objets dans la base :


p1 := Projetc_t(1200,'16-10-2009',9898,98989);
p2 := Projetc_t(1300,'16-10-2009',9898,98989);

L’applicatif ci-dessous comparera les deux objets, Pour comparer tous les objets deux à deux, il
faudra faire appel à deux curseurs parcourus pour faire la lecture du produit cartésien.

DECLARE
p1 Projetc_t ;
p2 Projetc_t;
BEGIN
p1 := Projetc_t(1200,'16-10-2009',9898,98989); -- objet non persistant
p2 := Projetc_t(1300,'16-10-2009',9898,98989);
IF p1 = p2 Then DBMS_OUTPUT.PUT_LINE( '*****projet1 et projet2 sont égaux*****');
ELSE DBMS_OUTPUT.PUT_LINE('*******projet1 et projet2 sont différents********');
END IF;
END;

© A. Gamache BDOO 17
18

Etape 5
Le modèle navigationnel du GPC initial est ainsi obtenu par l’intégration des sous-modèles précédents.
Modification du GPC navigationnel pour obtenir un GPC*
Ce modèle GPC initial est enrichi par l’ajout d’attributs et de liens interne et externe :

a- Un nouvel attribut à la classe SiteChantier est ajouté pour représenter deux numéros de téléphone pour
à chaque chantier. Ces téléphones sont utilisés pour rejoindre le chef ou le superviseur. Le premier (1) est
le téléphone cellulaire du chef de chantier et le deuxième (2) est le téléphone cellulaire portable du
superviseur. L’ordre des numéros d’appel est donc significatif. Les deux numéros de téléphone peuvent
être les mêmes dans quelques cas.
b- Dans le modèle obtenu par l’ajout des deux numéros de téléphone, il faut aussi implémenter
l’association Supervise différemment pour privilégier un parcours de l’association Supervise vers
SiteChantier. L e modèle obtenu est le GPC*.

Questions : (Utilisez le modèle initial GPC)


5.1 Modifiez le Mnav de GPC pour inclure le nouvel attribut tel (téléphone) et introduire le nouveau lien
externe multiple.
5.2 Donnez le nouveau schéma pour les classes SiteChantier et Chef qui sont modifiées.
5.3 Formuler une méthode modifTelChef permettant de modifier le numéro de téléphone du chef.
Choisissez le type de méthode le plus approprié pour celle-ci.
5.4 Écrire une procédure PL/SQL pour faire la mise à jour au moyen de cette méthode. La procédure est
appelée par un CALL.
5.5 Développez une méthode pour afficher le total dépensé pour un projet particulier qui est maintenant
terminé. Formulez une clause SQL SELECT pour lire ce total dépensé au moyen de la méthode et de
l’afficher au moyen d’une procédure PL/SQL.

Etape 6
6.1 Développez une application en PL/SQ utilisant que des méthodes pour effectuer l’affichage d’un
compte bancaire pour un client particulier.

6.2 … pour effectuer la mise à jour de la ville d’une usine particulière.

6.3… pour effectuer l’ajout d’un nouveau projet.

6.4 … pour effectuer la suppression d’un chef.

***

© A. Gamache BDOO 18

Vous aimerez peut-être aussi