Vous êtes sur la page 1sur 175

Université Tunis El Manar

Bases de données avancées


Section: IF5 - Option ISIAD
Département des Sciences de l’Informatique

Chapitre 2-a
Les bases de données relationnelles objets

mohamedali.benhassine@fst.utm.tn
© Med Ali Ben Hassine 2017 (FST) 1
Introduction

 Concepts Orienté Objet


 Classe, Objet, Méthode
 Encapsulation, Héritage

 De nouvelles applications avec des données complexes


 Médicale, CAO / DAO, SIG …

 Une autre charge de travail


 reflète l’activité de conception
 Transactions longues
 Workflow, Coopération

2
Introduction

Sy
do

3
Le paradigme Objet : notion d'objet

 Un objet est un triplet <Oid, classe, etat>


 Oid (Object Identifier): identifiant de l'objet, unique, invariant durant un
programme
 État: valeurs des attributs de l'objet (varie durant un programme)
 Classe: les attributs et les opérations de la classe définissent le
comportement de l'objet.

 Identité d’objet :
 Chaque objet a une identité indépendante de sa valeur.
 L’identificateur est géré par le système (correspond à une clef interne).
 Deux objets sont identiques s’ils ont le même identificateur, et sont égaux
s’ils ont la même valeur.
 Les objets peuvent être représentés par un graphe de composition, qui peut
comporter des cycles.
4
Le paradigme Objet : Classe

 Les objets partageant des caractéristiques communes (structure et


comportement) sont regroupés dans des classes.
 Les classes permettent une abstraction des informations et de leur
représentation. Ce sont les concepts utilisés pour décrire le schéma de la BD.

 Ex: Class Personne


 Un attribut est défini par son nom et son type
[nom : string,
age : integer,  Une opération est une fonction qui permet de
adresse : string, modifier l'état d'un objet ou de renvoyer une valeur
 Valeur :
conjoint : Personne,
– Valeur atomique (valeur de type simple :
enfants : {Personne} ] caractère, entier, booléen, …)
method get_age() : integer, – Valeur complexe : les tuples, les ensembles,
get_adresse(): string les listes, sont des valeurs complexes

 Une classe fournit un mécanisme de création d'objets (Instanciation)


 Extension de la classe : Ensemble de ses instances

5
Le paradigme Objet : Encapsulation

 Un objet est constitué


 de données
 d’opérations applicables à ces données
 On distingue l’interface (description des opérations applicables à l’objet), de
l’implémentation (structure des données physique et code des opérations).
 L’utilisateur ne voit que l’interface, les données sont encapsulées.

6
Le paradigme Objet : Héritage

 Mécanisme permettant la transmission des propriétés communes (structure


et/ou méthodes) d'une classe à une sous classe;
 Une sous-classe hérite des propriétés de sa super-classe.

 Spécialisation : affiner une  Généralisation : création d’une super-


classe en une sous-classe. classe regroupant les caractéristiques
communes à plusieurs classes.

 Spécialiser la classe Personne  Généraliser les classes Voiture et


en la classe Employé Camion en une classe Véhicule 7
Le paradigme Objet : Héritage

 Héritage simple : une propriété est héritée d'une seule surclasse


 Héritage multiple : une sous-classe possède plusieurs surclasses

8
Le paradigme Objet : Surcharge & Polymorphisme

Surcharge
 Le fait de redéfinir une propriété, dans une sous-classe, qui serait héritée
d'une superclasse.

Polymorphisme
 Le fait de disposer d'opérations ayant un même nom mais avec des
paramètres différents en nombre et/ou en type.

Liaison dynamique
 Mécanisme de sélection du code correspondant à l'opération concernée en
fonction des paramètres passés pendant l'appel.

9
BD Objet (BDO)
 La différence essentielle entre les objets manipulés dans les programmes et
dans les BD est la persistance:
 La durée de vie d'un objet dans une BD objet ne doit pas limitée à celle du
programme qui le crée.

 Si on gère les objets par l'approche classique des fichiers, les programmes
deviennent très coûteux et ne permettent pas de gérer la concurrence.

 La gestion des accès concurrents aux données est bien rodée dans les BD

 BD Objets
 Organisation cohérente d'objets persistants partagés par plusieurs utilisateurs
concurrents.

10
Les « Manisfesto »

 Codd, 1969
 Modèle relationnel

 Codd, 1990
 Modèle relationnel V2

 Atkinson et al, 1989


 The Object-Oriented Database System Manifesto

 Stonebraker et al, 1990


 Third Generation DataBase System Manifesto

 Darwen et Date, 1995


 The Third Manifesto

11
L'Objet dans les BD : deux Approches

 Le modèle Orienté Objet (OO)  Le modèle Objet-Relationnel (OR)

Smalltalk, C++, ... Codd (70)

OODBMS SQL
SQL2
ODMG 93
ODMG II SQL3 SQL 2003, 2008, 2011
ODMG (97) ANSI X3H2
Convergence SQL4 ISO/IEC JTC1/ SC21/WG3
CA-Jasmine, ?
ObjectStore, O2, Oracle, Informix,
Versant, POET, ... Sybase, IBM, DB2,
CA-OpenIngres

12
Les Propriétés RICE (Miranda) 1,2

Réutilisation
 Finalité du paradigme objet : héritage, généralité, composition, polymorphisme

Identification
 Identifier un objet de manière unique

Complexité
 définition de objets complexes et/ou fortement structurés

Encapsulation
 boîte noire avec des méthodes de manipulation

1(Miranda, 1996) Eyrolles


2(Miranda, 2002) Dunod

13
Les Modèles Objets et les Propriétés RICE

L’Objet-Relationnel (SQL3) L’Objet « Pur » (ODMG)


Réutilisation  Héritage (clause UNDER)  Héritage Multiple
 Polymorphisme (surcharge) et
TEMPLATE (généricité)
Identification  OID  OID
Complexité  ADT (Abstract Data Type)  Collections (SET, BAG, LIST,
 Collections (SET, LIST, …) ARRAY)
 Opérateurs VALUE, REF et DEREF  Pointeurs REF et INVERSE
Encapsulation  FUNCTIONs et PROCEDUREs  Attributs
associées à l’ADT  Méthodes
 Niveau d’encapsulation (public,
protected, private)

 2ième Manifeste de Stonebraker, 3ième Manifeste de Date  1er Manifeste de Bancilhon


14
Outils de gestion (éditeurs commerciaux de SGBD)

 Objet relationnel : Oracle 8i et plus , DB2, PostgreSQL, …

 Objet: O2, GemStone, Jasmine, Versant, …

 Portail sur les BD objets : http://www.odbms.org/


The Resource Portal for Big Data and New Data Management Technologies

15
LES BD RELATIONNELLES OBJETS

16
Introduction

 Extension du modèle relationnel aux concepts objets


 Définition de User Defined data Type (UDT)
 Données + Méthodes, Structuration, Héritage, Non First Normal Form
(NF2) Values, Références ...
 Intérêt :
 Systèmes patrimoniaux (Legacy Systems)
 Conserve la compatibilité des applications relationnelles
 Evolutivité douce
 Structurations plus complexes (i.e. riches)
 Définition d’Object View sur une base de données relationnelle

17
Modèle de données NF2 (Non First Normal Form)

 Forme normale tolérant des domaines multivalués.


 Structure des objets complexes dans un contexte relationnel.
 Cohabitation des notions de table (données en 1ère FN) et de
données de type complexe (ou objet).

 Une table en NF2 peut contenir un attribut composé d’une liste de


valeurs et/ou un attribut composé de plusieurs attributs.
⇒ Meilleur niveau conceptuel,
⇒ Moindre besoin d’aplatir le monde modélisé,
⇒ Moins de jointures.

18
Exemple : la table Personne

{enfant} {voitures} …
Date_
Nom prénom
naissance
prénom_enfant Modèle photo année no

Tarek
2ch 1980 128
Salah
Ben
Ali 16-05-1963
Amor

Sarra Mégane 2014 371

Hajer
Riahi Rim 29-02-1944 GOLF 7 2013 17
Ines

19
Relationnel-objet ou Object Pure ?

Le relationnel-objet
 Gère les bases relationnelles déjà en service, très nombreuses (le data legacy );
⇒ Capitalise sur les acquis permettant une migration évolutive (en douceur) du SGBDR vers l’objet.
 Conserve les notions de tables comme container d’objets.
 Permet l'encapsulation des données : implémentation de l’interface (des méthodes)
