Title: Object Query Language OQL
1Object Query Language (OQL)
2I- Généralités (I)
- OQL s'appuie sur ODMG/ODL
- OQL est proche de SQL 92 avec en
- objets complexes
- identité
- path expressions
- polymorphisme
- invocation d'opérations
- "late binding"
3I- Généralités (II)
- Gestion de sets, bags, lists, arrays, structures
- Résultat d'une requête type ODL gt possibilité
d'imbrication de requêtes - simplicité d'utilisation
- langage déclaratif
- sémantique formelle définie simplement
- OQL peut être appelé dans un programme et
réciproquement OQL peut faire appel à des
programmes externes
4II- Exemples introductifs (I)
- Soit la classe
Personne
(nom, sexe, date-naiss, salaire, opération age)
et la sous-classe Employé (relationship
subordonnés, opération ancienneté) (extensions
personnes, employes) - select distinct x.age from personnes x where
x.name "Alizée" rend un set ltintegergt - select struct(ax.age, sx.sexe) from personnes x
where x.nom "Alizée" rend un bag ltstructgt - select distinct struct(nomx.nom,
gros-salaires(select y from x.subordonnés as y
where y.salaire gt 20000) from x in personnes rend
un set ltstruct(nomstring, gros-salairesbagltemplo
yegt)gt
5II- Exemples introductifs (II)
- Si Directeur est un point d'entrée, alors
Directeur ou Directeur.subordonnés sont des
requêtes valides - personnes (extension de la classe Personne) rend
la liste de toutes les instances de la classe
Personne - first et last permettent de récupérer les 1er et
dernier éléments d'une collection indexée - quand une collection c contient un seul élément,
element(c) retourne un littéral/un objet
contenant cet élément
6III- Création d'objets et de littéraux
- Création d'une personne
- Personne(nom"Alizée", date-naiss"31/12/90")
- gt initialisation d'une partie des propriétés
de l'objet valeur par défaut pour les autres - Création d'une structure struct(a10, b"Théo")
- Création d'un set/bag/list/array
- set(1,2,3,4,5)
- list(1,2,3,4,5) ou list(1..5)
- bag(1,1,2,2,3)
- array(1,1,3,4,3)
7IV- Structure du langage IV.1 Typage (1)
- OQL est un langage typé une requête a un type
- Type d'une requête
- collection d'objets select x from personnes x
where x.nom"Théo" - un objet element(select x from personnes x
where num-SS "xxxxx" - collection de littéraux select x.num-SS from
personnes x where x.nom "Théo" - un littéral Directeur.salaire
8IV- Structure du langage IV.1 Typage (2)
- Typage et polymorphisme
- select e.salaire from etudiants e
- where e in (select dpt.moniteurs from
departements dpt) - plante à la compilation car le compilateur n'a
pas le moyen de - savoir que tous les étudiants concernés par la
requête ont un - salaire
- mais
- select ((Employé) e).salaire from etudiants
e... - est OK.
9IV- Structure du langage IV.2 Path expressions
- Path expressions utiliser . ou ?
- Relations (11) p.épouse.adresse.ville.nom gt
on part de la personne p, puis on va à l'épouse,
qui est également une personne, puis on va dans
l'attribut complexe adresse puis dans l'objet
ville et enfin dans l'attribut nom - Relations (nn) select e.nom from personnes p,
p.enfants e
10IV- Structure du langage IV.3 Prédicats (1)
- Opérations d'aggrégation classiques count, sum,
avg, max, min - Comparaison d'objets (ou de prédicats) e1 e2,
e1 ! e2 - Opérateurs unaires/binaires traditionnels , -,
not, etc. - Chaînes de caractères
- s1//s2, s1s2 concaténation
- c in s inclusion d'un caractère dans une chaîne
- s35 sous-chaîne du 4ème au 6ème caractères
(attention on part de 0 !!!) - méta-caractères ? (ou _) et (ou )
- s like pattern 'Jonas' like 'na rend true
11IV- Structure du langage IV.3 Prédicats (2)
- Quantificateurs for all et exists
- for all p in personnesp.age gt 10 retourne true
si toutes les personnes ont plus de 10 ans - exists p in personnesp.agegt10 retourne true s'il
existe une personne au moins de plus de 10 ans. - Exemples d'utilisation de prédicats
- select e.adresse from personnes p, p.enfants e
- where p.adresse.rue "Jaurès" and
- count(p.enfants) gt 2 and e.adresse.ville
"Lyon" - select... from ltcollectiongt where
exists(select...)
12IV- Structure du langage IV.4 Jointures
- Même utilisation qu'en SQL
-
- select p from personnes p, fleurs f where
p.nom f.nom
13IV- Structure du langage IV.5 Opérateurs
ensemblistes
- Classique
- union, intersect, except
- sort, group by (cf clause select)
14IV- Structure du langage IV.6 Invocation de
méthodes
- Idem référencement d'une propriété (utilisation
de .) - Exemples
- select max(select e.age from p.enfants e) from
personnes p where p.nom "Théo" - supposons que aîné soit une méthode rendant une
entité enfant et que vit-à soit une méthode
vérifiant le lieu d'habitation d'une personne - select p. aîné.adresse.rue from personnes p
- where p.vit-Ã ("Lyon")
15IV- Structure du langage IV.7 polymorphisme
- Soit personnes l'extension de la classe Personne
soit Employé et Etudiant deux sous-classes de
Personnes - les requêtes sur personnes portent sur l'ensemble
des trois (sous-)classes possibles des éléments
de la collection personnes - Late binding si une méthode possède des
implémentations différentes dans les 3
sous-classes, OQL invoque la méthode la plus
spécifique - Indicateur de classe il est possible de
spécifier la sous-classe sur laquelle on va
travailler - select ((Etudiant) p).cycle from personnes p
- where "cours" in p.activités
16IV- Structure du langage IV.8 Valeurs Null
- Pas de sémantique claire. Il existe un objet nil
accéder à une propriété de nil rend un résultat
undefined - Règles
- . (?) appliqué à un opérande undefined rend
undefined - la comparaison avec un ou deux opérandes
undefined rend false - is-defined(undefined) rend false
- is-undefined(undefined) rend true
- toute autre opération avec undefined rend une
erreur. Ex - si une personne n'a pas d'adresse (adresse
undefined) alors select p.adresse from personnes
p rend une erreur mais select p.adresse from
personnes p where is-defined(p.adresse) est OK et
select p from personnes p where not (p.adresse
"Lyon") est OK et rend en particulier les
personnes avec adresse undefined !!!
17IV- Structure du langage IV.9 Requêtes nommées
- Requêtes nommées vues
- define nom(x1,...,xn) as expression-de-requête(x1,
...,xn) - nom identificateur
- expression-de-requête expression OQL
- x1,...,xn variables libres
- Destruction delete definition ltnomgt
- Une vue peut être redéfinie
- Exemples
- define age(x) as select p.age from personnes p
where... - define etudiants() as select p from personnes
where p.profession "étudiant"
18IV- Structure du langage IV.10 Clause select (1)
- Select distinct f(x1,..., xn, xn1,..., xnp)
- from e1(xn1,..., xnp) as x1
- e2(x1, xn1,..., xnp) as x2
- ...
- en(x1,..., xn-1, xn1,..., xnp) as xn
- where p(x1,..., xn, xn1,..., xnp)
- order by f1(x1,..., xn, xn1,..., xnp),...,
fn(x1,..., xn, xn1,..., xnp) - Ex select from etudiants as x, x.choix as y,
y.prof as z - where z.fonction "moniteur" rend un bag de
structures (x, y, z)
19IV- Structure du langage IV.10 Clause select (2)
- Partitions group by... having
- Ex select dpt, salaire-moyenavg(select
e.salaire from partition) - from employes e
- group by dpte.num-dpt
- having avg(select e.salaire from partition) gt
10000 - Portée des identificateurs
- select portée 1
- from personnes, villes v
- where exists (select portée 2 from enfants
as enfant) - or count(select portée
3/select(portée 4 from partition) - from enfants p, portée 5 q
- group by age portée 6
- )
20IV- Structure du langage IV.Exemple simple
- Nom de la rue dans laquelle vivent les employés
ayant en moyenne le salaire le plus faible
comparé aux employés vivant dans les autres rues - 1- construction de l'extension de la classe
Employé - define employés as select (Employé) p from
personnes p where "travail" in p.activités - 2- regroupement des employés par rue calcul du
salaire moyen par rue - define salaire-rue() as select rue,
salaire-moyenavg(select e.salaire from
partition) from employes e group by
ruee.adresse.rue - 3- tri des salaires moyens
- define salaire-rue-trié() as select s from
salaire-rue() order by s.salaire-moyen - 4- récupération du 1er élément de la liste et
affichage du nom de la rue - first(salaire-rue-trié()).rue
- En une seule requête
- first(select rue, salaire-moyen avg(e.salaire
from partition) from (select (Employé) p from
personnes p where "travail" in p.activités) as e
group by ruee.adresse.rue order by
salaire-moyen).rue