⇒ Moins de jointures, références directes ⇒ Meilleures performances ! (en théorie)
 Permet de définir de nouveaux types utilisateur simples ou complexes (ADT)
 Concepts NF2 : structure complexe avec collection +
 Possibilité de référencer les données (similaire à la notion d'oid)
 Extensions du langage SQL (SQL3) pour la recherche et la modification des données

L’objet pure
 Manque de normalisation pour les SGBDO / trop de solutions propriétaires.
 SGBDOO moins souple que le relationnel pour s’adapter à plusieurs applications et
à l’augmentation de charge.
 Peu d'informaticiens formés aux SGBDO. 20
Les problèmes de l'OR

 Ne s'appuie pas sur une théorie solide comme le modèle relationnel.


 Manque de standard de fait : implantations différentes, et encore
partielles, dans les divers SGBDs.
 N'est pas 100% conforme à la norme ODMG

 La structure d’objet est plus complexe à gérer par les structures


disponibles dans les applications (langages de développement): usage
d’outils de mapping des objets (JPublisher, Hibernate, …).
 N'implémente pas l'héritage multiple. Idem pour Java sauf pour C++.
 Utilise la notion explicite de REF qui est en quelque sorte un pointeur
logique lequel devrait être normalement non visible.

21
SQL99 (SQL3)

 Cette partie du cours s’appuie autant que possible sur les spécifications de SQL99.
 Le langage SQL99 ajoute à SQL2 des variables et instructions de contrôle pour en
faire un langage procédural complet ; ce cours ne porte pas sur ces extensions.
 Les exemples concrets sont donnés dans le langage SQL de la version 10g
d’Oracle ; les différences avec SQL99 seront signalées.
 SQL3 intègre les 2 Manifestes OR ! Avec 2 possibilités de créer des CLASSES
d OBJETS
 CREATE TYPE (« Date »)
 CREATE TABLE (« Stonebraker »)

22
Concepts SGBDRO (Oracle)

 Le modèle géré par Oracle (8i, 9i, 10g et +) est dit OR parce qu'il peut
gérer simultanément les modèles relationnel et objet . Il est hybride !!

Concepts SGBD Concepts objets

●Persistance ●Objet
●Gestion du disque ● Encapsulation
●Partage des données ● Identité complexe
●Fiabilité ● Identité d’objet
●Sécurité ● Classe  Table
●Langages de requête d'objet
●Indépendance Logique ●Héritage
/ Physique ● Redéfinition

 Extension de SQL
 Définition des types complexes avec héritage
 Appels de méthodes en résultat (Select) et qualification (Where)
 Imbrication des appels de méthodes
 Surcharge d'opérateurs 23
Le SGBDRO Oracle

 Pas de classe
 Il faut créer un type abstrait de données (TAD), puis une table ayant ou
utilisant ce type.
 Implémentation des méthodes liées au TAD

 Héritage (à partir d'Oracle 9 et +) avec la clause UNDER.

 Surcharge possible des noms de méthodes


 2 méthodes d’un TAD avec le même nom et des paramètres différents =>
Oracle choisit la bonne méthode à l’exécution.
 Surcharge des opérateurs Oracle interdite.

 Encapsulation: simulation à travers un package PL/SQL.


24
1. Les TAD

Type: implémenté par une structure généralement complexe, le TAD (Type


Abstrait de Données) (en anglais ADT Abstract Data Type ou encore
UDT : User defined type) à laquelle des méthodes ou des opérations
sont associées afin de gérer le comportement du TAD.

Deux extensions par rapport au modèle relationnel :

I.Les TAD (Types abstraits de données),


1. Composition de types,
2. Collections,
3. Références, Types complexes
4. Méthodes.

II.Les oid via les pointeurs.

25
1. Les TAD

 Dans tout TAD peuvent être ajoutées des méthodes (procédures ou


fonctions PL/SQL) pour manipuler les objets du TAD, mais pas de
contraintes.

 Impossible de créer une instance d’un TAD directement, il faut


créer et passer par une table !

 Navigation à travers les instances des TAD avec la notation pointée


et un alias sur chaque table.

26
1. Les TAD

27
1. Les TAD

1.1 Composition de types

 Un TAD dans le modèle RO peut être perçu comme :

A. Un nouveau type d’attribut simple défini par l’utilisateur


(concerne 1 seul attribut),
 CREATE TYPE typemot AS varchar2;
 CREATE TABLE code (mot typemot(8), code
typemot(25));
ou

B. Une structure de données partagée: un TAD peut être utilisé dans


plusieurs tables.

28
1. Les TAD

1.1 Composition de types


B. TAD perçu comme une structure partagée
 Types utilisables par 1 ou plusieurs autres types (composition) et par 1
ou plusieurs tables (relationnelles ou RO).

 Peut être utilisé pour :


1. définir d’autres types objet qui contient cette structure
2. définir une table relationnelle standard  table non typée
3. définir une table objet (ou table objet relationnelle)  table typée

 Construction
1. Création d'un type,
2. Création d'une table contenant ce TAD.
29
1. Les TAD
1.1 Composition de types Utilisation du type dans un autre type

Exemple d'objet de type voiture_t:


CREATE TYPE voiture_t AS OBJECT ( voiture_t
modele varchar2(15),
modèle année no
annee date,
no integer)
/
-- Remarque : après la création d’un TAD et uniquement dans ce cas, ‘/’ remplace le ‘;’
pour terminer un ordre SQL.
CREATE TYPE personne_t AS OBJECT (noP number, nomP varchar2(15),
prenomP varchar2(15), date_naissance date, voiture voiture_t)/

personne_t
noP nomP prénomP date_naissance voiture_t
modèle année no 30
1. Les TAD
1.1 Composition de types

Instances de TAD
 Une table d’un TAD est une table d’objets.
 Uniquement créable avec la commande :

CREATE TABLE nom_table OF nom_TAD;


 Toute instance d’une telle table possède un oid unique, ce sont des n-
uplets objet.
 La portée de cet oid est globale.

 Attention,
 Les autres tables (non directement construite sur un TAD) ne sont pas
des tables d’objets.
 Les instances des autres tables n’ont pas d’oid sortie de leur table.
● portée de l’oid locale à la table.
31
1. Les TAD
1.1 Composition de types Création d'une table non typée

Exemple d'objet de type voiture_t:


CREATE TYPE voiture_t AS OBJECT ( voiture_t
modèle varchar2(15), modèle année no
année date,
no integer)
/

CREATE TABLE Personnes ( noP number, nomP varchar2(15), prenomP


varchar2(15), date_naissance date, voiture voiture_t )
/ -- Personnes n’est pas une table d’objets (table non typée).

Personnes
noP nomP prénomP date_naissance voiture : voiture_t
modèle année no
32
1. Les TAD
1.1 Composition de types Insertion dans une table non typée

Insertion de données dans une table utilisant un TAD :


INSERT INTO Personnes VALUES (101, ‘Riahi’, ‘Khalil’, ’16-05-1963’, voiture_t(‘2ch’, ‘1975’, 12) );

Personnes
voiture : voiture_t
noP nomP prénomP date_naissance
modèle année no
101 Riahi Khalil 16-05-1963 2ch 1975 12

Valeurs par défaut


Définition des valeurs par défaut pour un TAD dans la table de Personnes :
CREATE TABLE Personnes ( noP number, nomP varchar2(15), prenomP varchar2(15),
date_naissance date, voiture voiture_t DEFAULT voiture_t(‘2ch’, ‘1975’, 12)); - - Object-
Column (OC)

33
1. Les TAD
1.1 Composition de types Insertion dans une table non typée

 Insertion de données dans une table relationnelle utilisant un TAD :


INSERT INTO Personnes VALUES (100, ‘Riahi’, ‘Ali’, ’16-05-1963’, DEFAULT ); -- OC par défaut
INSERT INTO Personnes VALUES (101, ‘Riahi’, ‘Khalil’, ’16-05-1963’, NULL); -- OC vide
INSERT INTO Personnes VALUES (102, ‘Sassi’, ‘Heithem’, ’ 29-02-1944’, voiture_t(NULL, NULL, NULL) ); --OC null

 Un OC vide et null sont notions différentes :


1. VIDE indique l’absence d’objet (non updatable)
2. NULL: est un objet qui peut être mis à jour

 SQL> Select * From Personnes :


noP nomP prenomP date_naissance voiture (modèle, année, no)
100 Riahi Ali 16-05-1963 voiture_t(‘2ch’, ‘1975’, 12)
101 Riahi Khalil 16-05-1963 -- indicateur d’objet-colonne vide aucune maj possible
102 Sassi Heithem 29-02-1944 -- voiture_t (NULL, NULL, NULL) – objet null, maj possible

34
1. Les TAD
1.1 Composition de types Création d'une table d'objets

Exemple d'objet de type voiture_t


CREATE TYPE voiture_t AS OBJECT (
voiture_t
modele varchar2(15),
modèle année no
annee date,
no integer)
/
Création d'une table d'objets ayant 1 type TAD composé d'attributs simples
CREATE TABLE Voitures OF voiture_t;
-- Voitures est une table d’objets (table typée).

Création d’une table d'objets ayant au moins 1 attribut composé de TAD


CREATE TABLE Personnes OF personne_t;
-- Personnes est une table d’objets.

 La table Personnes a une colonne supplémentaire invisible, gérée par le SGBD qui
contient l'oid de chaque objet. 35
1. Les TAD
1.1 Composition de types Insertion dans une table d'objets

TAD voiture_t : voiture_t


modèle année no

L’insertion des données peut se faire comme d’habitude en SQL :


INSERT INTO Voitures VALUES (‘2ch’, ‘1975’, 128);

Table Voitures : (ordre SQL : SELECT * FROM Voitures)


Voitures
voiture_t
modèle année no
2ch 1975 128
Megane 1998 371

36
1. Les TAD
1.1 Composition de types Insertion dans une table d'objets

 A chaque TAD créé est associé un constructeur (même fonctionnement qu’en BDOO)
du même nom que le TAD (obligatoire de donner une valeur à tous les attributs).
⇒ Insertion des données dans une table avec TAD :

INSERT INTO Personnes VALUES (


personne_t( 102, 'Sassi', 'Heithem', '29-02-1944', voiture_t(‘Megane’, ‘1998’, 371) ) );

** le 1er constructeur, personne_t() est facultatif, obligatoire


car il correspond au type de la table.

Personnes
personne_t
Table Personnes :
noP nomP prénomP date_naissance voiture: voiture_t
(select * from Personnes)
modèle année no
101 Riahi Khalil 16-05-1963 2ch 1975 128
102 Sassi Heithem 29-02-1944 Megane 1998 371
37
1. Les TAD

 Si types inter-dépendants, il est impossible de créer un TAD complet et


correct sans que l’autre ne soit déjà crée.
problème

 Exemple :
TAD personne_t utilise voiture_t, et TAD voiture_t utilise personne_t.

 Solution de Oracle 8i : définition de TAD incomplet.

Syntaxe : Create type nom_type


/ -- ni attribut, ni méthode déclarés.
 TAD complété plus tard, mais d’ores et déjà référençable dans d’autres TAD.

38
Différences entre table typée et non typée du OR
 Table typée réfère à un stock non ordonné d'objets (avec chacun un oid). Chaque
objet peut avoir en plus une ou plusieurs colonnes d'objets (objets-colonnes).

 Exemple avec table typée :


CREATE TYPE personne_t AS OBJECT (nom varchar2(15), prenom varchar2(15),
date_naissance date, voiture voiture_t)/
personne_t et voiture_t sont des TAD.

 2 tables possibles:
 Create table Personnes of personne_t; -- (table typée )
 Tuple de la table typée est un objet avec son oid.
 Create table Personnes (matricule int, nom varchar(50), voiture voiture_t);
 (table non typée, non 1FN)
 Tuple de la table non typée a un rowid seulement
 Objet de colonne (OC) : instance de voiture_t dans un tuple de Personnes (sans
OID propre). Il est persistant via l'objet hôte. C'est une caractéristique de l’OR et
non pas de l’OO.
39
Différences entre table typée et non typée du OR
 Evolutivité plus difficile avec table typée : Ajout de âge dans la table typée
Personnes Répercussion possible sur d’autres tables utilisant le type
personnne_t ou sur un autre type défini avec personne_t (sous-type).
CREATE TABLE Personnes OF personne_t;
ALTER TYPE personne_t ADD attribute âge int default 999;
ALTER TYPE personne_t MODIFY attribute âge char(2);

 Seule la table typée peut avoir des méthodes (Member Procedure) :ajout et
suppression d’une méthode;
ALTER TYPE personne_t ADD Member Procedure ajouter(n IN number);
ALTER TYPE personne_t DROP Member Procedure ajouter;

40
Utilisation d’un type partagé entre utilisateurs et DBA

 Ali veut créer un type gerant_t en utilisant dans sa définition le type créé par Hajer:

Create type gerant_t as Object


( noGerant int, personne Hajer.employe_t )
/
Describe Hajer.employe_t;

 Pour créer des types, Ali doit avoir l’autorisation ou le privilège du DBA :

Grant create type to Ali; -- accordé par le DBA


ou
avoir les privilèges du DBA.

41
1. Les TAD
1.2 Les collections

 Exprimer qu’une personne possède plusieurs enfants ou plusieurs


voitures dans une même table.

 2 possibilités de stockage des collections :


1. Collections liées (ordonnées) : Varray
2. Collections libres (non ordonnées) : Nested Table (une table séparée)

Personnes
lesEnfants :{ } voiture
noP nomP prenomP date_naissance
noE prenomE ageE modèle année no
1 Sarra 12 2ch 1975 128
101 Riahi Khalil 16-05-1963
2 Hajer 15 407 2011 280
102 Sassi Heithem 6 Med 16 29-02-1944 Megane 1998 371
42
1. Les TAD
1.2 Les collections - VARRAY

 VARRAY : une collection limitée, ordonnée d’éléments de même type.

 Construction d’un Varray :


1. Création du type de la collection, avec :

create type nom as Varray (nb_max) of type_elt,


 type_elt peut être simple ou TAD
 nb_max : le nombre maximum d’éléments de cette liste.

2. Création du type contenant la collection, personne_t par exemple (ou


création directe de la table).
3. Création de la table de ce dernier type.

 Manipulation :
 dans une requête SQL, on manipule le VARRAY entier
 dans un bloc PL/SQL, on manipule des éléments particuliers du VARRAY
43
1. Les TAD
1.2 Les collections - VARRAY

Exemple : Plusieurs enfants pour une personne.

Création du type de la collection enfant_t :


Create type enfant_t as Object (noE number, prenomE varchar2(50) , ageE number)
/
Create type lesEnfants_t AS VARRAY(5) of enfant_t
/

Create type or replace personne_t as object


(noP number, nomP varchar2(15), prénomP varchar2(15), date_naissance
Date, lesEnfants lesEnfants_t, voiture voiture_t)
/

Create table Personnes of personne_t;


-- personnes est une table d’objets.

44
1. Les TAD
1.2 Les collections - VARRAY
 Là encore on utilise le constructeur pour les listes :

INSERT INTO Personnes VALUES (personne_t(101, ’Riahi', 'Khalil',


lesEnfants_t(enfant_t(1,‘Sarra’, 12), enfant_t(2, ‘Hajer’, 15)), ’16-05-1963’,
voiture_t (‘2ch’, ‘1975’, 128) ) ) );

Table personnes (ordre SQL : Select * from personnes)

Personnes
lesEnfants :{ } voiture
noP nomP prenomP date_naissance
noE prenomE ageE modèle année no
1 Sarra 12
101 Riahi Khalil 16-05-1963 2ch 1975 128
2 Hajer 15
102 Sassi Heithem 6 Med 16 29-02-1944 Megane 1998 371

 La lecture est possible avec SQL mais pas la mise à jour et la suppression.
45
1. Les TAD
1.2 Les collections - VARRAY
 La lecture est possible avec SQL mais pas la mise à jour et la suppression.
Select P.lesEnfants From Personnes P ;
LESENFANTS(NOE, NOME, AGEE)
LESENFANTS_T(ENFANT_T(1, 'Sarra', 12))
LESENFANTS_T(ENFANT_T(2, 'Hajer', 15))
LESENFANTS_T(ENFANT_T(6, ‘Med', 16))

-- Applicatif PL/SQL pour afficher le no des enfants assurés par la personne 101
Declare
v_tableauE lesEnfants_t ;
Begin
Select P.lesEnfants into v_tableauE
From Personnes P Where P.noP = 101;
For i IN 1..v_tableauE.COUNT Loop
IF v_tableauE.EXISTS(i) Then
DBMS_OUTPUT.PUT_LINE (v_tableauE(i).noE);
End IF;
End Loop; 1
End; 2
/ Procédure PL/SQL terminée avec succès .46
1. Les TAD
1.2 Les collections - VARRAY

-- Applicatif PL/SQL pour la Recherche d’un objet particulier du varray

Declare
v_tableauE lesEnfants_t ;
Begin
Select P.lesEnfants into v_tableauE From Personnes P Where P.noP =102;
DBMS_OUTPUT.PUT_LINE (v_tableauE(1).noE ||' ' ||
v_tableauE(1).nomE) ;
End;
/
Réponse:
6 Med
Procédure PL/SQL terminée avec succès.

47
1. Les TAD
1.2 Les collections - VARRAY
-- Modification de l’attribut d’un objet-colonne (ageE)
Exemple: Sarra titulaire du numéro 1 (fille de Khalil), a 26 ans plutôt que 12.
Pour modifier un objet ayant un attribut de type varray, il faut lire l’objet , le
mettre à jour dans l’applicatif PL/SQL et l’insérer à nouveau dans la base-objet.
Declare
v_tableauAssur assurance_t; -- type des objets de la table
v_lesEnfants lesEnfants_t; -- type varray
Begin
Select P.lesEnfants into v_lesEnfants From Personnes P
Where P.noE = 101;
v_lesEnfants(1).ageE := 26; -- mise à jour de l’objet-colonne
Update Personnes a SET a.lesEnfants = v_lesEnfants Where a.noP = 101;
End;
/
sqlplus: select lesEnfants from Personnes;
LESENFANTS(NOE, NOME, AGEE)
LESENFANTS_T(ENFANT_T(1, 'Sarra', 26), ENFANT_T(2, 'Hajer', 15),)
LESENFANTS_T(ENFANT_T(6, 'Med', 16))
48
1. Les TAD
1.2 Les collections - Nested Table

 Une personne peut avoir plusieurs voitures.

Personnes
lesEnfants :{ } Voitures :{}
noP nomP prenomP date_naissance
noE prenomE ageE modèle année no
1 Sarra 12 2ch 1975 128
101 Riahi Khalil 16-05-1963
2 Hajer 15 407 2011 280
102 Sassi Heithem 6 Med 16 29-02-1944 Megane 1998 371

49
1. Les TAD
1.2 Les collections - Nested Table

Construction d’un Nested Table :


1. Création du type de la collection, avec :
Create type nom as Table of type_elt,

2. Création du type contenant la collection puis 3, par exemple Personnes


(ou création directe de la table).

3. Création de la table de ce dernier type (s’il y a lieu).


⇒ Génération automatique d’un identifiant superficiel Nested_Table_Id pour
chaque collection
⇒ Possibilité de créer un index sur le Nested Table

Attention : Un Nested Table n’est pas une table objet


⇒ Pas d’oid associé à un élément de collection
50
1. Les TAD
1.2 Les collections - Nested Table

Create type voiture_t as object (modele varchar2(15), annee date, no integer)


/
Create type ens_voiture_t as Table of voiture_t
/
Create table Personnes (noP number, nomP varchar2(15), prenomP varchar2(15),
lesEnfants lesEnfants_t,
date_naissance date,
voitures ens_voiture_t); -- pas table d’objets
Nested table voitures Store As ToutesVoitures

Définition de la colonne (attribut d’ensemble) de Nom de la table physique utilisée pour


Stockage qui forme la table imbriquée. implémenter la table imbriquée, ToutesVoitures
Cette table ToutesVoitures n'est accessible que
sqlplus: describe ToutesVoitures le Select.
ens_voiture_t TABLE OF voiture_t
Nom NULL ? Type
----------------------------------------- -------- ----------------------
MODELE VARCHAR2(15)
ANNEE DATE
NO INTEGER 51
1. Les TAD
1.2 Les collections - Nested Table

Une collection dans un Nested Table peut être


 Insérée,
 Supprimée,
 Mise à jour : les éléments dans le nested table peuvent être insérés,
supprimés ou maj

– INSERT INTO Personnes VALUES (‘Riahi’, … , ’16-03-75’, ens_voiture_t


(voiture_t(‘2ch’, 1975, 128), voiture_t(‘Mégane’, 1998, 179)));

– INSERT INTO Table (select p.voitures from Personnes p where p.nom= ‘Riahi’)
VALUES (‘206’, ‘2000’, 3);

Insertion d'un objet sans valeur dans la table imbriquée (vide au début)

– INSERT INTO Personnes VALUES(1, ‘Guesmi', 'Ramzi',


lesEnfants_t(enfant_t(1,‘Sarra’, 12), enfant_t(2, ‘Hajer’, 15)), ’16-03-75’,
ens_voiture_t ()); 52
1. Les TAD
1.2 Les collections - Le mot clé THE / TABLE

 Pour parcourir des collections libres ou liées : voir une collection comme une table.
 THE (SQL3) ou TABLE (Oracle) est une fonction qui retourne un seul
objet (colonne). C'est l'opération Unnesting !

 THE désigne une table imbriquée et apparaît dans une clause FROM.
 THE est suivi :
 d'une requête ne renvoyant qu'un seul objet,
 d'un alias (pas de manipulation directe avec THE)
Select v.No
from THE (select p.voitures
from personnes p
where p.nomP='Riahi') v
La sous requête (THE) fournit la table d'objets (références) de la sous-table associée à
personnes 'Riahi' 53
1. Les TAD
1.2 Les collections - Nested Table

Manipuler ses éléments

 Supprimer une collection libre :


UPDATE Personnes SET voitures = NULL where nom= ‘Riahi’

 Re-créer : avec le constructeur (sinon, aucune opération possible)


 Créer un ensemble vide :
UPDATE Personnes SET voitures = ens_voiture_t() where nom= ‘Riahi’
Créer un singleton :
UPDATE Personnes
SET voitures = ens_voiture_t(voiture_t(‘Mégane’, 1998, 179))
where nom= ‘Riahi’

 Attention : une opération sur 1 élément d’1 collection dans une


Nested Table pose un verrou sur son propriétaire
=> 1 opération à la fois dans une collection !!!!!!
54
1. Les TAD
1.2 Les collections - Nested Table
Exemple de parcours de listes
 Numéro des voitures des personnes :
Select v.no
from Personnes p, Table (p.voitures) v;

 Numéro des voitures de Riahi:


Select v.no
from Personnes p, Table (p.voitures) v
where p.nom = ‘Riahi’;

Personnes
lesEnfants :{ } voiture
noP nomP prenomP date_naissance
noE prenomE ageE modèle année no
1 Sarra 12 2ch 1975 128
101 Riahi Khalil 16-05-1963
2 Hajer 15 407 2011 280
102 Sassi Heithem 6 Med 16 29-02-1944 Megane 1998 371
55
1. Les TAD
1.2 Les collections

Opérations sur les Collections En PL/SQL


 (i) ième élément (peut être vide)
 .FIRST(), .LAST()
 Indice du premier ou dernier élément (non vide).
 NULL si la collection est vide
 .NEXT(i), .PRIOR(i) :
 élément non vide suivant (précédent) l’élément i
 .EXTEND, .EXTEND(n), .EXTEND(n,i)
 étend de 1 ou n éléments, avec des copies de l’élément i
 .DELETE : Supprime tous les éléments
 .DELETE(i), .DELETE(i,j) :
 Supprime l’élément i / Supprime les éléments i à j
 .TRIM : supprime l’élément à l’indice LAST()
 .TRIM(n) : supprime les n derniers éléments 56
1. Les TAD
1.2 Les collections Imbrication de collections

 Impossible dans l'absolu, mais des tableaux fixes (Varray) peuvent être
imbriqués grâce aux références.

Create type panne_t as object ( typep varchar2(20), datep date, detail varchar2(200)); /
Create type pannes_t as Varray(10) OF REF panne_t; /
Create type voiture_t as object (modele varchar2(15), annee date, no integer,
sespannes pannes_t); /
Create type voitures_t as Varray(10) OF REF voiture_t;/
REMPLACE "Create type liste_voiture_t as Varray(10) of voiture_t"

Create table Pannes OF pannes_t;


Create table Voitures OF voitures_t;
Create table Personnes (noP number, nomP varchar2(15), prenomP
varchar2(15), lesEnfants lesEnfants_t, date_naissance Date, voitures voitures_t);

57
1. Les TAD Varray vs. Nested Table
1.2 Les collections

 Ces deux types sont du genre ensemble et peuvent avoir comme


éléments des refs, des valeurs ou des objet-colonnes.

VARRAY NESTED TABLE


Ensemble trié Ensemble non trié
indexation des éléments (0rig. 1) Éléments non indexés
Nombre limité d’éléments Nombre illimité d’éléments
Pas de SELECT sur les objets-colonnes SELECT possible sur les objets colonnes
Accessible avec PL/SQL (non accessible avec SQL) Accessible avec SQL et PL/SQL
Éléments de même type ou un soustype du type déclaré Éléments du même type

 L’insertion, mise à jour, suppression et autres opérations avec ces types complexes
exigent l'emploi de méthodes qui seront étudiées ultérieurieurement.

58
1. Les TAD
Les contraintes définies au niveau des tables

 Une contrainte est toujours définie au niveau de la table et non au


niveau du type qui est partageable avec d'autres tables qui n'ont pas
nécessairement les mêmes contraintes.

 Contraintes de table : clé primaire, clé étrangère, unicité, check, …


Create table Personnes of personne_t (
constraint pkPers Primary key(CIN));

 La définition suivante est INTERDITE :

Create type personne_t as object (noP number(8), nomP varchar2(15), …,


constraint pkPers Primary key(noP));

59
1. Les TAD
1.3 Les références - Type REF

 On peut indiquer dans la définition d’un type qu’un attribut contient des
références (et non des valeurs) à des données d’un autre type ; la syntaxe
est « REF nom-du-type » :

Create or replace type personne_t as object


(noP number, nomP varchar2(15), prénomP varchar2(15),
lesEnfants lesEnfants_t,
-- Rq : impossible de référencer une collection !
-- lesEnfants REF les Enfants_t est illégal.
date_naissance Date,
voiture REF voiture_t)

60
1. Les TAD
1.3 Les références - Type REF

 Un attribut peut avoir un type REF ce qui signifie qu’il est valué avec
une référence (qui pointe) à un autre objet et qui inclut l'oid de l'objet
ciblé d'une table typée.
 C'est une référence vers un objet, construit avec l'oid (+ le rowid)
 Le oid (son identité) est de préférence (ou devrait) être non visible (variable
selon les implémentations);

 Le REF permet de :
 implanter le lien externe du Mnav (une représentation graphique du MOR)
 améliorer la fonction de navigation avec le langage SQL (Par exemple,
accélérer les jointures).

 N.B: dans la technologie relationnelle le ROWID joue un rôle similaire au OID


dans Oracle-Objet mais il n’est pas un vrai oid ne serait-ce par le fait qu’il est
visible et manipulable directement (mais non modifiable directement).

61
1. Les TAD
1.3 Les références - Type REF

 Une valeur de type REF réfère seulement à un objet de table; elle inclut
l'oid de l'objet ciblé, lequel est stocké dans une table-objet. L’objet colonne
n’a pas de oid.
 Dans ce cours et par convention volontairement abusive :
Valeur Ref sera considérée idem à l'oid

 La fonction REF(x), ou x est un objet, rend l'oid de l'objet x.

 Objet de travail: Il est toujours possible de créer un objet sans oid (Oracle).
C'est le cas de l'objet créé par le NEW() de PL/SQL qui génère un objet de
travail non persistant puisque pas encore chargé dans une table.

62
1. Les TAD
1.3 Les références – Fonction DEREF()
 La fonction REF(x), ou x est un objet, rend l'oid de l'objet x.
 De façon similaire, la fonction DEREF(a), où a est un oid, rend l'objet correspondant et l'assigne à une
variable du type.

Exemple PL/SQL:
Declare
vref REF client_t;
v_client client_t;
Begin
Select REF(x)
Into vref
From Client x
Where x.matC = 10000;

Select DEREF(vref)
Into v_client
From Dual;

DBMS_OUTPUT.PUT_LINE(v_client.nomC);
End;
/

63
1. Les TAD
1.3 Les références

 Référencer une voiture dans une table sans l’expliciter à chaque fois.
 Attention, impossible de référencer une collection !

 Possibilité de référencer des données via des pointeurs.


 Créer le TAD t dont on veut référencer les instances,
 Créer la table contenant ces instances de t,
 Puis :
 Créer le TAD qui référence t (mot-clé REF),
 Créer la table associée.
ou
 Créer directement la table.

64
1. Les TAD
1.3 Les références - Exemple
Référencer la voiture d’une personne :
Create type voiture_t as object (modele varchar2(15), annee date, No number)
/
Personnes : personne_t
Voitures : voiture_t
noP number
nomP : varchar(20) modele : varchar2(15)
prenomP : varchar(20) annee : Date
lesEnfants: {lesEnfants_t} No : number
date_naissance : Date
voiture
Create table Voitures of voiture_t;
Create or replace type personne_t as object
(noP number, nomP varchar2(15), prénomP varchar2(15),
lesEnfants lesEnfants_t,
-- Rq : impossible de référencer une collection !
-- lesEnfants REF les Enfants_t est illégal.
date_naissance Date,
voiture REF voiture_t)
/
Create table Personnes of personne_t;
65
1. Les TAD
1.3 Les références – Exemple (suite)

Personnes : personne_t
Voitures : voiture_t
noP number
nomP : varchar(20) modele : varchar2(15)
prenomP : varchar(20) annee : Date
lesEnfants: {lesEnfants_t} No : number
date_naissance : Date
voiture
Select p.nom, p.date_naissance
From Personnes p
Where p.voiture.modele = ‘Golf-6';

voiture est un attribut de Personnes de type REF référant à une autre table
typée Voitures.

NB: Personnes et Voitures sont des tables typées personne_t et voiture_t.


66
1. Les TAD
1.3 Les références – Insertion avec références

 Pour insérer un n-uplet dans la table personnes, il faut référencer la


voiture de cette personne dans la table Voitures.

⇒ Récupérer l’adresse de cette voiture pour la placer dans la table


Personnes.

⇒ Utilisation de l’opérateur REF qui renvoie l’adresse d’un n-uplet dans


une table (REF : n- uplet -> pointeur).

⇒ INSERT INTO Personnes VALUES (


personne_t(101, ’Riahi', 'Khalil',
lesEnfants_t(enfant_t(1,‘Sarra’, 12), enfant_t(2, ‘Hajer’, 15)), ’16-05-1963’,
(select REF(v) from voitures v where v.modele = ‘2ch’)) ) );

67
1. Les TAD
1.3 Les références – Insertion avec références
personne_t
lesEnfants
noP nomP prénomP date_naissance @voiture
{lesEnfants_t}

voiture_t
Voitures
modèle année no
voiture_t
modèle année no
2ch 1975 128
Megane 1998 371

Personnes
lesEnfants :{ }
noP nomP prenomP date_naissance @voiture
noE prenomE ageE
1 Sarra 12
101 Riahi Khalil 16-05-1963
2 Hajer 15
102 Sassi Heithem 6 Med 16 29-02-1944 68
1. Les TAD
1.3 Les références – Requêtes avec références

Résultat de la requête : select * from personnes

Personnes
lesEnfants :{ }
noP nomP prenomP date_naissance @voiture
noE prenomE ageE
1 Sarra 12 03F43970135A39847C…
101 Riahi Khalil 16-05-1963 -- adresse du pointeur.
2 Hajer 15
Ne veut rien dire!
102 Sassi Heithem 6 Med 16 29-02-1944 03F43970135A39848E…

Pour obtenir la valeur référencée :


⇒ Utilisation de l’opérateur DEREF (pointeur -> valeur)
Select DEREF(p.voiture), p.nom from Personnes p
where p.voiture.année < 1990; 69
1. Les TAD
1.3 Les références – Création directe d'une table avec références

Référencer la voiture d’une personne :

Create type voiture_t as object (modele varchar2(15), annee date, No number)


/

Create table voitures of voiture_t;


-- voitures est une table d’objets.
Create table Personnes (
noP number, nomP varchar2(15), prénomP varchar2(15),
lesEnfants lesEnfants_t,
-- Rq : impossible de référencer une collection !
-- lesEnfants REF les Enfants_t est illégal.
date_naissance Date,
voiture REF voiture_t)
/
-- personnes n’est pas directement construite avec un TAD, donc n’est pas
une table d’objets.
70
1. Les TAD
1.3 Les références – Mise à jour avec références

 Changer de voiture :
UPDATE Personnes p SET p.voiture =
(SELECT REF(v) FROM Voitures v WHERE v.modele = ‘Mégane’)
WHERE p.noP = 101;

 Attention : modifier une voiture à travers une personne est impossible !

71
1. Les TAD
1.3 Les références – Références du Vide

 Pour tester l’existence d’une instance référencée : utilisation du prédicat IS


DANGLING.

 DANGLING : référence qui ne pointe pas sur un objet valide.

 Exemple :
Update Personnes set voiture = NULL
Where voiture IS DANGLING

SELECT count(*) FROM Personnes WHERE voiture IS DANGLING

 Une référence perdue est une référence DANGLING (danger d’incohérence)


72
1. Les TAD
1.3 Les références – Références croisées

Comme d'habitude, on commence par créer un type vide pour être


référencé dans un second type et on modifie le premier type ensuite. On
crée les tables en dernier.
Create type voiture_t /

Create type personne_t as object (noP number, nomP varchar2(15),


prénomP varchar2(15), lesEnfants lesEnfants_t, date_naissance
Date, voiture REF voiture_t)

Create or Replace type voiture_t as object


(modele varchar2(15), annee date, No number, personne REF personne_t) /

Create table Voitures of voiture_t;


Create table Personnes of personne_t;

73
1. Les TAD
1.3 Les références – Limitation de portée d'une référence

 Il est intéressant de pouvoir limiter les références à une table particulière


(table construite à partir de ce type).
 La commade SCOPE IS/FOR permet cette limitation dans la déclaration
d'une table.

Create type voiture_t as object (modele varchar2(15), annee date, No number)/


Create table Voitures of voiture_t;
Create table VoituresDeLuxe of voiture_t;

Create table Personnes ( noP number, nomP varchar2(15), prénomP varchar2(15),


lesEnfants lesEnfants_t,
date_naissance Date,
voiture REF voiture_t,
voiture SCOPE IS Voitures);

 On ne peut pas avoir pour le même attribut refCap un 2ème SCOPE IS


dans la même table référant à une autre table.
74
1. Les TAD
1.3 Les références – Avantage du REF dans une recherche

CREATE type etudiant_t (no NUMBER, bac REF bac_t, adr adr_t)
CREATE type bac_t (nomB CHAR(20), anCreationB DATE,
moyResultats99 NUMBER)

CREATE TABLE Bacc OF bac_t;


CREATE TABLE Etudiant OF etudiant_t;

75
1. Les TAD
1.3 Les références – Avantage du REF dans une recherche

76
1. Les TAD
1.3 Les références – Le type REF et le swizzling

 La référence pointe sur (identifie) un objet abstraction de son placement


physique sur disque. (location independancy).
 Le REF ne peut donc pas pointer sur un
objet dans la RAM comme un véritable
pointeur physique sait le faire.

 L'OID est muté en pointeur physique dans la RAM (dès la 1ère lecture
de l’objet): c'est la transformation ou mutation des Refs (le swizzling).

1. L’objet oid8 est transféré de la BDOO et inséré dans la cache


RAM. Son adresse RAM est inscrite dans la table des objets
persistants: OP
2. Par la suite, la table OP est consultée pour trouver l’adresse
de oid8 en RAM. L’écriture se fait via la page vers le disque.

 le swizzling accélère l'accès aux objets. Cette transformation est gérée par le SGBD. 77
Comparaison entre la référence et le oid

 Une référence n'est pas nécessairement identique à l'oid. Une référence


permet de cibler un objet. Cela dépend des spécifications lors de sa création.
 Un oid est un identifiant logique unique jamais réutilisé qui caractérise un objet
persistant d’une table-objet. Il est transformé en RAM en oid-physique (adresse RAM)
 En OR-Oracle, une référence REF peut être composée des trois parties
suivantes  REF := oid + metadonnée + [rowid]
 l'oid du type de la table objet : 16 octets (la structure de la table correspond à un objet)
 l'oid de l'objet référencé : 16 octets pour les oid générés par le système et variable
pour les oid dérivés de la clé primaire
 rowid de l'objet, soit 10 octets.
 Au total 42 octets = 316 bits pour chaque référence!

78
1. Les TAD
1.3 Implémentation de la contrainte référentielle en OR

 La cohérence d'une BDR est assurée par l'intégrité référentielle.

 En OR, cette même cohérence est prise en charge au moyen de la


contrainte REFERENCES.

 Deux cohérences à assurer :


 Insertion dans la table enfant : cohérence des objets de la table enfant :
ce dernier ne peut pas référer à un objet du parent absent.

 Suppression dans la table parent : cohérence des objets de la table


parent : un objet parent ne peut pas être supprimé si une REF de la
table enfant y réfère.
79
Contrainte référentielle en OR (Exemple)

 Cohérence du parent : suppression dans Atelier


 Cohérence de l'enfant : insertion dans Ouvrier

80
Contrainte référentielle en OR

 L’attribut de type REF est utilisé pour implémenter l’association de la


classe UML.

 Clés étrangère et clé primaire d’une table:


 La clé primaire en objet est non essentielle car l’oid distingue tout
objet. Elle est cependant utile pour la recherche d’un objet particulier.
 La clé est une contrainte d’entité (toutes les valeurs sont distinctes)
 La clé étrangère est implémentée en objet autrement que par le
partage d’une valeur primaire.

81
Contrainte référentielle en OR (Exemple avec table typée)

CREATE type atelier_t as Object(nomA varchar2(50), AdreA varchar2(50))


/

CREATE type ouvrier_t as Object(matO varchar2(6), nomO varchar2(50),


villeO varchar2(50), refA REF atelier_t)
/

CREATE TABLE Atelier of atelier_t


(constraint pk_Atelier Primary Key (nomA));

CREATE TABLE Ouvrier of ouvrier_t


(constraint pk_Ouvrier Primary Key (matO),
constraint c1_refAtelier CHECK (refA is not null));

82
Suite … Intégrité référentielle avec les oid et table typée

DELETE from Atelier where nomA ='AtelierTunis'; -- cet objet existe est supprimé!

Cette suppression du parent peut engendrer une incohérence de l'enfant. Il peut y


avoir un ouvrier qui pointe vers un atelier (parent). Donc un atelier est supprimé
même s'il y a des ouvriers qui y travaillent ! Anomalie potentielle. Avec l'intégrité
référentielle déclarée en relationnel cette suppression serait interdite.

Correction de cette faiblesse avec la clause REFERENCES :


CREATE TABLE Ouvrier of ouvrier_t
(constraint pk_Ouvrier Primary Key (matO),
constraint c1_refAtelier CHECK (refA is not null),
constraint c2_refAtelier refA REFERENCES Atelier);

 La suppression de l'atelier est bloquée par la contrainte c2_ref_Atelier


assurant la cohérence du fils.
 Par contre, la suppression n'est pas bloquée avec le SCOPE
83
Suite … Intégrité référentielle avec les oid et table typée

Insertion d'un fils (cohérence de l'enfant)

INSERT INTO Ouvrier values ('123', 'Tunisie', 'Tunis', (SELECT REF(a)


FROM Atelier a
where a.nomA ='AtelierTunis')
);
*** Erreur **** l'atelier (parent) recherché n'existent pas.

 Cohérence de l'enfant est vérifiée : le SELECT ne trouvant pas


d'objets retourne un null dont l'insertion est interdite par la
contrainte c1_refAtelier de Ouvrier qui interdit la référence null.

84
Cohérence référentielle du parent avec une table typée

Cohérence du parent 'Atelier'

DELETE FROM Atelier WHERE nomA='Mecano';


** Erreur à la ligne 1
ORA-02292> Referential Constraint Violation …

En supprimant cet atelier la contrainte de tuple ci-dessous est non validée :


Constraint c2_refAtelier refA References Atelier

*** Erreur violation de la contrainte c2_refAtelier

 A tout moment l'attribut refA doit se référer à un oid valide de la


table Atelier, soit un oid d'objet présent dans la base.

85
Suite … Intégrité référentielle avec une table non typée

Table OR pour voir les oid

CREATE TABLE Atelier of atelier_t


(constraint pk_Atelier Primary Key (nomA));

CREATE TABLE Ouvrier (matO varchar2(6), nomO varchar2(50),


villeO varchar2(50), refA REF atelier_t,
constraint c_refA refA SCOPE IS Atelier, -- ref limitée à la table Atelier
constraint pk_Ouvrier Primary Key (matO),
constraint c1_refA CHECK (refA is not null)); 86
Cohérence de la table enfant avec une table non typée

 Insertion d'un ouvrier qui référence un atelier non encore crée


INSERT INTO Ouvrier values ('12356', 'Ramzi Guesmi', 'Tunis',
(SELECT Ref(a) FROM Atelier WHERE noA=''TecMec));
** Erreur à la ligne 1
L'atelier TecMec n'existe pas encore, le Select imbriqué retourne un NULL pour
l'attribut refA ce qui viole la contrainte c1_refA.
 Insertion correcte d'un atelier parent
INSERT INTO Atelier values ('TecMec', '25 Rue de Tunis');
1 row (object) inserted
 Toutes les contraintes sont alors vérifiées
 Insertion en se référant à une table de même schema (AtelierART)
INSERT INTO Ouvrier values ('12356', 'Ramzi Guesmi', 'Tunis',
(SELECT Ref(a) FROM AtelierART WHERE noA=''TecMec));
 Insertion limitée par le SCOPE IS Atelier.
87
Actions référentielles en OR

La contrainte référentielle avec la technologie relationnelle a les actions


référentielles ON DELETE CASCADE et ON DELETE SET NULL.

En objet les mêmes actions sont possibles :


 (parent) CREATE TABLE Atelier of atelier_t
(constraint pk_Atelier Primary Key (nomA));

 (enfant) CREATE TABLE Ouvrier of ouvrier_t


(constraint pk_ouvrier Primary Key (matO),
constraint c1_refAtelier CHECK (refA is not null),
constraint c2_refAtelier refA REFERENCES Atelier
ON DELETE CASCADE );
Toute suppression d'un atelier supprime les ouvriers qui y travaillent.
88
Action ON DELETE SET NULL

 (enfant) CREATE TABLE Ouvrier of ouvrier_t


(constraint pk_ouvrier Primary Key (matO),
constraint c1_refAtelier CHECK (refA is not null),
constraint c2_refAtelier refA REFERENCES Atelier
ON DELETE SET NULL );

 Toute suppression d'un atelier met à null la ref des ouvriers qui y travaillent.
 Cette action référentielle exige la suppression de la contrainte c1 qui est
contradictoire avec la sémantique de l’action SET NULL.

89
LMD et TAD

 Comme d’habitude en SQL,


 Insert, Update, Delete, Select.
 Avec en plus les fonctions :
 VALUE,
 REF,
 DEREF
 Le constructeur associé à chaque TAD,
 Le prédicat IS DANGLING,
 La clause RETURNING pour ESQL et PL/SQL, ajout à la fin d’un
insert ou update de la clause :
Returning ref(alias_table) into nom_var
 L’opérateur TABLE.

90
Création des objets: NULL et VIDE dans PL/SQL
CREATE TYPE voiture_t AS OBJECT (modele varchar2(15), annee date, no integer)
/
CREATE TYPE personne_t AS OBJECT (noP number, nomP varchar2(15), prenomP
varchar2(15), date_naissance date, voiture voiture_t)/

Declare -- dans un bloc anonyme PL/SQL


v personne_t ;
n personne_t ;
o personne_t ;
Begin -- le constructeur personne_t () exige une valeur pour tous ses paramètres.
v:= NEW personne_t (101, ‘Riahi’, ‘Khalil’, ’16-05-1963’, NULL); -- OC vide
n:= NEW personne_t (102, ‘Sassi’, ‘Heithem’, ’ 29-02-1944’, voiture_t(NULL, NULL, NULL)); -- OC null
o:= NEW personne_t (103, 'Ahmed', 'Ali', '29-02-1944', voiture_t(‘Megane’, ‘1998’, 371) )); --Objet initialisé
Insert into Personnes values(o); -- objet o rendu persistant et assigantion d’un oid
End;
 L'objet v est vide et non modifiable puisqu’il n’y a pas d’objet. L'objet n est
null et modifiable. L'objet o est initialisé par le constructeur.
91
Mise à jour de l‘OC NULL d'une table typée

Update Personnes p SET p.voiture = voiture_t(‘2ch’, null, null) Where p.noP = 104;

 SQL> Select * From Personnes ;


noP nomP prenomP date_naissance voiture (modèle, année, no)

102 Sassi Heithem 29-02-1944 -- voiture_t (‘2ch’, NULL, NULL) -- OC est mis à jour

101 Riahi Khalil 16-05-1963 -- objet vide---

Mise à jour de l'objet OT 101 avec création de l’objet colonne OC (noP = 101)
Update Personnes p SET p.voiture = voiture_t(‘2ch’, null, null) Where p.noP = 101;
Mise à jour impossible ***
noP nomP prenomP date_naissance voiture (modèle, année, no)
102 Sassi Heithem 29-02-1944 -- voiture_t (NULL, NULL, NULL)

101 Riahi Khalil 16-05-1963 -- objet vide---


92
Persistance des OC et indexation des OT en OR (Oracle)

 Un OC est persistant si son objet-hôte est un objet de table (OT)


 L’insertion de l'objet hôte dans une table rend l‘OC (qui n'a pas de oid)
persistant. Indexation possible des objets-colonnes.
 Ces objets-colonnes peuvent avoir leurs propres méthodes.
 Le partage, comme la création d'une autre table objet sur la base du type de
Méthode de l'OC

l'OC est possible et ses méthodes deviennent celles de la nouvelle table objet.
 Les méthodes propres au type voiture_t ne s'appliquent pas à un objet vide, v !
 Les méthodes de voiture_t peuvent s'appliquer aux objets nuls et les objets
initialisés à la création.

 OT (ligne/tuple) : indexation possible des objets via leur oid


 Correspond à un tuple ou à une ligne dans une table objet et chacun a un oid.
 Ces objets peuvent être indexés et partitionnés.
 Création avec le INSERT et les constructeurs de type approprié.
93
Suppression d'objets / types OR-Oracle

 Via la suppression d'une table : DROP table Employe;


 Entraîne la suppression des objets, des privilèges et des index éventuels
définis sur cette table Employe.
 Rend aussi inopérant les composants dépendants : déclencheurs
(triggers), vues.

 TRUNCATE TABLE Employe ;


 Ne supprime que les objets et non les index,…. Les composants
demeurent en place et éventuellement seront de nouveau opérationnels.

94
Dictionnaire des objets

 Le dictionnaire est fait de tables pour décrire notamment les types.


Celles-ci sont accessibles via les vues statiques suivantes :

 USER_COLL_TYPES : pour décrire les collections


 USER_INDEXTYPES : pour décrire les index
 USER_TYPES : pour décrire les types
 USER_TYPE_ATTRS : pour décrire les attributs des types
 USER_TYPE_METHODS : pour décrire les méthodes des types
 USER_TYPE_VERSIONS : pour décrire les versions des types
 USER_SOURCE : pour décrire notamment le texte des types;

 DESC USER_TYPES -- directive SQLPlus


 Pour obtenir le schéma (avec les types) de cette table.
95
LDD et TAD

 Modification d’attribut ….
 Ajout : Alter type personne_t ADD attribute sexe varchar2(10) Cascade;
* Cascade pour répercuter ce changement pour tous les types qui utilisent le type personne_t;
Seules la table typée peut avoir des méthodes (member procedures) : modifications possibles
(insertions, suppressions, modifications)

 Suppression : ALTER TYPE personne_t DROP ATTRIBUTE (adresse) CASCADE;


* CASCADE: Le système doit vérifier que cette suppression ne se répercute pas sur un
autre type qui l’utilise comme attribut indexé ou utilisé par ex. pour le partitionnement ou
le clustering des tables, …
*** Si le test passe alors le type est modifié, sinon refus du système.
* INVALIDATE (pas de vérification à faire) : le test est supprimé et les changements sont
imposés quitte à ce que le clustering par exemple soit rendu inopérant. Pour le redevenir, il
faudra réinstaller le type initialement supprimé!
96
LDD et TAD
Alter Type …et son Impact sur les données de la base

 Suppression d’un type et les répercussions sur les données

Alter Type .... CASCADE options

Options:
INCLUDING TABLE DATA : entraîne la conversion des données selon le type modifié
NOT INCLUDING TABLE DATA : le dictionnaire est modifié mais pas les données.

Ex: si un attribut est supprimé par un DROP, la colonne reste dans la base
(containeur) mais est marquée comme supprimée.

Alter Table Personne DROP UNUSED COLUMNS;


Pour supprimer toutes les colonnes marquées au préalable comme étant supprimées

97
LDD et TAD

Suppression de TAD : DROP type personne_t [FORCE|VALIDATE]

 FORCE : force la suppression du type même si des objets l'utilisent; les objets
demeurent dans la BD mais deviennent inaccessibles;
 VALIDATE : si ce type est un super_type alors il y a substitution de type.

 Rien n’est changé pour la modification et la suppression des tables (y


compris les tables d’objets).

 Suppression et ajout des signatures et/ou des méthodes dans le type


(voir section 'Les méthodes')

98
Les méthodes

99
Accès à l'objet : encapsulation
 La création, la suppression et la modification d'un objet doivent se faire
par le biais d'une méthode associée à l'objet via son type (classe).

Objet

 L'encapsulation se traduit par la présence d'une interface composée de


méthodes (procédures ou de fonction) dans la déclaration du type et cela
pour accéder aux objets des tables typées.

 L'accès aux objets avec le LMD est toujours possible, mais normalement
remplacé par les méthodes (donc accès direct interdit). Les méthodes font
appel aux ordres LMD sans restriction. 100
L'encapsulation

 Dans Oracle, le droit d'accès est accordé à un utilisateur au regard d'un type et
l'utilisateur voit tous les attributs et méthodes du type sur lequel il a les droits.

 Une méthode peut/doit débuter une transaction et ensuite la terminer avec


le Commit (comme toute transaction autonome i.e. non liée à une autre
transaction ou procédure).

 Les méthodes sont associées aux données tandis que les fonctions et les
procédures SQL stockées sont rangées en dehors de toute association aux
types puisqu'elles sont stockées dans le dictionnaire et sont appelées pour
traiter les données peu importe leur origine.
 Une méthode Oracle peut être une procédure ou une fonction PL/SQL (ou C, C++, Java,..)

101
1.4 Les méthodes
 En principe, un objet de table–objet devrait se comporter comme un
véritable objet de classe et être accessible que par son interface.
1. Une signature est la liste typée de ses paramètres incluant celui de retour.
2. L’interface de classe est l'ensemble de ses signatures

 Un objet-colonne est aussi un objet mais sans oid, Cet objet peut avoir sa propre interface. 102
1.4 Les méthodes

 Déclaration des méthodes (signature) insérée après les attributs dans la


déclaration des TAD.
Create type [or replace] nom_type as object
(att1 type1, …, atti typei,
MEMBER signature_methode1, …,
STATIC signature_methodej),
 MEMBER : méthode invoquée sur les instances du TAD,
 STATIC : méthode invoquée sur le TAD,
 signature : Nom et liste de paramètres avec leur mode (IN, OUT ou IN/OUT)
et s'il y lieu le type de la valeur retournée (sans la longueur du type).
 signature_methode1 : nom_méthode (var1 type_var1, …).

Avec
 type1 ou type_var1 défini par l’utilisateur ou prédéfini
 Nom_méthode différent de celui du TAD et de ses attributs.
103
1.4 Les méthodes (Corps )

 Le code des méthodes (body) est définie séparément dans le corps du TAD.
 Syntaxe : Create or replace type body nom_type as …
 Si uniquement des attributs dans un TAD, corps inutile.
 Possibilité d’utiliser le paramètre SELF dans le corps des méthodes (idem qu’en OO)

 Visibilité des attributs via l’interface Oracle


 L'union de tous les paramètres de l’interface définit
les attributs visibles par les développeurs (s'il y a une
méthode Member , alors le paramètre SELF rend alors tous
les attributs visibles pour qui a un droit sur le type).
 Dans cet exemple tous les attributs de Personne sont
visibles aux applications via les méthodes de sa
classe. 104
1.4 Les méthodes
UML: attribut calculé et caché: accessibilité indirecte

 Certains attributs UML sont cachés aux applications même si celles-ci


peuvent en avoir besoin.
 Exemple: l'âge n'est pas accessible directement aux applications, mais la date de
naissance l'est. Ex. 30-12-1987.

 La méthode getAge se chargera du calcul de l'âge.

105
1.4 Les méthodes
Création d’un type avec son interface

Create or Replace Type personne_t as Object (nasP int,


dateNaissP Date, villeP varchar2(50),
Member Function GetAge Return Number,
Member Procedure PutDateNaiss ,
Member Procedure ajoutPersonneC) /

 L’âge sera calculé par la méthode GetAge sur appel par un objet ou une variable de type personne_t.
 L'appel se fait par un objet (transitoire ou pas) de son type. Tous les attributs sont alors
visibles à une application.

 Autorisation d’exécuter une méthode associée au type:


-- l’utilisateur Ahmed peut exécuter toute méthode du type personne_t ou celles héritées
dans sa hiérarchie:
SQL> Grant EXECUTE ON personne_t to Ahmed;
Autorisation de privilège (GRANT) acceptée pour l'accès au type personne_t

106
1.4 Les méthodes
Création d’un type avec son interface

 Implémentation des méthodes (body) spécifiées dans l’interface


/*Respecter l’ordre des méthodes de la spécification et dans la création du type */

Create or Replace Type Body personne_t as


Member Function GetAge return Number IS -- signature du body
v_ageP number(4,2) ;
v_naissP Date;
Begin
Select p.naissP into v_naissP From Personne p
where p.nasP = self.nasP ; -- un seul objet retourné avec l’usage de la clé
v_ageP := (Sysdate - v_naissP) /365 ;
Return v_ageP;
End GetAge;

(suite de l’implémentation du body sur l’écran suivant)


107
1.4 Les méthodes
(suite de l’implémentation du body sur l’écran suivant)

 Implémentation des méthodes (body) spécifiées dans l’interface


/*Respecter l’ordre des méthodes de la spécification et dans la création du type */

Member Procedure PutDateNaiss IS


BEGIN
Update PersonneC p set p.dateNaissP = self.dateNaissP
where p.nasP = self.nasP ;
End putDateNaiss;

Member Procedure ajoutPersonneC IS


BEGIN
Insert into PersonneC values (self); éventuellement /* NULL; */
/* Insert into PersonneC values(personneC_t(null, null, ….)) */
End ajoutPersonneC;
End ;

108
1.4 Les méthodes
Notes sur l'implémentation du corps du type: ajout des méthodes à un type

 Le body d'un type est construit en spécifiant un code pour chaque


signature associée au type.

 Important : La signature incluse dans le body d'une méthode doit être


totalement identique à celle spécifiée dans son type.
(utilisez le copier/coller pour éviter les différences et avoir une image exacte de
la chaîne de caractères qui représente la signature de l’interface).

 L’ordre des signatures est significatif : il doit respecter celui des


signatures dans la spécification du type

 Un sous-type peut aussi surcharger les méthodes héritées de son super-


type.

109
1.4 Les méthodes (Appel)
 Avec notation pointée (comme pour les attributs)
 Le select peut-être autorisé sans restriction, car il ne met pas en danger la
cohérence de la base. Sauf le Select …FOR UPDATE.
 Chaînage des appels de méthodes possible
 Exécution des méthodes de gauche à droite,
⇒ Pas d’appel à droite d’un appel de procédure
⇒ Si chaînage, la 1ère fonction doit renvoyer un objet pouvant être passé à la 2ème.

Exemple :
SQL> Select p.getAge()
From Personne p --alias nécessaire pour représenter l'objet
Where p.nasP = 2345;
P.GETAGE()
23
 La fonction getAge() n’exige pas de curseur explicite puisque que le ResultSet ne contient
qu’un objet . Il faut donc faire une sélection avec la clé pour avoir qu'un seul objet dans la
réponse de la sélection.
 Sans paramètre, les parenthèses sont quand même essentielles avec SQL (comme en Java) ,
tandis qu'elles sont absentes en PL/SQL. 110
1.4 Les méthodes (Appel)

 Appel de getAge dans un applicatif et par un objet


Notez l'usage de la fonction Value() pour initialiser une variable objet (de métier):

Declare -- applicatif /* calcul de l’âge avec la méthode GetAge */


v_age int;
v_nasPers int := 123
v_p personne_t; -- objet à instancier au préalable comme persistant ou non (sans oid)
BEGIN
Select value(p) into v_p from Personne p where p.nasP = v_nasPers
v_age := v_p.GetAge; -- appel d’une fonction sans paramètre
DBMS_OUTPUT.PUT_LINE (‘xxxxxx’ || v_age || ' ans');
End;
11
Applicatif PL/SQL terminé avec succès.

111
1.4 Les méthodes
Méthode incluse dans le type

 Le type d’une table typée peut avoir des signatures de méthode:


(exemple : Member Procedure Augmente() ).

 Ajout et suppression d'une méthode :


Alter type employe_t ADD Member Procedure augmentationSal (as IN number);
Alter type employe_t DROP Member Procedure augmentationSal (as IN number);

** Le type de la signature n’inclut pas la longueur du type : Number et


non pas Number(8,2), varchar2 et non varchar2(50), …

 NB : L'évolution d'un type avec le ALTER change le type dans la base mais
pas celui placé dans la cache. Pour voir le changement, il faut vider la cache
en se déconnectant et en créant une nouvelle connexion (nouvelle session) !!
112
1.4 Les méthodes
Opérations légales sur les objets

 Les méthodes sont associées aux objets et implémentent que les opérations
légales sur les objets de la table-objet tout en respectant les contraintes.
 Une méthode peut être ajoutée par la suite à l’interface existante.

 Toute opération sur un objet passe par ses méthodes.


 Ceci exige une analyse préalable pour trouver les méthodes nécessaires aux
applications actuelles et anticiper le futur !!!! C'est le but de l'analyse objet UML qui
identifie les opérations sur les objets (publiées dans le DC-UML).
 Toute modification d’une méthode (sa logique de traitement) s’applique immédiatement à
toutes les applications. Les clauses LMD sont non disponibles aux développeurs.

 L'usage de l'interface d'une classe peut-être aussi un moyen de cacher des


données aux applications ou de les rendre visibles aux applications.

113
1.4 Les méthodes
Suppression et ajout des signatures et/ou des méthodes dans le type

 Le type peut être modifié après sa création: DROP, ADD de signatures:

Alter type personne_t DROP Member Procedure putDateNaiss Cascade;

 Cascade sous-tend que la modification au type sera propagée aux sous-types d’une
hiérarchie d’héritage.
 La suppression du body d’une signature doit cependant précéder celle d’une signature.
obligatoire
 Ajout de la signature putDateNaiss:
Alter type personne_t ADD Member Procedure putDateNaiss Cascade;
Alter type personne_t COMPILE ; -- en l'absence de sa table-objet

 Le OR REPLACE avec le Create et le Alter lancent indirectement une


recompilation du type.

114
1.4 Les méthodes
Sortes de méthodes (résumé)

 Méthode MEMBER
Appel par une variable objet instanciée au préalable (usage du SELF
possible, voire nécessaire).
Les méthodes MEMBER :
 function: Member nomFonction(…) RETURN type IS
... code de la fonction … RETURN var ou self
End;
 procedure: Member nomProc (…) IS
... code de la procédure (PL/SQL, Java, …)
End;

 Méthode STATIC (similaire à une méthode de classe, STATIC de JAVA)


Appel avec le nom du type sans exiger l'instanciation d'un objet appelant.
 STATIC Procedure et STATIC Function
 Constructeur d’objet : implicite et explicite.

115
1.4 Les méthodes
Méthode STATIC

 Une telle méthode est invoquée par le nom du type et non pas par un objet.
L’appel est similaire à un appel de fonction ou de procédure classique.
Exemple d’appel: nom_type.nom_méthode (liste param)

 L'usage du SELF dans le body d’une méthode statique est interdit


puisqu'il n'y a pas d'objet appelant.

 Convient aussi pour implémenter l'encapsulation et permettre les


insertions et les suppressions directes des objets dans les tables objets.

 NB: En Java, une méthode STATIC est une méthode de classe

 Avantage ???
 Il n’est pas nécessaire de créer un objet transitoire inutile pour appeler une méthode.

116
1.4 Les méthodes
Méthode STATIC

Implémentation d'une méthode STATIC

 Une table-objet Labo existe et son type est labo_t, sans méthode constructor
(explicite) pour la création des objets.
Create or Replace Type labo_t as Object (noL int, nomL
varchar2(50), nbBrevet int,
STATIC Function changeNomL (nouvNomL IN varchar2, ancNomL
IN varchar2) RETURN number )
/
Create table Labo of labo_t;
 La méthode changeNomL a une signature comprenant 2 paramètres IN et un
paramètre de retour pour la fonction. (Notez l’absence de la longueur du type)
 Ajout d'un objet:
Insert into Labo values ( labo_t(50, 'nom1', 123)) ;-- constructeur implicite
117
1.4 Les méthodes
Méthode STATIC
Create or Replace type body labo_t as
STATIC Function changeNomL (nouvNomL IN varchar2, ancNomL IN varchar2)
RETURN number IS
Begin
Update Labo Set nomL = nouvNomL Where nomL = ancNomL;
Return 1; -- succès
End;
End;
/
 Une méthode STATIC est appelée comme une fonction classique sans exiger la
création ou la recherche d'un objet pour l'appeler:
 Appel dans un bloc PL/SQL
Declare -applicatif
res int; nomDuType.nomDeLaFonction
Begin
res := labo_t.changeNomL('nom2', 'nom1'); --retour 1si bien exécutée
If res = 1 Then COMMIT; Else ROLLBACK;
End if;
End;
/; 118
1.4 Les méthodes
Méthode Constructor

 Méthode pour les objets non persistants et pour tout nouvel objet instancié
qui doit être initialisé par défaut.
 Deux genres de constructeur d'objets
1. Par défaut (ou implicite ou attribute constructor) qui ne nécessite pas de définition
dans la classe et demande l’initialisation obligatoire de tous les attributs de
personne_t . Le constructeur porte aussi alors le nom du type.
Ex. NEW personne_t ( ….)
avec même nombre d’attributs et dans le même ordre
2. Explicite et concrétisé par une méthode constructor définie par l’utilisateur dans le
type de la classe , (le constructeur porte aussi le nom du type est connu comme le user-
defined constructor); Un constructeur explicite peut assumer des valeurs par défaut.
Ex. personne_t (….)

 Il peut y avoir plusieurs constructeurs pour le même type à condition d'être


distincts par la signature (surcharge du constructeur).
119
1.4 Les méthodes
Méthode Constructor

 Le type du retour d’une méthode Constructor est celui de l'objet d'appel : SELF
 Si aucun constructeur explicite n’est défini dans un type, alors la création
des objets est faite obligatoirement par le constructeur implicite, soit le nom
du type :
employe_t (345, 'Pierre', 2) pour un objet de la table
Employe (nas, poste, expProf).

 Si un constructeur explicite est défini, le New y fera appel en utilisant sa signature.


 Avec un constructeur explicite: des valeurs par défaut peuvent être définies,
sinon elles sont des nulls

120
1.4 Les méthodes
Définition de deux constructeurs

Surcharge du constructeur du type Personnel_t


Create type personnel_t as Object (nas int,
nom varchar(50), ville varchar(50), tauxH real,
Constructor Function personnel_t(nas int, nom
varchar, ville varchar) return SELF as Result,
Constructor Function personnel_t (nas int,
nom varchar) return SELF as Result,
Member procedure calculSal(s1 out real),
Member Procedure calculSal(s1 out real, p2
out real)) /

 Il y a un taux horaire conventionné à 25DT si la ville n’est pas fournie ; sinon le taux horaire est 40DT.
 La procédure calculSal a 1 ou 2 paramètres fournissant le salaire basé sur le taux horaire par défaut
(25DT) et effectue le calcul des charges
121
1.4 Les méthodes
Création d’objets avec un constructeur implicite surchargé

Insert Into Personnel values (personnel_t( 4535, 'Paul'))

ERREUR à la ligne 1 :
ORA-04067: type body "ANGAM5.PERSONNEL_T" n'existe pas - non exécuté
ORA-06508: PL/SQL : unité de programme nommée :
"ANGAM5.PERSONNEL_T" introuvable
 Absence du body ! Et de la table!

122
1.4 Les méthodes
Body des constructeurs surchargés
Create or Replace type body personnel_t as
Constructor Function personnel_t(nas int, nom varchar, ville varchar)
return SELF as Result IS
Begin
Self.nas := nas;
Self.nom := nom;
Self.ville := ville;
Self.tauxH := 40.00;
Return;
End;
Constructor Function personnel_t(nas int, nom varchar) return SELF as
Result IS
Begin
Self.nas := nas;
Self.nom := nom;
Self.ville := ‘inconnue’ ;
Self.tauxH := 25.00;
Return;
End; 123
1.4 Les méthodes
Body des constructeurs surchargés – suite -
Member procedure calculSal (s1 out real) IS
Begin
Null;
End;

Member Procedure calculSal (s1 out real, p2 out real ) IS


Begin
Null; -- Stub
End;
End;
/
Create table Personnel of personnel_t;

124
1.4 Les méthodes
Ajout d’objets avec des constructeurs distincts

Insert into Personnel values (personnel_t( 4535, ‘Tarek’));


 l’objet créé est : [4535, ‘Tarek’, ‘inconnue ‘ , 25.00]

Insert into Personnel values (personnel_t( 776, ‘Sarra’, ‘Tunis’));


 l’objet créé est : [776, ‘Sarra’, ‘Tunis’, 40.00]

 Insert into Personnel values (personnel_t( 120, ‘Rim’, ‘Sousse’, 55.00));

 Select * from Personnel;

NAS NOM VILLE TAUXH


453 Tarek inconnue 25
776 Sarra Tunis 40
120 Rim Sousse 55
125
1.4 Les méthodes
Persistance des modifications

 Oracle ne gère pas la persistance des objets : c’est au programmeur de


coder, si nécessaire, l’ordre update qui garantira la persistance d’une
modification d’un objet.
 Exemple : méthode permettant de modifier le numéro dans la partie adresse
d’un étudiant.

Alter type Etudiant or replace as object ( ...,


Member procedure Changer_Numero (nouveau_numero in Positive) ) ;

Si cette modification n’est pas destinée à être persistante il suffit de modifier


l’objet en mémoire centrale :

Create or replace type body Etudiant as ...


Member procedure Changer_Numero (nouveau_numero in Positive) is
begin self.a.numero := nouveau_numero ;
end Changer_Numero ;
end; 126
1.4 Les méthodes
Persistance des modifications

 En revanche si cette modification doit être persistante, on peut être tenté


d’émettre un ordre de mise à jour dans la méthode :

Create or replace type body Etudiant as


...
Member procedure Changer_Numero (nouveau_numero in Positive) is
begin
self.a.numero := nouveau_numero ;
update Les_Etudiants set a.numero = nouveau_numero
where p.nom = self.nom ;
end Changer_Numero ;
end ;

127
1.4 Les méthodes
Persistance des modifications

Plusieurs inconvénients :
 choix précoce sur le fait que la méthode a un effet persistant ou non
 on pourrait par exemple fournir systématiquement deux versions de
chaque procédure, une persistante et l’autre non.

 en cas de persistance il faut connaître les structures de stockage (les


tables). Un même type d’objet peut être stocké dans plusieurs tables :
comment choisir la bonne table pour garantir la persistance ?
 cela pose aussi des problèmes de maintenance si on choisit de modifier les
noms des tables de stockage.

128
Rappel: Accès aux méthodes par un utilisateur autre que le DBA

 Les méthodes sont définies par le DBA avec la coopération des


développeurs qui en précisent le besoin. Un développeur a accès aux
méthodes que si le DBA lui accorde le droit EXECUTE .
 Par contre un développeur soit le user1, n’aura aucun droit de faire
directement une mise à jour, suppression et insertion d’objets via les
clauses DML: Update, Insert et Delete.
 Contrôle des accès à la base par les méthodes
 Les applications ne seront plus autorisées à accéder directement aux données
avec les clauses Select, Insert, Update, Delete. Elles devront obligatoirement
passées par les méthodes pour manipuler les données de la base.

129
Attribution et révocation des privilèges
 Chaque table-objet de la base est identifiée par un nom préfixé par le
compte du propriétaire:
User2:
Insert into dba.Usine values (usine_t(25, ‘Tunis’, 1200));

Insertion réalisée par le user2, s’il a le droit d’insérer un


objet dans la table-objet : Grant Insert on Usine to user2;

• Révocation des privilèges :


Revoke select, update, delete from user2; ou
Revoke ALL on usine_t from user2;

Il faut passer par les méthodes dont le droit d’exécution est donné par le DBA:
Grant Execute on usine_t to user2;

• En ce faisant, le user2 peut utiliser toutes méthodes de ce type.


130
L'héritage

131
L'héritage

 L’héritage de type sous-tend l'exploitation de tables typées et favorise


la réutilisation du code via les méthodes partagées et éventuellement
certifiées par le DBA.

 En Oracle à partir de la version 9, il est possible de créer des


hiérarchies de types OBJECT, puis d'utiliser ces types et leurs sous-
types lors des créations de tables.

 Il n'y a pas d'héritage entre les tables.


 Pas d'héritage des contraintes entre les tables

 Substitution de type : Ce mécanisme permet d’exploiter les objets d’une


hiérarchie tout en se référant à la racine ou à un niveau intermédiaire.
132
L'héritage
 L'héritage se traduit par la possibilité de définir des types (TAD ou UDT)
avec des attributs et des méthodes qui sont obtenus par voie de l'héritage.

 Pour créer un type pour lequel on va déclarer des sous-types :


 ajouter la clause NOT FINAL à son instruction CREATE TYPE;
 sinon, par défaut le type créé sera considéré par Oracle comme "final",
c'est-à-dire sans sous-type.

 Pour créer un sous-type d'un type non final, il faut rajouter la clause
UNDER nom-sur-type. Le sous-type héritera alors des attributs et
méthodes du sur-type.
 Attention, l'héritage multiple est interdit : un type ne peut avoir qu'un seul sur-type.
 Il n’est pas possible de faire évoluer un type NOT FINAL en FINAL si ce type a des sous-types.

133
L'héritage
 L’héritage est spécifié dans le type avec le CREATE TYPE :
Create type adr_t as object (no int, rue
varchar2(50), ville varchar2(50))
/
CREATE TYPE personne_t as Object (nas NUMBER,
nom VARCHAR(20), adr adr_t) INSTANTIABLE NOT
FINAL
/
CREATE TYPE chercheur_t UNDER personne_t
(sujet varchar2(50)) INSTANTIABLE FINAL
/
Create type etudiant_t UNDER personne_t (pgm
varchar2(50)) Final Instantiable;
/
Create Table Etudiant of etudiant_t ...
Create Table Chercheur of chercheur_t
(Constraint pk_Chercheur Primary key (nas));
Comment les objets de la hiérarchie sont-ils rangés? 134
L'héritage (Directive INSTANTIABLE)
 Les directives INSTANTIABLE et NOT INSTANTIABLE indiquent la
capacité d’instancitation d’un type
 Tous les types crées sont par défaut INSTANTIABLE
 Chaque type dispose d’un constructeur permettant de créer des objets (persistants
ou non) à l’aide de la commande NEW ou au sein d’une commande INSERT.

 NOT INSTANCIABLE s’apparent à la notion de classe abstraite des LPOO


 Tout type INSTANTIABLE possède un constructeur (par défaut) et plusieurs
dans le cas de surcharge
 Un type NOT INSTANCIABLE ne peut pas être FINAL
 Un sous-type NOT INSTANCIABLE doit hériter d’un type INSTANCIABLE

 La commande ALTER TYPE permet sous certaines condition de modifier les opérations FINAL et INSTATIABLE
 Il n’est pas possible de faire évoluer un type INSTANTIABLE en NOT INSTANTIABLE si : des objets sont
rattachés au type (persistant ou non) ou si une table ou vue dépend du type
135
Rangement et Substitution de types : 2 cas

1) Les objets sont rangés (par 3 clauses INSERT) dans leur table respective:
 les objets de type personne_t dans la table Personne
 les objets de type chercheur_t dans la table Chercheur
 les objets de type etudiant_t dans la table Etudiant
Trois tables distinctes et éventuellement dans des espaces de table distincts.
 Insert into Personne values (personne_t(….));
 Insert into Chercheur values (chercheur_t (….);
 Insert into Etudiant values (etudiant_t( ….));
2) Les objets d’une hiérarchie peuvent être rangés dans une même table du
type de la racine par une clause DML Insert:
– Tous les objets : personne, chercheur et etudiant cohabitent dans le
containeur de la classe Personne et donc dans le même table-space
Create Table Personne of personne_t ;
 Insert into Personne values (personne_t(….));
 Insert into Personne values (chercheur_t (….);
 Insert into Personne values (etudiant_t( ….)); 136
Substitution des types : cohabitation de divers objet
dans la même table

● La cohabitation dans une même table-racine des objets de type t1 (la


racine de la hiérarchie) et des objets de sous-types différents, t2 et t3,
est appelée la substitution des types d'objets.
● La seule condition imposée pour cette cohabitation est que les types t2
et t3 soient des sous-types de t1 (i.e. partager la même racine).
A
● Il en est de même pour les objets-colonnes de Oracle
B
● Règles de substitution des types A
1. un objet du sous-type B peut cohabiter avec un autre du type A,
qu’il soit de table ou de colonne;
2. une REF qui pointe sur un objet de type A peut aussi référer à un
objet du sous-type B.

137
Structure de stockage des tables -objets dont les types sont
en relation d’héritage (cas sans substitution des types)

1. Chaque objet est rangé dans sa table et dans son espace de données propre.
(tablespace).

Pour fouiller tous les objets de la hiérarchie, une requête doit débuter par une
consultation du dictionnaire pour générer un plan d’exécution qui sous-tend le parcours
des 3 tables dans autant d’espaces de données utilisés par la hiérarchie.
138
Structure de stockage des tables
Cas avec substitution des types (cohabitation)
2. L’interrogation de la table T1 dont le type est la racine de la hiérarchie
d’héritage permet de fouiller aussi tous les objets des sous-tables de la
hiérarchie rangés dans la table T1 créée dans le tablesapce ts1.

Une requête sur T1 débute par une consultation du dictionnaire pour générer un plan
d’exécution qui sous-tend le parcours d’une seule table T1 rangée dans un seul espace de
données. T1 stocke tous les objets de la hiérarchie. 139
Insertion d’objets de types différents dans la même table-objet
(cohabitation dans la même table d’objets différents de la même hiérarchie)

Insert into Personne values (personne_t (123, 'Riahi'));


Insert into Personne values (chercheur_t (34, 'B Ahmed', null,'physique'));

Un chercheur étant une personne, cet objet peut alors être inséré dans la
table Personne malgré la différence dans la structure!

Select value(p) From Personne p ;

VALUE(P) (NAS, NOM)


PERSONNE_T( 123, 'Riahi')
CHERCHEUR_T(34, 'B Ahmed', null, 'physique')

La fonction Value() fournit en résultat la valeur structurée de l'objet (avec le


nom de son type).

140
Sélection des objets de table à un niveau de la hiérarchie
lorsqu'il y a substitution des types d'objets de table

● Fonction IS OF
Traite à un niveau de la hiérarchie les objets pour sélectionner que ceux
des niveaux inférieurs de la hiérarchie (la racine étant le niveau 0).

Select VALUE(p) From Personne p Where value(p) IS OF (chercheur_t);


VALUE(P) (NAS, NOM)
CHERCHEUR_T (34, 'Tarek', 'physique')

Select p.nom From Personne p Where value(p) IS OF (chercheur_t);

 rend les objets de Personne qui sont de type chercheur_t


* Le filtre se fait avec la fonction value(p)
** La fonction Treat() fait un travail similaire avec les objets-colonnes.

141
Héritage de type et non pas de table (en Oracle)

 Une table-objet typée avec un sous-type n'hérite pas des contraintes d'une
table parent-objet typée avec un sur-type (de la même hiérarchie).
Create table Personne of personne_t (
Constraint pk_personne Primary Key (nasP));

Pas d’héritage de la contrainte

Create table Enfant of enfant_t (


 Constraint pk_Enfant Primary Key (nasP),
Constraint c_age check(age < 16));

** Sans la contrainte de clé primaire dans la table Enfant


permettrait d'ajouter jeux enfants (2 objets) ayant le même nasP.

Cela est possible car la contrainte de clé primaire dans la table Personne n’est pas
l'objet d'un héritage entre les tables. --- l’héritage concerne les types et non les tables ---
142
Clin d’oeil sur la définition de l’héritage avec le LDD
Héritage (spécialisation et généralisation)
Create type personnel_t as Object (nas int, nom varchar(50), …) NOT Instantiable NOT final/
Create type enseignant_t as object UNDER personnel_t ( noCours int) Final Instantiable/
Create type chercheur_t as object UNDER personnel_t (nomLabo varchar2(50), nbArticle int) FINAL Instantiable /

• Le lien d’héritage des modèles UML et


Mnav est implémenté en Oracle objet.
• L’héritage concerne les attributs et les La méthode calculSal()
est redéfinie. Elle est
méthodes. aussi surchargée

NB : La surcharge (même nom mais signature différente dans la même classe ou non) et la redéfinition
(même signature mais body différent dans classes différentes) sont implémentées dans Oracle … qui
devient donc un peu plus OO. 143
Redéfinition (Overriding)

● Une méthode redéfinie dans une sous-classe doit conserver sa


signature et bien sûr son nom :
 Son nom
 Liste de ses paramètres typés (signature)
 Se situer dans une hiérarchie de classe (d'héritage)

● Restrictions qui découlent du bon sens :


 Les méthodes de comparaison ORDER ne peuvent pas être redéfinies (car elles
sont limitées au type racine);
 Une méthode MEMBER ne peut pas être redéfinie par une autre STATIC;
 Une méthode STATIC ne peut pas être redéfinie par une méthode MEMBER
 Les valeurs par défaut d'une méthode doivent être les mêmes dans une
redéfinition de la méthode dans un sous-type.
 Seules les méthodes des types NOT FINAL peuvent être redéfinies;
144
Héritage du type et blocage de l'héritage du type (attributs)

● Les attributs d'un sous-type sont obtenus par héritage conformément


aux directives suivantes applicables au sur-type A et contraignant son
sous-type B: A B

● Les méthodes sont aussi l'objet d'héritage.


145
Pour la méthode

● La signature dans une interface caractérise le body d’une méthode et en


contraint l’héritage et le blocage :
Héritage:
 INSTANTIABLE : signature avec body et utilisable par un objet du type et
elle peut être héritée par un sous-type.

 NOT INSTANTIABLE: signature sans body pour la méthode donc


inutilisable par un objet du type mais la signature peut être héritée. Le type
doit aussi être Not Instantiable.

Blocage (via la signature) de la redéfinition du body d’une méthode:


 FINAL : dont le body ne peut pas être redéfini dans un sous-type;

 NOT FINAL : méthode dont le body peut être redéfini dans un sous-type (overriding).

146
Combinaisons possibles pour les types et méthodes
● Un type Not Instantiable n'a pas de valeurs pour ses attributs mais l'héritage de
ses attributs et méthodes est possible. Une méthode d'un tel type n'a pas de body.
● Dans une interface, une méthode Instantiable doit avoir un body pour traiter les objets.
● Le défaut  *

 NOT Instantiable et la référence à une table objet dans le body


● Un type Not Instantiable peut avoir une méthode (signature) qui est l'objet d'un
héritage, mais cette signature ne peut pas avoir un body.
● Dans un sous-type Instantiable le body d'une méthode peut référer à une ou plusieurs
tables objets à la condition que ces tables objets soient déjà créées dans la base. 147
Directive OVERRIDING (pour la redéfinition de la
méthode dans la sous-classe)
● La méthode (son code) redéfinie est préfixée par la directive OVERRIDING.
● Elle doit conserver son nom et sa signature.
Create type etudiant_t as Object (nasE int, nomE varchar2(50), pgmE int,
INSTANTIABLE NOT FINAL Member Function modif ( p IN number) return int)
Instantiable NOT FINAL -- pour le type
/
● Surcharge de la méthode héritée: le body est choisi par la nature de l’objet
appelant, la signature est la même:
Create type etudiantUniv_t UNDER etudiant_t (matU int, admis Date,
OVERRIDING INSTANTIABLE NOT FINAL
Member Function modif (p IN number ) return int)
Instantiable NOT FINAL -- pour le type
/

148
Redéfinition du body de modif()
(conservation de la signature)
● Avant la création des body, les tables objets doivent être crées:

Create table Etudiant of etudiant_t;


Create table EtudiantUniv of etudiantUniv_t ;

Insert into Etudiant values (etudiant_t(1, 'Maria', 100));


Insert into EtudiantUniv values (etudiantUniv_t(1, 'Maria', 100, 10,Sysdate));

Create or Replace type Body etudiant_t as


Instantiable NOT FINAL Member Function modif (p IN number) return int is
rep int;
Begin
Update Etudiant e Set e.pgmE = p Where e.nasE = SELF.nasE;
rep := 1; return(rep);
End;
End;
/ 149
Redéfinition de Modif() (conservation de la signature)

● Dans la sous-classe:
 Le mot clé OVERRIDING signifie que cette méthode a un body
redéfini mais la signature héritée doit être exactement la même

Create or Replace type Body etudiantUniv_t as


OVERRIDING Instantiable NOT FINAL Member Function modif (p IN number)
return int is
rep int ;
Begin
Update EtudiantUniv e Set e.pgmE = p + 100 Where e.nasE = SELF.nasE;
rep := 2;
Return rep;
End;
End;
/
150
Choix de la méthode redéfinie selon la nature de l’objet appelant

Declare
e etudiant_t;
rep int;
Eu etudiantUniv_t;
Begin
Select value(o) into e From Etudiant o
where o.nasE = 1 ; --chargement d’un objet
rep := e.modif(200); -- modifie le pgm d'un étudiant.
Select value(ob) into eu from EtudiantUniv ob where ob.nasE =1;
rep := eu.modif(200);
End;

● -- choix de la méthode selon le type de l'objet appelant, la méthode de


même nom sera différente
151
Comment le système s'y retrouve dans la redéfinition ?

● À l'exécution, l'appel de la méthode modifPgm lance une


recherche du body dans la classe à laquelle appartient
l'objet appelant (EtudiantUniv).

● Si la signature trouvée concorde avec l’appel, le body de


la 1ère méthode est retenue, sinon la recherche se poursuit
dans la classe supérieure de la même hiérarchie.

● Comme l'héritage multiple n'est pas implanté, aucune


ambiguïté n'est possible dans la remontée de l’héritage.

152
Surcharge : Exemple dans un héritage avec
une méthode STATIC

● La méthode Affiche du type personne_t peut-être utilisée par un


objet du type et aussi être surchargée par un sous-type, soit
etudiantG_t. Dans ce cas, il y a surcharge de la méthode affiche().
153
Surcharge de la méthode Affiche() de etudiant_t

● Création du body de la méthode affiche dans EtudiantG:


Create or Replace type Body etudiantG_t as
Instantiable Not Final STATIC Procedure affiche (nasP IN int, matE IN int) is
etud etudiantG_t;
Begin
Select Value(p) into etud
From EtudiantG p Where p.nasP = nasP and p.matEt = matE;
DBMS_OUTPUT.PUT_LINE(etud.nomP);
End;
End;

Insert into EtudiantG values ( etudiantG_t(50, 'Jamel', 200));

154
Appel de la méthode surchargée Affiche()

● L'appel est fait par un objet et c'est la signature qui permet d'obtenir le
bon body.
● Appel dans un bloc PL/SQL:
Begin
etudiantG_t.affiche(50,200); -- méthode affiche() dans le type etudiantG_t
END;
● Réponse:
 Jamel
>> Procédure PL/SQL terminée avec succès.

155
Dictionnaire de données et les méthodes

● La vue USER_TYPE_METHODS du dictionnaire de données fournit les


informations sur les méthodes de la hiérarchie de types
Select type_name, method_name, final, overriding, inherited
From USER_TYPE_METHODS
Where …;

● Dans la réponse:
 Final: si la méthode peut être redéfinie: (Yes/No)
 Overriding: indique que la méthode (corps) est redéfinie: (Yes/No)
 Inherited: si la méthode est héritée d'un sur-type:(Yes/No)

156
Info du dictionnaire sur la hiérarchie des types
Personne-Etudiant-Employe

157
Conclusion : Relationnel vs Relationnel Objet

 Le nombre de types dans le R est environ 15. EN OR, nombre illimité (!)

 Le MR est basé que sur les valeurs pour matérialiser les associations entre
tables : partage d'attributs partageant un même domaine. Le RO utilise les
REF pour la navigation entre les tables et implémenter les associations.

 La contrainte référentielle du R est implementée par la clé étrangère FK; en


OR, pas de FK obligatoire; il y a le REF, mais avec des limites.

 Seule l'objet de la table OR typée reposant sur un TAD a un oid et un rowid; la


table R n'a pas de oid même si elle utilise un type atomique et/ou type
complexe maintenant permi avec Oracle 10g.

 A la création d'un objet (tupe avec oid), la persistance est assurée. Sans oid un
objet est transitoire!

 Le oid est muté en pointeur physique dans la RAM 158


Conclusion

Oracle versus SQL3 :


Oracle basé sur SQL,
 L’existant +
 Relationnel Objet
 TAD utilisateur,
 Collections,
 Référence d’ objet,
 Héritage (TAD)

Pour compléter ce cours


 Plus de détails sur l'héritage
 Un complément sur les méthodes
 Restrictions sur les signatures (qq. types non autorisés)
 Méthodes MAP et ORDER
 Modèle navigationnel (Mnav)
 Les vues OR
159
Modèle Poste de Travail et
Exercice corrigé les Segments de réseau (PTS)

160
Requête multitable avec
Exercice corrigé une solution relationnelle

Modèle relationnel : présence d'une contrainte référentielle matérialisée


par une clé étrangère

161
Requête multitable avec
Exercice corrigé une solution relationnelle

 Quelle est la longueur du segment sur lequel sont connectés les postes
W7 ? -- (avec jointure relationnelle explicite)

 Lister le numéro de série, le no de segment et le type des postes de


travail connectés au segment ‘Icare' ?

162
Requête multitable avec
Exercice corrigé une solution OR

Des instances du modèle OR correspondant: le Mnav avec pointeur fils Père

163
Requête multitable avec
Exercice corrigé
une solution OR
 Quelle est la longueur des segments sur lesquels sont connectés les
postes W7 ?

 Lister le numéro de série, le no de segment et types des postes de


travail connectés au segment ' Icare' ?

 La formulation est légèrement plus simple et surtout, leur exécution plus rapide.164
Requête multitable avec une solution
Exercice corrigé OR : Table imbriquée de REF

165
Requête multitable avec une
Exercice corrigé solution OR : Table imbriquée
Création du schéma PTS avec une table imbriquée
 Les types :
Create Type posteTravail_t as Object (noSerie varchar2(15),
adrIP varchar2(15), typePT varchar2(15)) /
Create Type poste_t as Object (refPT REF posteTravail_t) /
Create type lesPostes_t as TABLE OF poste_t /
Create type segment_t as Object (noS varchar2(15), nomS
varchar2(50), longS int, lesPostes lesPostes_t) /

 Les tables:
Create table PosteTravail of posteTravail_t ;
Create table Segment of segment_t NESTED TABLE lesPostes Store
AS table_LesPostes ;

166
Requête multitable avec une
Exercice corrigé solution OR : Table imbriquée
Insertion dans la table imbriquée de Segment
Insert into PosteTravail values('p4', 344013, 'TX'); --relié au segment 130.40.30

 Insertion d'un objet avec deux références :


Insert into Segment values (segment_t('130.40.31', 'Dedale', 75, lesPostes_t
( poste_t((select ref(z) From PosteTravail z where z.noSerie = 'p4')),
poste_t((select ref(z) From PosteTravail z where z.noSerie = 'p9')) )
));
 Insertion d'un objet avec une référence (un poste):
Insert into Segment values (segment_t('130.40.33', 'Titus'75, lesPostes_t(
poste_t((select ref(z) From PosteTravail z where z.noSerie = 'p4')))));
 Insertion d'un objet avec une référence nulle :
Insert into Segment values (segment_t('130.40.30', 'ICare', 25,
lesPostes_t(poste_t(NULL), poste_t(NULL))));
167
Requête multitable avec une
Exercice corrigé solution OR : Table imbriquée
Suite …

select * From Segment;

NOS NOMS LONGS LESPOSTES(REFPT)


130.40.30 ICare 25 LESPOSTES_T(POSTE_T(NULL), POSTE_T(NULL))
130.40.31 Titus 75 LESPOSTES_T( POSTE_T(0000220208F0609BD64F8040DE 9C
1 F86486DFFC1F637727164B4794461BE 2B))
130.40.33 Dedale 75 LESPOSTES_T(
POSTE_T(0000220208F0609BD64F8040DE9C1F86486DFFC1F637727164B4794461BE2B),
POSTE_T(0000223508G0609BD64J08040DE9C1F86486DFFC1F637727164B4794461BE2))

168
Requête multitable avec une
Exercice corrigé
solution OR : Table imbriquée
 Quelle est la longueur du segment sur lequel
sont connectés des postes de type TX ?
La réponse requiert un unnesting de la
sous-table avec jointure implicite:

 Numéro de série et adresse IP des postes connectés au


segment de réseau 'Titus' ?
Les attributs proviennent uniquement de la sous-table:

169
Requête avec
Exercice corrigé association réflexive
Solution relationnelle

170
Requête avec
Exercice corrigé association réflexive
Solution relationnelle

171
Requête avec
Exercice corrigé association réflexive
Solution objet relationnelle : usage de REF

172
Requête avec
Exercice corrigé association réflexive
Solution objet relationnelle : Requête OR

173
Exercice corrigé Requête avec
association réflexive
Solution objet relationnelle : Requête OR

174
LES BD ORIENTÉES OBJETS

175