207
André Gamache 2005 Fascicule 3 Architectures, modèles et langages de données Hypercube Ingénierie des bases de données OLAP c,d Langage SQL, indexation et vue relationnelle

Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Embed Size (px)

Citation preview

Page 1: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

 

  

  

     

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    Volume I 

  

 

André Gamache 2005

Fascicule 3

Architectures, modèles et langages de données

Hypercube

Ingénierie des bases de données

OLAP

c,d

Langage SQL, indexation et vue relationnelle

Page 2: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

 

Page 3: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

  

Architectures, Modèles et Langages de Données

Volume 1 Fascicule 1

1- Introduction 1

2- Architecture fonctionnelle du SGBD 20

3- Modèle conceptuel des données 79

- Index

Fascicule 2 4- Modèle relationnel : théorie et contraintes d’intégrité 1 5- Algèbre relationnelle 57 6- Transposition du MCD au MRD 137 - Index

Volume 2 Fascicule 3

7- Langage de données SQL 1 8- Indexation, vue relationnelle et base réactive 123 - Index

Fascicule 4 9- Langage de programmation et SQL 1

10- Théorie de la normalisation relationnelle : les formes normales FN1 à FN5 45 11- Optimisation des requêtes relationnelles 117 Annexes : A- SQLoader B- Projet ALU-Nord : Script de chargement des données - Index  

Page 4: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

 

Page 5: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

5

 Chapitre 7   

Langage de données SQL  DDL, DML et les recherches  Dans  les  sections  précédentes,  les  éléments  au  langage  SQL  ont  été  présentés  afin d’illustrer les formulations équivalentes aux opérateurs algébriques. La facette DDL du langage  a  aussi  été présentée  avec plusieurs détails  afin de pouvoir  créer  et  formuler correctement  les  contraintes  des  tables.  Dans  ce  chapitre,  nous  approfondirons  les clauses  SQL‐DDL  en  examinant  quelques  paramètres  qui  ont  trait  aux  structures physiques  et  nous  poursuivrons  l’étude  du  langage  de  requête  SQL,  en  accentuant davantage  les  diverses  fonctions  disponibles  dans  ce  langage  sans  égard  à  leur implémentation  dans  un  SGBD  particulier.  Encore  ici,  de  nombreux  exemples  sont formulés avec le SQL implémenté par Oracle, lequel correspond à peu près au niveau 2 de  la norme SQL‐92. Nous  étudierons  en détails  l’implémentation Oracle de  certaines notions qui sont particulières à ce logiciel SGBD. Cependant, notre étude débordera les limites  imposées  par  Oracle  pour  discuter  aussi  de  plusieurs  autres  notions  et implémentations propres à d’autres SGBD. 

7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL créé dans les années 70 découle des travaux d’une équipe de chercheurs de la société IBM qui travaillait à la mise au point des langages de données SQUARE  et  SEQUEL  dans  le  cadre  du  développement  du  système R,  précurseur  de plusieurs  SGBD  relationnels,  notamment  du  système  SGBD    DB2.  Lʹacronyme  SQL signifie  Structured Query  Language.  C’est  un  langage  à mots  clés  réservés.  Il  est  non procédural  dans  sa  formulation,  masquant  assez    bien  le  caractère  algébrique  des expressions syntaxe relativement simple, mais affiche une facette de langage naturel, soit l’anglais élémentaire. Le langage SQL a fait lʹobjet de plusieurs efforts de normalisation qui ont débuté de  façon  sérieuse en 1989 et qui  se poursuivent  toujours. Toute norme SQL  publiée  peut  être  implantée  à  divers  niveaux,  selon  les  choix  faits  par  le développeur du SGBD. Trois niveaux sont possibles  : minimal  (1),  intermédiaire  (2) et complet  (3).  Ce  dernier  niveau  doit  respecter  intégralement  la  norme  SQL.  Il  y  a plusieurs normes SQL, chacune enrichissant  la version précédente  : SQL‐89, SQL‐92 et SQL‐93.  Lʹimplantation de SQL par la société Oracle est fortement similaire à la norme ISO‐SQL‐92 de niveau 2.  Il en est de même aussi pour le système WATCOM SQL. Le langage SQL comporte trois facettes fortement intégrées peu importe le SGBD relationnel  : a) DDL (Data Definition Language), pour la définition des tables, des contraintes diverses et des vues relationnelles stockées dans le dictionnaire du SGBD. b)  DML,  (Data  Manipulation  Language)  pour  la  manipulation  des  tables  et  plus précisément les manipulations des tuples de relations. c) DCL,  (Data Control Language) pour gérer  la définition physique des accès  (index),  la spécification des  fichiers physiques  et  la  validation des  opérations  exécutées dans un contexte multiposte. 

Page 6: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

6

 

SQL et les autres langages L3G Le  langage  SQL  (Oracle)  est  utilisé  de  façon  autonome  et  interactive  (au moyen  du module SQL*Plus interactif). Il est aussi utilisé dans les blocs de PL/SQL (SQL intégré à un langage procédural interactif de Oracle) et dans les applications mises au point avec les L3G grâce aux API (interfaces de programmation pour les applications). Finalement, le SQL dynamique permet la formulation de requêtes dont la spécification complète ne sera connue qu’au moment de lʹexécution.  

SQL*Plus (rappel sur cette application) Les  clauses du  langage  SQL de Oracle  sont  prises  en  charge  par  le module  utilitaire SQL*Plus qui  les réceptionne et  les  transmet à  lʹinterpréteur de SQL qui est un service intégré du SGBD.  Après le calcul de la réponse, le module SQL*Plus reçoit les tuples et les  affiche  selon  des  paramètres  qui  peuvent  être  fixés  par  lʹutilisateur  au moyen  de directives particulières. Il y a dʹautres modes dʹinteraction avec le SGBD, notamment par lʹentremise des  applications développées  en  langage de  troisième  génération  (L3G)  et utilisant lʹinterface API appelée OCI chez Oracle.  Le module  SQL*Plus  est  donc  lʹintermédiaire  incontournable  lorsquʹun  développeur veut exécuter une clause SQL en mode interactif. Le texte de la dernière clause est placé dans un  tampon prédéfini et nommé par un nom  interne  suffixé par SQL. Cet espace peut contenir seulement une clause SQL, excluant les directives ayant trait au formatage, à  lʹenvironnement  et  à  lʹaffichage  de  la  réponse  par  le  module  SQL*Plus.  Pour contourner  cette  restriction,  il  est possible de définir un  autre  tampon  courant par  la directive SET BUFFER dont la durée est celle de la session de travail.          

 Figure 7.1 

Utilitaire SQLPlus et script d’exécution L’application utilitaire SQLPlus est  incontournable pour  la mise au point et  l’exécution en ligne des clauses SQL. Cette utilitaire SQL*Plus comporte plusieurs directives :   

SET BUFFER tampon1 -- un autre tampon courant est créé SAVE C:\tampon1.sql --sauvegarde du tampon dans un fichier sur C SET BUFFER SQL -- retour au tampon par défaut de SQL*Plus

BD

serveur Tampon SQL*Plus 

Directives SQL*Plus 

 SGBD 

SQL*Plus

client 

Page 7: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

7

 En outre, il est possible dʹenregistrer une trace complète de lʹaffichage avec la directive SPOOL : 

SPOOL C:\trace.4juillet -- trace dans un fichier SPOOL ON -- début de la trace SPOOL OFF -- pour terminer la trace; spool ON pour redémarrer

                                                                             Un fichier de directives est très utile pour obtenir lʹenvironnement désiré et cela, dès le début dʹune  session de  travail. Voici un exemple dʹun  tel  fichier‐script qui est exécuté par la directive : START :environbd3.sql)  Dans le fichier‐script, il faut insérer les commandes et/ou les directives suivantes : 

ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY', ALTER SESSION SET NLS_LANGUAGE_FORMAT = french COLUMN NOM FORMAT A25 .../*liste des formats requis pour l’affichage des colonnes*/

 Le  fichier  est  exécuté  par  START  envirobd3.sql  ou  en  le  nommant  init.sql  ou login.sql,  auquel  cas  il  sera  exécuté  automatiquement  avec  le  lancement  du module SQL*Plus. Avant dʹaborder lʹétude du langage SQL, il est utile de survoler les différentes structures  utilisées  par  la  base  de  données  afin  de  donner  un  sens  physique  aux paramètres des ordres SQL‐DDL. Ce survol est effectué en faisant référence au système Oracle  dont  lʹimplémentation  du modèle  relationnel  et  du  langage  SQL  est  reconnue comme étant de très bon niveau.   Les directives du module SQL*Plus sont résumées dans le tableau ci‐dessous.  APPEND*  Ajout de texte à la fin de la ligne courante CHANGE  Changement de texte dans une ligne CLEAR  Supprimer le contenu du tampon courant DEL  Supprimer la ligne courante DESCRIBE  Liste du schéma d’une table GET  Lecture d’un fichier dans le tampon HOST  <commande>  Exécution d’une commande de l’OS (hôte) LIST  Afficher le contenu du tampon courant RUN  ***  Exécution de  la commande ou du script rangé dans  le 

tampon courant de l’application SQL*Plus SAVE  <fichier.sql>  Écriture de tampon courant dans un fichier SPOOL <fichier.sql>  Écriture de la trace de l’écran dans un fichier  

Page 8: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

8

* Les directives et les commandes peuvent être écrites indifféremment en majuscules ou minuscules. 

Fonctions du dictionnaire de données Le dictionnaire de données (DD) dʹun système relationnel est implanté comme une base de données du même type. Les structures de données utilisées sont les mêmes que celles utilisées  pour  stocker  les  données  transactionnelles.  Le  dictionnaire  contient  les métadonnées nécessaires pour définir notamment  les  tables de  la base de données. Le dictionnaire  de  données  joue  un  rôle  central  dans  le  fonctionnement  du  SGBD relationnel. Son contenu est   rangé dès  le démarrage dans  la RAM, accessible en  ligne par le noyau du SGBD. Les tables du dictionnaire servent à diverses fonctions:  a) Stockage de  la définition de  la base de données  :  schéma,  index,  trigger, packages, fonctions,  procédures,    synonymes  (alias)  etc.  Il  est  entièrement  accessible  à lʹadministrateur  des  données  (DBA)  et  partiellement  aux  utilisateurs  qui  peuvent consulter les tables (et les autres objets) dont ils sont propriétaires.    b)  Passerelle  incontournable  entre  le  noyau  du  SGBD  et  lʹinterpréteur  du  SQL  pour effectuer  lʹanalyse  et  le  traitement  des  requêtes  SQL.  Le  dictionnaire  est  essentiel  à lʹappariement  (binding)  dynamique  avec  les  applications  L3G,  notamment  en  ce  qui concerne la compatibilité entre le type interne dʹune donnée et le type externe disponible dans le langage de programmation hôte.     c) Documentation   des divers objets   de  la base de données  :  tables,  index  , attributs, déclencheurs, packages.     d) Participation à  la sécurité et à  lʹintégrité de  la base en stockant  les droits dʹaccès des utilisateurs aux tables de base, aux vues et aux espaces de données.     e) Répartition des données au moyen des liens entre les bases qui sont spécifiées dans le dictionnaire et leur localisation géographique. 

Introduction à lʹorganisation des espaces physiques et logiques de la base de données Oracle La  base  de  données  Oracle  est  définie  comme  un  ensemble  de  tables  (relations) appartenant  au  compte  créateur  des  tables  qui  a  généralement  la  propriété  du DBA. L’unicité du nom dʹune table est assurée par  l’adjonction automatique du préfixe formé avec  le numéro de compte de  lʹutilisateur propriétaire. La  répartition des données  sur plusieurs serveurs est prise en considération par les métadonnées du dictionnaire sur la localisation,  notamment  les  liens  de  placement.  L’ensemble  des  définitions  de  table correspond au schéma de la base de données qui est exprimé en SQL‐DDL.   

7.2 Objets Oracle Un  objet  ou  plus  précisément  une  entité  de  la  base  de  données Oracle,  est  la  notion utilisée pour représenter les éléments suivants : le schéma de relation, lʹextension d’une 

Page 9: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

9

relation  (table),  les déclencheurs  (trigger),  la  fonction,  la procédure  interne,  lʹespace de données,  lʹindex,  la vue,  le  trigger  et  le package. Tous  ces objets  sont  rangés dans  les tables du dictionnaire du SGBD, sauf  l’extension de  la relation qui est stockée dans un espace de  table  (tablespace). L’accès à chacun des objets est contrôlé par des droits qui sont accordés et, au besoin, révoqués par le DBA.                                                         

Figure 7.2 

Espace de stockage Oracle Une  relation du MRD  est  implémentée par une  structure de  table définie  comme une liste de pages physiques appartenant à un tablespace défini et associé à un ou plusieurs fichiers  gérés  par  le    système  d,exploitation  du  serveur.  Chaque  table  ne  contient  généralement  que  des  tuples  de même  schéma.  Il  y  a  une  exception  avec  les  tables stockées dans un cluster. Un extent est l’unité d’allocation de l’espace et les extents d’une même table forment un segment.         

Structure physique de table : pages enchaînées Figure 7.2a 

 Chaque  table dʹun  schéma appartient au  compte  (Oracle) qui  l’a  créée. Par défaut,    le nom complet dʹune  table est  formé du nom du compte suffixé par  le nom de  la  table: compteChef. Tous  les droits d’accès  sur  une  table  sont  acquis  automatiquement par  le  propriétaire de  la  table qui peut  cependant  les partager  en propageant  aux  autres  les droits  dʹaccès  appropriés  (commande  GRANT).  Une  table  Oracle  est  accessible  par diverses  interfaces  relationnelles,  notamment  via  le  module  SQL*Plus,  le  langage procédural   PL/SQL et lʹinterface de programmation des applications (API) utilisant un langage de troisième génération.  

Compte5.r2 

Compte6.r2 

 Dictionnaire  de données,  schémas, procédures, … 

Compte4.r1 

SGBD Instance1 

BD 

     Piage i 

Page i+1 

extent1  extent2

Page 10: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

10

Organisation logique des espaces de stockage pour les données et les index  La  structure  de  l’espace  physique  d’une  base  de  données  est  définie  par  le DDL  au moyen de plusieurs paramètres qui spécifient  l’allocation  initiale de  l’espace pour une table, à même celui du tablespace auquel  la table sera associée. Les données du système Oracle sont stockées via des espaces logiques, appelés espaces de table (tablespaces) (TS), chacun    composé  de  segments,  eux‐mêmes  composés  de  lots  homogènes  et  contigus d’octets appelés extents. Ces espaces sont utilisés pour stocker notamment les tables, les index, les clusters et les données des segments de recouvrement transactionnel (rollback).               

  

Figure 7.2b Une extent est défini comme une unité dʹallocation de lʹespace physique. Les extents dʹun segment peuvent être dispersés et chaînés. Sur le plan de l’espace physique, un extent est formé  de  pages  contiguës  (blocs  Oracle).  Finalement,  une  page  est  constituée  de plusieurs blocs du  système d’exploitation hôte, blocs dont  la  taille  est  fixée  lors de  la création  de  la  base  de  données.  Lʹespace  physique  dʹune  base  de  données  peut  être augmenté par  le DBA, par  lʹajout, en tout temps, dʹun ou de plusieurs fichiers dans un espace de table particulier.  

Page Oracle Une page Oracle est une suite de blocs physiques constitués dʹoctets contigus (1 K à 16 K). La  taille d’une page est  fixée à  la création de  la base de données par  le paramètre DB_BLOCK_SIZE  initialisé dans  le  fichier  INIT.ORA. Une page  contient normalement des tuples dont la structure est homogène, i.e. appartenant à une seule table, sauf pour les pages de cluster. Ces pages ont une structure particulière permettant d’y ranger des tuples en provenance d’au moins tables différentes.  

Espace de table (tablespace) Toute entité ou  tout objet dans une base de données relationnelle est rangée dans une table qui est elle‐même placée dans un espace de table particulier appelé tablespace . Cet espace  sur  disque  est  associé  à  un  fichier  physique.  Le  compte Oracle  SYS    est,  à  la création de  la base de données,  le propriétaire  initial des objets du dictionnaire  et de 

Espace de table AB

Segment 1 Segment 2

Extent 1         Extent 2        Extent 3                   Extent 4 pages 

Fichier AB 

Fichier B

Page 11: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

11

certaines  autres  tables  utilisées  en  cours  dʹexploitation  pour  stocker  les métadonnées traitant de la performance et de lʹexploitation des tables.  Le  premier  compte  DBA  créé  lors  de  lʹinstallation  du  SGBD  est  nommé  SYSTEM. L’espace de  table SYSTEM  est  aussi  créé  à  lʹinstallation  et  il  appartient  au  compte de même  nom.  Les  divers  objets  créés  y  sont  placés  par  défaut,  y  compris  ceux  des utilisateurs, sauf si lʹutilisateur propriétaire de lʹobjet requiert de le faire autrement. Une meilleure performance est atteinte si les objets dʹindex et de tables des utilisateurs sont placés dans autant de TS (tablespace) distincts créés par le DBA. C’est le principe de base de  l’architecture optimale appelée OFA  (Optimal Flexible Architecture) et suggérée pour Oracle 1. 

           

Figure 7.3  

Structure générale de page Une  page  a  une  taille  fixée  au  lancement  de  lʹinstance  et  cela,  par  lʹentremise  du paramètre de système BLOCK_SIZE. Sa taille peut varier  jusquʹà 16 Ko. Chaque page a une zone de gestion de son espace qui est   appelée répertoire des  tuples ou de  lignes.  L’espace d’une page est assortie d’une contrainte qui est la suivante :  

PCTFREE + PCTUSED < 100  Dans ce  répertoire, on  trouve une entrée où est  inscrit un déplacement  (offset) dans  la page  qui  est  en  quelque  sorte  un  pointeur  sur  le  début  du  tuple.  Lors  dʹune réorganisation de la page, les tuples sont déplacés vers le bas afin de récupérer lʹespace libre. Seuls les déplacements sont modifiés, tandis que le rid ( soit le TID pour Ingres et le ROWID pour Oracle) demeure constant, évitant ainsi de faire la mise à jour des index    

1..* 

1..*

BD 

Schémas 

Comptes 

FichierPhysique EspaceDeTab

Extent 

Page 

Segment

Table1..* 

1..1 

1..1 

1..1 

1..1

1..1 

1..* 1..1 

1..1 

1..* 

1..*1..1  1..1 1..1

1..* 1..*

1..*

1..* 1..11..*

Page 12: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

12

                

Figure 7.4                              Lʹen‐tête de  la page contient des données pour  la gestion  transactionnelle, notamment les  adresses  logiques  (rid)  des  tuples  verrouillés  avec  le  numéro  de  la  transaction propriétaire  du  verrou.  Lors  dʹune  relecture  de  la  page,  le  système  vérifie  si  une transaction inscrite dans lʹen‐tête (qui a donc lu un tuple) est encore active et, dans le cas affirmatif, considère que le tuple est toujours verrouillé. Sinon, le verrou est périmé et le tuple est considéré disponible pour les autres transactions. L’adresse logique d’un tuple nommé rid ou rowid (row identifier) est souvent formée de la façon suivante : 

rid ::= noFichier:noPage:noEntreedansRepertoire

Page Oracle Chaque  page  ou  bloc Oracle  est  composé de  blocs  physiques d’octets  contigus  et  est l’espace  utilisé  pour  ranger  les  tuples  d’une  même  table.  La  structure  de  la  page comprend au moins trois parties  : un en‐tête, une zone primaire pour ranger les tuples (PCTUSED) et une zone de débordement (PCTFREE) pour ranger les tuples dont la taille a augmenté suite à une mise à jour. Par défaut, le système Oracle fixe la zone primaire à 40% de la taille de la page et la zone de débordement à 10 %. Dans les cas où il y a peu de mises à jour et beaucoup d’ajouts, les valeurs par défaut (10/40) pour les paramètres PCTFREE  et  PCTUSED  ne  sont  pas  toujours  adaptées  aux  besoins  d’un  tel environnement d’exploitation. Il faut les ajuster par exemple à 5/80 lorsquʹil y a peu de mises à jour.   Le  rôle du paramètre PCTFREE est de  réduire  le chaînage des parties de  tuples dʹune page à  lʹautre. Cette  fragmentation dʹun  tuple devrait se  faire pour réaliser une mise à jour qui  exige un  espace plus grand non disponible à  lʹadresse actuelle. À  la  création dʹune  page,  le  paramètre  PCTFREE  indique  le  pourcentage  de  la  page  à  garder  en réserve  pour  y  reloger  les  tuples  mis  à  jour.  Le  paramètre  PCTUSED    permet  de  

En‐tête de page 

 Zone  d’élargissement  des tuples   

Zone de tuples    Répertoire des tuples 

INITRANS :  espace  pour  la  gestion des accès à la page MAXTRANS : nombre maximum de transactions en accès simultané.  PCTFREE :  %  de  l’espace  de  page réservé  à  l’élargissement  des  tuples lors de la mise à jour.     PCTUSED : % de la page réservé aux données  et  en  dessous  duquel  la 

Page 13: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

13

minimiser  les  lectures  et  les  écritures  sur  le  disque  en  indiquant  au  serveur  le pourcentage de  lʹespace occupé dʹune page, qui doit être atteint avant que  la page soit désignée à nouveau comme une page  insérable.   En effet,  les  insertions se poursuivent dans une page tant et aussi longtemps que le pourcentage du PCTFREE est respecté. À ce  moment,  la  page  est  marquée  non  insérable  et  supprimée  de  la  liste  des  pages disponibles (free  list). Des    insertions de tuples seront faites à nouveau dans cette page, lorsque  les  suppressions  ramèneront  le  pourcentage  dʹoccupation  de  lʹespace  sous  la barre du paramètre PCTUSED.   Les  tuples des  tables  et des  index peuvent  cohabiter ou non dans  le même  espace de table tout en étant rangés obligatoirement dans des segments différents et donc dans des extensions  différentes.  Dans  une  extension  donnée,  il  n’y  a  donc  que  des  pages  de données  de  tables  ou  d’index  et  non  les  deux.  Dans  les  deux  cas,  les  paramètres PCTFREE et PCTUSED sont utilisés pour la gestion de lʹespace de la page. Avec lʹindex, le paramètre PCTFREE doit être assez grand pour une table indexée, surtout  lorsque le taux  de mise  à  jour  est  élevé.  En  effet,  tout  ajout  de  tuples  dans  une  table  indexée entraîne  une mise  à  jour  de  lʹindex,  donc  une  augmentation  de  la  taille  des  entrées, notamment pour les index sur les attributs de type chaîne. Ceci entraîne rapidement un débordement dans la zone libre. Pour éviter le chaînage des tuples qui ralentit la lecture, il  faut  prévoir  dans  chaque  page  un  espace  libre  un  peu  plus  grand  pour  les  pages destinées à stocker les index.              

Page insérable Une page a  le  statut dʹinsérable  si  le SGBD est autorisé à y ajouter encore des  tuples, sinon elle a  le statut de page non disponible. Lorsque  l’occupation dʹune page est  telle que lʹespace restant correspond à lʹespace réservé par le PCTFREE, la page est enlevée de la liste des pages insérables (free list). Elle ne peut plus recevoir de nouveaux tuples, mais on  peut  toujours  mettre  à  jour  les  tuples  présents  en  utilisant  la  zone  libre  ou  de débordement. Par contre,  lorsque  les suppressions et  les modifications (changement de la valeur d’un attribut qui  fait passer sa  taille de 450 à 40 caractères ou  la mise à  jour d’un  attribut  null)  ramènent  l’espace  occupé  en dessous de  la  valeur PCTUSED pour cette page, celle‐ci est réinscrite dans la liste des pages insérables et de nouveaux tuples peuvent  y  être  ajoutés. Lorsquʹun  tuple  est  ajouté  dans  une  page,  il  est  possible  que lʹespace occupé dépasse le PCTUSED, et cela, tant que la limite du PCTFREE est toujours respectée. Cette situation peut se produire si PCTUSED + PCTFREE < 100. Lorsque  les paramètres PCTUSED et PCTFREE ne sont pas adaptés à lʹenvironnement d’exploitation de  la base de données, cela conduit à des échanges de pages  supplémentaires  inutiles entre  le disque et  la ZMP  (Zone de Mémoire Partagée). Pour une exploitation avec un faible  taux  de  réorganisation  et  de mise  à  jour,  le  facteur  PCTUSED  devrait  être  de l’ordre de 80 et le PCTFREE de 10. 

Page 14: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

14

Migration des tuples Lorsquʹun tuple est modifié et quʹil ne peut pas être replacé dans son espace dʹorigine, le système cherche à le ranger en entier dans lʹespace du PCTFREE (zone de débordement) et une adresse de suivi est placée dans lʹespace dʹorigine afin de garder lʹadressage initial fonctionnel pour les index.         

Figure 7.5 Ainsi,  les  entrées dʹindex  sur  cette  table pointent  toujours  au même  rid    (ou  rowid)  et dans la même page et cela, même si le tuple pointé a été déplacé. Le traitement des index incorpore  celui  du  suivi  dʹun  tuple  au  fil  de  ses  adresses  de  déplacement.  Cʹest  la migration des tuples. Pour lire un tel tuple, le système nʹa pas à effectuer un accès disque supplémentaire  puisquʹil  se  trouve  dans  lʹespace  de  débordement  de  la même  page. Après lʹinsertion du tuple dans lʹespace PCTFREE (débordement), lʹespace dʹorigine nʹest occupé que par une adresse de suivi et le reste de cet espace pourra être éventuellement récupéré pour y placer les données dʹun autre tuple. Si le tuple modifié ne peut pas être rangé dans  lʹespace du  PCTFREE,  il  est déplacé  entièrement dans  une  nouvelle  page insérable et la nouvelle adresse est aussi rangée dans son emplacement initial afin dʹen permettre  le suivi à partir des  index existants, qui pointent toujours sur  lʹemplacement dʹorigine. Lʹinconvénient de cette gestion est que cela oblige à faire deux lectures au lieu dʹune seule pour accéder au tuple recherché. 

Fragmentation des grands tuples et chaînage Une deuxième solution à la gestion des tuples plus encombrants (par exemple les tuples avec un BLOB) consiste à les diviser et à chaîner leurs parties. Lorsquʹun tuple modifié ne peut pas être rangé ni dans sa page dʹorigine ni dans une autre page de  la base de données, le serveur divise le tuple en parties chaînées et chacune sera rangée dans une page ayant lʹespace suffisant.   

    

  

Figure 7.6 

 

12 :89

Tuple  modifié  et placé dans la zone de débordement

Place  initiale du  tuple de rid = 12 :34 

 

tuple rid : 23:12 

PCTFREE

PCTUSED 56:77

123:45

en‐tête

Page 15: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

15

Cʹest le chaînage dʹun tuple qui nʹintervient que lorsque la migration est impossible. Le chaînage  est  aussi pénalisant parce  quʹil  faut  faire plusieurs  lectures  sur disque pour retrouver la première partie et autant de lectures supplémentaires pour lire les autres.  

Placement des données : regroupement La  notion  de  regroupement  des  tuples  (dans  une  structure  de  cluster)  concerne généralement  plusieurs  tables  qui  partagent  les  pages  dʹun  même  segment  spécial appelé cluster.          

    

Figure 7.6a  Ces  tuples  cohabitent  parce  qu’ils  ont  en  commun  des  valeurs  d’attributs  de regroupement  (key  cluster  attributes)  et quʹils  sont  souvent utilisés par  les  applications dans une opération de  jointure.  Étant logés dans les mêmes pages, la vérification de la condition  de  jointure  sera  faite  plus  rapidement  parce  quʹils  seront  accessibles  sans nécessiter d’échanges de pages supplémentaires entre le noyau du SGBD et le disque des données. On peut concevoir la structure logique dʹun cluster comme ayant un répertoire dʹen‐tête  construit  avec  les  valeurs  partagées  par  deux  tuples  de  tables  différentes. Chaque entrée du répertoire pointe sur les deux tuples au moyen de deux rid. Un cluster peut aussi être défini pour ne loger que les tuples dʹune même table, en les regroupant selon la valeur dʹun attribut particulier.  

Rappel de quelques  notions sur les arbres utilisés par les index Les index utilisés par Oracle2 ont généralement une structure en B*‐arbre. Ils sont rangés dans  des  tables,  elles‐mêmes  placées  dans  un  segment  dédié  à  un  index  et éventuellement dans un espace de données (tablespace) spécialisé, créé par le DBA. Cette structure est du type  index hiérarchique  :  les feuilles pointent sur  les adresses rids   (ou encore  ROWID)  des  tuples  indexés  par  un  attribut  dont  les  valeurs  indexées  sont regroupées et ordonnées dans une cellule  terminale  (feuille). Chaque cellule  terminale est  indexée  au  niveau  supérieur  qui  contient  un  pointeur  de  plus  que  le  nombre  de valeurs dans la cellule. Par exemple, la recherche du tuple indexé par la valeur 76 débute à la racine, par l’examen de la première et de la dernière entrée pour déterminer le sous‐arbre à explorer. Le premier examen indique qu’il faut explorer le sous‐arbre milieu et la 

45 ::::23 :34 (45) ::::23 :67      45, ‘jacques’, 75  75, ‘patricia’, 45

Valeur de clé du cluster =  En‐tête du 

cluster 

Page 16: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

16

procédure  se  poursuit  ainsi  jusqu’à  l’atteinte  du  dernier  niveau.  Une  telle  structure arborescente  est  gardée  équilibrée  par  une  procédure  de mise  à  jour  et  la  longueur moyenne du chemin d’accès à n’importe quel tuple est constante. Pour 106 tuples, il faut environ cinq accès pour retrouver un tuple. Dans le pire des cas, cinq lectures sur disque sont nécessaires pour obtenir autant de pages.   Chaque clé primaire spécifiée dans un schéma de table génère soit un index interne (du type Système),  soit une procédure  interne pour vérifier  la contrainte de clé. Toutefois, lʹindex  système  peut  être  désactivé  (disable),  auquel  cas  l’index  nʹest  pas  utilisé  pour renforcer  la  contrainte  dʹentité.  La  contrainte  de NULL  continue  de  sʹappliquer  aux attributs primaires. La création d’un  index avec un attribut  se  fait par une commande SQL‐DCL  et  suppose  un  tri des  valeurs de  la  clé. Lʹopération  sera  effectuée dans  un espace de mémoire  temporaire géré par  le SGBD. Un  index créé par  le DBA peut être supprimé  à  volonté  et  refait plus  tard. Dans  certains  cas,  le DBA peut  accorder  à un utilisateur  le  droit  de  créer  un  index.  Si  une  telle  structure  est  intéressante  pour  la recherche, elle gêne souvent  la mise à  jour. En effet,  l’ajout d’un nouveau tuple  indexé par  la valeur 9  implique une  insertion de  la clé dʹindexation dans  la cellule  référencée par  le pointeur droit de  la clé 3  (voir Figure 7.8). Or, cette cellule étant déjà saturée,  la cellule ciblée sera divisée et la valeur médiane insérée au niveau supérieur par la même procédure. Ces opérations exigent des accès aux disques qui ralentissent  les opérations dʹaccès à la base de données. Le maintien de l’équilibre de l’arbre est toutefois assuré et réparti entre les différentes opérations sur la base de données. 

7.3 B‐arbre   Le  B‐arbre  dʹorigine  est  construit  à  partir  de  la  racine  et  il  est  géré  pour  demeurer toujours équilibré, i.e. avec une hauteur à peu près constante (Figure 7.7).                                                   

Figure 7.7 

81 21 

tuple

  12  3   5235 91 85

  2    1    1913  3937

90 87 

  9995 

  2623   10 5 6255

84 82 

Pointeur  sur  clés  supérieures  à  celles  de gauche et inférieures à celles de droite.  

Pointeur sur tuple         L’absence de la flèche indique l’absence de pointeur. 

Page 17: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

17

 Les cellules feuilles sont aussi reliées par un chaînage latéral afin de faciliter le balayage séquentiel partiel ou complet des tuples d’une table.   Les caractéristiques de cette structure sont les suivantes : Une cellule contient p pointeurs aux sous‐arbres toujours équilibrés et un maximum de (p‐1) clés. Lʹarbre est dit dʹordre p.    Le pointeur à  la gauche dʹune valeur de clé  référence un  sous‐arbre dont  les clés sont inférieures ou égales à la clé du nœud; le pointeur à la droite fait référence un sous‐arbre dont les clés sont supérieures. Le pointeur sur un tuple est constitué du rid, cʹest‐à‐dire lʹadresse de la page. Ce pointeur est inséré dans chaque nœud et non seulement dans les feuilles.  Avec  l’arbre d’ordre  3 de  la  Figure  7.7  (  3 pointeurs  et  2  valeurs de  clé),  la  clé  9  est ajoutée  pour  fournir  l’arbre  suivant représenté  à  la  figure  7.8.  Le  rééquilibrage  est généralement immédiat, ou légèrement différé, cʹest‐à‐dire quʹil est fait pratiquement  à chaque ajout ou modification dans le B‐arbre. En insertion, le tuple est stocké dans une page  et  sa  clé  insérée  dans  la  cellule  appropriée  de  lʹindex  avec  les  divisions  et  les migrations des tuples quʹimposent les règles dʹéquilibre. La principale caractéristique de cet arbre est que les nœuds internes contiennent des pointeurs aux tuples et que les clés ne sont pas redondantes dans les feuilles.  

Procédure algorithmique dʹinsertion La  clé  dʹun  tuple  est  insérée  en  trouvant  la  cellule  où  elle  devrait  être  normalement placée. Sʹil y a lieu, la division de la cellule est faite et la clé à la droite de la médiane est déplacée  au    le niveau  supérieur  en utilisant  la procédure dʹinsertion. Lʹopération  est récursive. 

Procédure  de suppression  La suppression dʹun tuple dans une cellule conserve cette dernière intacte si le nombre de pointeurs résiduel est supérieur à p/2, où p est lʹordre de lʹarbre.             

Page 18: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

18

                    

Figure 7.8 

Calcul de la hauteur dʹun arbre dʹordre  3 (avec p = 3 pointeurs par cellule) La hauteur dʹun B‐arbre peut être estimée par un simple raisonnement inductif : niveau h=1:  1 cellule, 3 pointeurs et  2 clés :  30 p0 cellule et p0 x (p‐1) clés niveau h=2:  3 cellules, 9 pointeurs et 6 clés :  31 p1 cellules et p1 x (p‐1) clés niveau h=3   9 cellules, 27 pointeurs et 18 clés :  32 p2 cellules et p2 x (p‐1) clés donc au niveau h : p(h‐1) (p‐1) >= n  (où n est le nombre de tuples) (h‐1)log p + log(p‐1) >= log n  h>= 1 + (log n ‐ log(p‐1)) avec log dans la base p (soit l’ordre de l’arbre).  Donc le nombre moyen de pages lues dans un accès est environ logp n (dans la base p). Pour un arbre d’ordre plus élevé, par exemple 50, les gains en terme d’accès sont encore plus significatifs : avec   n = 500 000 tuples et p = 50     on a   h ≈ 4.   Soit   quatre  lectures nécessaires pour atteindre la feuille recherchée dans un B‐arbre. Dans le cas courant où la cellule est une page, lʹadresse se réfère à celle‐ci,  la recherche dʹune clé en mémoire se fait très rapidement. En effet, la taille d’une page (8Ko) pour la cellule confère un ordre relativement  élevé  à  l’arbre  pour  ainsi  en  diminuer  sensiblement  la  hauteur  à  une constante généralement inférieure à 8. La base p du logarithme joue un rôle critique. En effet, plus p est grand, plus la valeur du log dans la base p est petite. 

Avantages de la structure en B‐arbre  Le B‐arbre offre plusieurs avantages lorsquʹil est utilisé comme index :  ‐ Le parcours moyen pour trouver un tuple est inférieur à la hauteur de lʹarbre. 

  21 12

tuple

  10 3   5235 91 85

  2  1    1913  3937

  9087 

  9995 

  2623   9 5  6255

  8482 

  81 

tuple 

Page 19: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

19

‐ Il nʹy a pas de redondance des clés à la suite dʹune duplication dans les feuilles. ‐ La hauteur dʹun arbre pour indexer un nombre n de dossiers est la même quel que soit 

le chemin parcouru. Pour 2 millions de tuples, il est de lʹordre de 5 accès au disque. 

Inconvénients du B‐arbre Lʹajout et  la suppression sont des opérations complexes en  raison de  la  réorganisation des nœuds  internes. Périodiquement,  le DBA  aura  à  supprimer  lʹindex  et  à  le  recréer pour  compacter  les  entrées. Les  pointeurs  aux  tuples  (8  octets)  occupent  lʹespace des cellules autrement occupé par des clés. Finalement, le parcours séquentiel des tuples est parfois difficile, voire impossible ou impraticable, en cas dʹabsence de chaînage latéral à tous les niveaux et en raison de la dispersion des pages qui exige plusieurs lectures sur le disque. 

B*‐arbre La  structure  du  B*‐arbre  est  similaire  à  celle  du  B‐arbre,  mais  les  clés  des  cellules intermédiaires sont aussi  insérées dans  les  feuilles avec  le pointeur aux  tuples,  i.e. aux données.  Les  nœuds  intermédiaires  ne  pointent  pas  sur  les  tuples.  Il  y  a  donc  une certaine  réduction  de  la  redondance,  augmentant  ainsi  la  densité  des  tuples  dans  les pages de données. Le parcours séquentiel des feuilles est possible au moyen du pointeur de chaînage latéral. 

Variantes du B‐arbre Deux variantes existent pour le B‐arbre : ‐  B+‐arbre  :  il  correspond  au  B‐arbre  classique  avec  des  pointeurs  aux  tuples  placés uniquement dans les feuilles et un remplissage des cellules qui ne dépasse pas  la moitié de leur capacité. ‐ B*‐arbre : il est identique au B+‐arbre, mais avec la garantie dʹun remplissage de chaque cellule ne dépassant pas les deux tiers de sa capacité.   Le nombre de réorganisations des cellules peut devenir important, surtout à lʹapproche de  la  saturation des  feuilles de  lʹarbre. Dans  la pratique,  lorsque cet état est atteint au cours d’une mise à  jour,  les procédures de gestion de  l’arbre amorcent  immédiatement sa  réorganisation  en  divisant  le  contenu  de  la  cellule  saturée  en  deux  parties  et  en réallouant  l’espace  pour  une  ou  plusieurs  nouvelles  cellules  du  B‐arbre.  L’effort  de rééquilibrage  est  consenti  au  fur  et  à  mesure,  par  quanta  répartis,  afin  d’éviter l’accaparement du noyau du SGBD aux temps d’une demande forte et durant lesquelles le travail de réajustement ralentirait les opérations dans la base de données. 

Mécanisme de verrouillage des tuples  Normalement, un utilisateur du système Oracle exploitant directement les données par lʹentremise de SQL*Plus, soit par une application n’a pas à se soucier du verrouillage des données. La gestion des verrous est automatique et assumée par le SGBD du serveur. Un premier utilisateur qui accède à une table acquiert aussi un verrou dʹexclusivité TX (ou plus simplement X)  sur chaque tuple modifié ou inséré et un verrou RX sur la table. Le verrou RX (RS en premier se transformant en RX) sur une table autorise la transaction à faire dʹautres actions sur les tuples de la table qui ne sont pas encore verrouillés par une 

Page 20: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

20

autre transaction. À la fin de la mise à jour marquée par un COMMIT transactionnel, les verrous  sont  automatiquement  libérés  par  le  moteur  dʹOracle.  Le  système  pose  un verrou  au niveau des  tuples,  sauf  si une  application  le demande  explicitement par  la commande explicite LOCK TABLE. Le verrou contrôle alors  toute  la  table. L’atomicité de chaque ordre SQL est assurée par le SGBD en ce sens quʹun ordre est complété ou en cas d’erreur, défait entièrement, et cela, sans intervention directe de lʹapplication. 

7.4 Association des espaces de table avec les fichiers physiques Les espaces de table nommés tablespaces (TS) sont associés à des fichiers physiques dʹun OS    lors  de  leur  création  par  le  DBA.  Les  tables  et  les  index  sont  créés  et  associés explicitement à un TS particulier par une commande particulière utilisée seulement par le DBA.  

CREATE TABLESPACE ESPACE_USER3 --commande pour le DBA DATAFILE '/usr/users/fichier1.dbf' SIZE 25M DEFAULT STORAGE INITIAL 50K NEXT 30K PCTINCREASE 0 MINEXTNENTS 1 MAXEXTENTS 100 ONLINE;

Une table peut être rangée explicitement dans ce tablespace  déjà créé par  la commande DDL suivante : 

CREATE TABLE Usines( no number(2) constraint cp_usines primary key, libelle varchar2(45), ville varchar2(60), capacite number, -- par défaut un entier de précision 32 classe char(1)) TABLESPACE ESPACE_USER3;

 Lʹespace  de  table  est  nommé  et  son  espace  maximal  spécifié  dans  une  commande antérieure  est  de  50 Mo.  Toutefois,  lʹespace  initial  est  de  50K  et  augmente,  selon  les besoins,  par  quanta  de  30 Ko.  Toute  table  stockée  dans  cet  espace  de  table  aura  les caractéristiques de  stockage par défaut. Normalement,  lʹespace de  table est créé par  le DBA et non par les développeurs. La création d’une table se fit dans un espace prédéfini par le DBA et alloué au compte Oracle par défaut. N.B.  Si  lʹespace  de  table  nʹest  pas  fourni  dans  la  commande  CREATE  TABLE  ou prédéfini par défaut,  les objets sont rangés dans lʹespace de table SYSTEM.      Les segments ROLLBACK et les INDEX sont aussi créés explicitement par le DBA : 

CREATE INDEX Usines_nom_idx On Usine(nom); CREATE [PUBLIC] ROLLBACK SEGMENT segt25 TABLESPACE TS_table10;

 La création d’un segment temporaire est effectuée automatiquement par le SGBD lors de son  installation.  Rappelons  aussi  que  les  segments  de  rollback  sont  nécessaires  pour 

Page 21: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

21

effectuer le UNDO  ou le ROLLBACK dʹune seule transaction  sans pour autant recourir au journal interne qui est global à toutes les transactions.                        

Bases de données de référence Les  exemples  utilisés  pour  illustrer  les  premières  clauses  SQL du  présent  chapitre  se réfèrent à quelques bases de données dont le schéma et la sémantique sont présentés ci‐dessous.  Les  versions  récentes  des  SGBD  utilisant  lʹUNICODE  devraient  pouvoir éventuellement  accepter  les  signes  orthographiques  nationaux  dans  les  clauses  SQL. Pour  simplifier  la  base,  on  convient  dʹutiliser  de  préférence  les  minuscules  non accentuées, mais en tolérant les exceptions pour des raisons de meilleure lisibilité. 

BD1 : Ventes au détail Cette  extension  de  la  base  de  données  valide  la  contrainte  référentielle  qui  est implémentée  et  active  lors  des  transactions  sur  la  base.  Elle  sera  utilisée  par  la  suite comme base de  référence pour de plusieurs  exercices SQL. La base  est  composée des tables Ventes et Inventaire.  

Ventes :  nom*  article*  qte*  (table enfant)   Serge  a1  3     Ted  a2  5     Andrée  a1  2     Serge  a2  4     Erik  a1  2     Serge  a3  4     Valérie  a7  3     Lucie  a7  2     Serge  a5  3     Serge  a7  5     Christine  a3  6     Serge  a1  7   

 Cette  contrainte  référentielle  est  un  cas  particulier  d’une  contrainte  d’inclusion  plus générale qui  spécifierait que  tout  article de  la  relation Ventes doit  être  inclus dans  la projection  de  la  table  Inventaire  sur  l’attribut  article. Une  transaction  sur  la  base  ne concerne qu’un article en inventaire au moment de la vente, tandis que chaque article en inventaire peut faire l’objet de plusieurs transactions de vente.        Dans  la table Inventaire,  les attributs prixVente et cout partagent  le même domaine de valeurs, mais avec une sémantique distincte marquée par un  libellé respectif différent. Tous les articles vendus sont inscrits dans lʹinventaire. Au moins un article disponible en inventaire n’a pas encore été vendu. Pour satisfaire l’hypothèse de la relation universelle qui  impose  l’unicité  des  libellés  dans  un  schéma,  les  articles  déjà  vendus  et  ceux actuellement  en  inventaire  peuvent  être  libellés  respectivement  Ventes.article  et 

Page 22: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

22

Inventaire.article. Une  transaction de vente est  inscrite en notant  le nom de  l’acheteur, l’article et la quantité. La clé de la table Ventes est rendue volontairement complexe par l’absence  d’un  numéro  de  transaction.  Dans  ce  schéma,  elle  est  formée  de  tous  les attributs.    

Inventaire :  article*  prixVente  cout    (table parent)   a5  17  20     a1  10  5     a2  20  0     a7  15  15     a3  25  null     a16  46  34  + nouvel  article 

Figure 7.9  La  table  Inventaire  fournit  les articles en  inventaire. L’absence de coût signifie que cet article n’est plus disponible. La contrainte référentielle est spécifiée par une clé étrangère mono‐attribut  dans  la  table  Ventes  (soit  article)  portant  le  même  libellé  que  la  clé primaire dans la table parent Inventaire. La simplicité de la relation Inventaire et le choix de sa clé sous‐tendent que certains faits ne peuvent pas être représentés dans cette base. Par exemple, deux articles  identiques achetés à des  coûts différents ne pourraient pas être représentés dans cet inventaire.  

BD2 Gestion des stocks de pièces pour les transporteurs aériens  Cette deuxième base représente les stocks de pièces des transporteurs aériens répartis ici et là dans le monde pour la réparation de leurs avions.   

Transporteur :  mat*  nom  volPass  villeSS  permis   f1  Flyer  200  Londres  235   f2  Inter  100  Paris  160   f3  Airqc  300  Québec  null   f4  Boac  200  Londres  190   f5  Delta  300  Boston  120 

 Un transporteur a un permis d’opération pour chaque avion q’il possède, une matricule, un siège social dans une ville donnée et un nom de société. Le permis d’un transporteur peut être révoqué  temporairement auquel cas  l’indicateur null est utilisé pour signifier l’absence  de  permis.  Chaque  transporteur  peut  déplacer  un  nombre  maximum  de passagers par jour (volPass).     Dans  le cas de cette base BD2,    l’hypothèse de  la relation universelle est aussi vérifiée, car un libellé d’attribut n’a qu’une seule sémantique, peu importe la table où il apparaît. Les attributs proprio et mat partagent le même domaine sémantique. En outre, l’attribut proprio peut être null comme cela est signalé par un null dans l’extension ci‐dessus. 

Page 23: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

23

                                        Pieces :  noP*  description  km (K)  poids  villeP  proprio 

  p1  aileron  8500  12  Londres  f3   p2  moteur  9900  50  Paris  f5   p3  porte  6000  17  Rome  f1   p4  radar  8000  14  Londres  null   p5  train  5000  78  Paris  f2   p6  télémètre  9000  36  Londres  f2 

Figure 7.10    La  contrainte dʹinclusion  (qui est dénommée DIN) est du genre  référentiel et elle doit être valide à tout moment. De plus, le permis de vol international est unique et identifie le transporteur, mais il est possible d’avoir un transporteur qui ne l’a pas ou qui est en instance de l’obtenir (unicité de l’attribut avec valeur nulle autorisée). Lʹattribut permis ne peut donc pas être une clé, car  il peut être nul. Les clés sont respectivement mat et noP.  Les  attributs  proprio  et  mat  ont  le  même  domaine  sémantique  et  font  donc référence au même concept. Si  la colonne proprio était  ignorée,  la table n’aurait pas de contrainte référentielle et les deux tables seraient sans association sémantique.   La ville du siège social du transporteur est nommée différemment (villeSS) de celle du dépôt de pièces (villeP). L’hypothèse de la relation universelle est donc vérifiée de facto. Il y aurait une ambiguïté  si, dans  les deux  relations,  il y avait un même attribut ville ayant deux  interprétations différentes. Avec  la  colonne proprio  (comme  clé étrangère) dont  le domaine  sémantique est partagé avec  celui de mat, un  lien est établi entre  les deux  tables  et  les  jointures deviennent possibles. Avec  ces deux  tables,  il  serait  aussi possible  de  définir  un  cluster  indexé  de  placement  des  tuples  pour  que  ceux  qui partagent  la même valeur de  la clé du cluster (par exemple,  la clé primaire et de  la clé étrangère) soient rangés dans la même page. 

BD3  Dotation des ressources humaines Cette base implante une association (n‐m) entre deux classes au moyen d’une troisième relation ou table.   

Postes :  noPoste*  description   j12  gérant   j34  électricien   j98  null   j21  mécano1   j55  contrôleur   j75  mécano2 

 

Page 24: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

24

Empl :   noEmpl*  nom  prenom  tauxH   P346  Audy  Rudy  13.00   P456  Gagnon  André  17.00   P345  Audy  Michel  12.50   P651  Tremblay  Robert  12.50   P762  Dussault  Marc  13.25   P337  Bérube  null  12.50   P450  Dion  Fabrice  13.25   P535 

P800 Joncas Vanjulier 

Sylvie Julie 

14.50 19.50 

                                                      

Assignations :  noPoste*  noEmpl*  debut  quart   j12  P456  21‐jan‐1992  soir   j34  P651  22‐mar‐1991  jour   j21  P762  23‐dec‐1990  nuit   j34  P345  24‐sep‐1994  jour   j75  P346  12‐oct‐1997  null   j55  P456  25‐jan‐1994  jour   j34  P337  21‐jan‐1992  nuit   j75 

j34 P450 P800 

27‐jan‐1994 10‐nov‐1995 

null soir 

* Indique un attribut primaire (i.e. un attribut inclus dans une clé) Figure 7.11 

 Le  lien d’association complexe entre  les deux  tables est assuré par une  troisième  table Assignations.  La  troisième  table  utilisée  pour  implémenter  lʹassociation  a  une  clé primaire  composée  (noPoste,  noEmpl);  les  deux  clés  étrangères  distinctes  dans  cette table sont respectivement noPoste et noEmpl.  

7.5 Schéma de la base de données Le modèle conceptuel est transposé en un modèle  logique  (MLD) propre au SGBD par lʹentremise de règles de passage particulières. Le schéma du modèle logique est spécifié par  les  clauses  SQL‐DDL  qui  définissent  les  tables  de  la  base  de  données  et  leurs caractéristiques.  Les  contraintes  dʹattribut,  la  clé  primaire  et  la  ou  les  clés  étrangères dʹune relation sont aussi définies dans le schéma.  

Création dʹune table et le typage des attributs La  création d’une  table  consiste à définir  son  schéma  et à  l’associer à un nom unique composé du  compte propriétaire  et du  libellé de  la  table. Définir une  table  sous‐tend aussi  la  spécification  de  ses  attributs  typés,  des  contraintes  d’intégrité  associées  aux attributs et, éventuellement, de son espace de table. Les types internes (type avec lequel une donnée est stockée dans la base de données) disponibles dans Oracle sont similaires à ceux spécifiés par le SQL‐92 avec cependant quelques différences. Par exemple, le type booléen n’est pas  toujours  implémenté ;  il est cependant présent dans  la version 9i de Oracle et de DB2.  

Page 25: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

25

Types internes dʹOracle pour les données Les  SGBD    comme Oracle, DB2  et  Informix  sont  capables de  représenter  les données avec une  gamme  assez  étendue de  types.   Toutefois  leurs  types ne  sont pas  toujours aussi  élaborés  que  ceux  des  langages  de  programmation  de  3e  génération.  Une conversion  s’imposer alors, opération qui devra être prise en  charge par  l’application! Avec Oracle, les types suivants sont disponibles :   VARCHAR2(w), où w est la longueur de la chaîne,  max. 2Ko,  et 4Ko avec la version 8. NUMBER(p, s),  p est le nombre total de chiffres avec  s chiffres après le point (scale). LONG, données en caractères jusqu’à deux Go (image). DATE  (1),  ce  type  comprend  les  éléments  suivants :  le  siècle,  l’année,  le mois,  le  jour, l’heure, la   minute, la seconde(voir (1)). RAW (w), données en binaire, pour une longueur maximale de 255 octets; LONG RAW, données en binaire, jusqu’à 2 Go. ROWID, caractères hexadécimaux représentant l’adresse du tuple. CHAR (w), où w est la longueur fixe de la chaîne avec un maximum de 255 o. MLSLABEL, étiquette de système (pour la version Trusted Oracle). FLOAT (b), pour les réels avec précision b. CLOB, données de longueur variable codées sur 1 octet/caractère, mx 4Go. BLOB, chaîne de bits, max. 4Go. NCHAR, chaîne fixe de caractères NLS (alphabet national).  L’implémentation des  types peut varier d’un manufacturier à  l’autre avec  la  limitation classique pour le Float dans sa représentation des entiers et des réels.   (1) Le  type DATE  a un  format  externe  bien  connu, mais  son  format  interne  est  bien différent. Le passage de l’un à l’autre se fait par des fonctions spécialisées : TO_DATE(), TO_CHAR() et TRUNC(). La  fonction TO_CHAR(), avec un gabarit approprié, permet dʹafficher  la date dans  le  format  externe  souhaité  et de  supprimer  le  temps  lors de  la transposition  de  la  date.  Cela  permet  ainsi  de  faire  des  comparaisons  fondées uniquement sur le jour, le mois et lʹannée: TO_CHAR(dateContrat, ʹYYYY‐MM‐DDʹ) ‐‐>  ʹ1999‐11‐24ʹ.  

Conventions dʹécriture des contraintes de clé  Les tables sont créées avec une clé primaire (dite aussi principale) et éventuellement une ou plusieurs clés étrangères. Le nom d’une contrainte spécifiée lors de la création dʹune table doit être unique et peut être formé par simple convention d’écriture avec le préfixe cp_ ou pk_ pour  la contrainte de clé primaire    suivi du nom de  la  table. Pour une clé étrangère, le nom de la contrainte est préfixé par fk_, suivi du nom de la table enfant et au  besoin,  celui  de  la  table  parent.  Exemple,  fk_ouvrier_atelier,  pour  dénoter  la contrainte  référentielle entre  la  table Atelier et Ouvrier. Ainsi,  le nom de  la contrainte permet de l’associer au couple table enfant‐parent.  

Page 26: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

26

Voici la formulation du schéma de la table Ventes de la BD3  :  CREATE TABLE Ventes(

nom VARCHAR2(15) NOT NULL, article VARCHAR2(10) NOT NULL, qte NUMBER(3), CONSTRAINT pk_Ventes PRIMARY KEY (nom,article, qte), CONSTRAINT fk_Ventes_inventaire FOREIGN KEY(article) REFERENCES Inventaire (article) ) [Tablespace TS_user99 Storage initial 500M next 75M minextents 5 maxextents 20] ;

 N.B. Les  tuples de  la  table Ventes  sont  rangés dans  lʹespace  table TS_user_99  jusquʹà hauteur de 10 Go. Le reste de lʹespace sera occupé par dʹautres tables. La spécification de l’espace  de  données  (tablespace)  n’est  pas  nécessaire  lorsque  le  rangement  des  tuples  est  fait automatiquement dans l’espace de données associé par défaut au compte de l’utilisateur. Lorsque la clé primaire est simple, elle peut être aussi définie au niveau de lʹattribut.    

CREATE TABLE Inventaire ( article VARCHAR2(10) CONSTRAINT cp_inventaire PRIMARY KEY, prixVente NUMBER(5,2) NOT NULL, cout NUMBER(5,2) null) PCTFREE 20 PCTUSED 75 [TABLESPACE TS_donnees1]; --table stockée dans TS_donnees1

 La  table  est  créée  et  les  données  seront  stockées  dans  un  espace  de  table  nommé TS_donnees1.  Si  lʹespace  de  table  nʹest  pas  identifié,  lʹextension  sera  créée  et  placée automatiquement dans lʹespace de table SYSTEM. Ce dernier est créé par le SGBD pour y ranger les tables du dictionnaire. Il faut donc de préférence ne pas engorger cet espace en plaçant les données dans des espaces de table séparés stockés au besoin sur un disque différent.  

CREATE TABLE Transporteur( mat CHAR(3) NOT NULL, nom VARCHAR2(15) NOT NULL, volPass NUMBER(3), villeSS VARCHAR2(15), permis CHAR(3) NULL, CONSTRAINT pk_transporteur PRIMARY KEY (mat)) [TABLESPACE TS_donnees_user]; **** -- [] signifie non nécessaire selon le cas. Les données sont rangées dans le tablespace TS_donnees_user

 CREATE TABLE Pieces (

Page 27: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

27

noP CHAR(2) NOT NULL PRIMARY KEY, description VARCHAR2(15) NOT NULL, km NUMBER(4)NOT NULL, poids NUMBER(2)NOT NULL, VILLEP VARCHAR2(15) NOT NULL, proprio CHAR(3) NULL, CONSTRAINT fk_transporteur_pieces FOREIGN KEY (proprio) REFERENCES Transporteurs(mat)) [TABLESPACE TS_donnees_user];

CREATE TABLE Empl(

NOEmpl CHAR(4) NOT NULL PRIMARY KEY, -- si clé simple nom VARCHAR2(35) NOT NULL, prenom VARCHAR2(25) NULL, TAUXH NUMBER(5,2) NOT NULL check(tauxH > 10.00)) TABLESPACE TS_donnees_user;

CREATE TABLE Postes( NOPoste CHAR(3) NOT NULL PRIMARY KEY, description VARCHAR2(45) null) [TABLESPACE TS_donnees_user];

CREATE TABLE Assignations ( NOPoste CHAR(3) NOT NULL, NOEmpl CHAR(4)NOT NULL, debut DATE NOT NULL, quart VARCHAR2(6) NULL, CONSTRAINT cp_Assignations PRIMARY KEY (noPoste, noEmpl), CONSTRAINT fk_Assignations_empl FOREIGN KEY(NOEMPL) REFERENCES EMPL (noEmpl), CONSTRAINT fk_Assignations_postes FOREIGN KEY (noPoste) REFERENCES Postes (noPoste)) TABLESPACE TS_donnees_user;

 Le schéma de cette dernière table comprend une clé primaire et deux clés étrangères. Par la suite, le DBA ou le propriétaire de la base de données peut toujours modifier certains paramètres d’un schéma par la commande ALTER  TABLE : 

ALTER TABLE Postes ADD (description varchar2); ALTER TABLE Postes DROP description; --avec la version 8

   Les clés primaires sont qualifiées NOT NULL de sorte que si le chargement initial de la base de données est fait avec une clé primaire désactivée, les nulls seront quand même interdites de stockage.  À la fin de lʹopération, la clé primaire est activée de nouveau afin dʹamorcer  la  construction  ou  la mise  à  jour  de  lʹindex‐système  sous‐tendu  par  la  clé 

Page 28: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

28

primaire. Cette façon de faire est plus rapide, puisquʹil nʹy a pas de mise à jour de lʹindex en cours de chargement, mais exige lʹabsence de clés dupliquées. Avec le NOT NULL, le chargement refusera tout tuple dont les attributs primaires ne sont pas valués, puisque ces données ne constituent pas une clé valide. 

Les clés : primaire, étrangère et attribut UNIQUE Une  clé primaire  limite  la nature des  tuples  qui peuvent  être  rangés dans  la  base de données en interdisant les doublets. En effet, il ne peut pas y avoir deux tuples ayant la même  valeur  pour  les  attributs  de  la  clé  primaire. Cette  contrainte  est  généralement placée à la fin de la spécification du schéma d’une table et est nommée de manière à la distinguer dans le dictionnaire. La clé primaire peut être simple ou composée. Voici un exemple dʹune clé composée : 

CREATE table Assignation ( noEmpl number(2) not null, noPoste number (2) not null, … , CONSTRAINT cp_EmplPoste PRIMARY KEY (noCours, section);

 Lorsque  la  clé primaire est  composée, elle peut être  formulée pour avoir des attributs nuls, pourvu quʹun des attributs primaires soit non nul. Dans ce cas, la contrainte de clé primaire  est  implémentée par  la  clause UNIQUE(),  laquelle permet de  contraindre  les valeurs pour quʹelles soient toutes différentes ou nulles pour un ou plusieurs attributs.  

CREATE TABLE Employe ( nom varchar2(50) NOT NULL, noEquipe number(4) NULL, . . . ) Constraint U_NoBinome UNIQUE(nom, noEquipe) );

                     La paire dʹattributs (nom, noEquipe) doit avoir au moins une valeur pour l’attribut nom qui  ne  peut  pas  être  nul. Toutefois,  lʹattribut  noEquipe  peut  être  nul  comme  cela  est autorisé par les UNIQUE et NOT NULL. Une contrainte étrangère peut être spécifiée en se référant a un attribut UNIQUE, donc à des attributs qui ne sont pas une clé primaire.  La clé étrangère simple ou complexe exprime une contrainte pour les tuples qui peuvent être ajoutés dans  la  table  enfant  et une autre  contrainte  sur  la  suppression des  tuples dans  la  table  parent.  Soit  la  table  ChoixCours  avec  une  contrainte  référentielle  par rapport à la table parent CoursHoraire.  

CoursHoraire(noCours*, section*, professeur) ChoixCours(matricule*, noCours*, section)

 Create table ChoixCours(

Page 29: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

29

matricule char(3) NOT NULL, noCours char(6), section number(1), constraint cp_choix_cours primary key (matricule, noCours), CONSTRAINT fk_choix_cours_cours_horaire FOREIGN KEY(noCours, section)

REFERENCES CoursHoraire(noCours, section);                 L’ajout d’un choix de cours particulier  sous‐tend une  référence à un cours‐horaire qui doit exister dans la base. La clé étrangère dans un tuple est soit entièrement composée de nulls, soit partiellement ou entièrement valuée,  i.e. qu’au moins un des attributs a une valeur.  

7.6 Implémentation des contraintes structurelles avec le langage SQL‐92  Les définitions ci‐dessus  sont partiellement muettes en ce qui concerne  les contraintes structurelles du MCD. Ceci est particulièrement important pour les tables avec des clés étrangères. En effet, la suppression dʹun tuple dans une table parent nʹest pas neutre par rapport à la table enfant. Quʹarrive‐t‐il aux tuples dépendants lors de la suppression ou de la mise à  jour de la clé du tuple parent ? Reprenons lʹexemple du modèle simple ci‐dessous dont le schéma correspondant est constitué de deux relations : Ville et Province. Les contraintes du modèle  imposent une  suppression automatique des villes associées lorsque la province est supprimée.                       

Figure 7.12 Le modèle équivalent UML est le suivant :       

Province(nomP*, populationP) Ville(nomV*, populationV, dateCreationV, nomP)

Figure 7.13  

EstDansVille 

nomV* populationV dateCreationV

Province nomP* populationP 

(1,1) (1,n)

Ville nomV* populationV dateCreationV

Province nomP* populationP 

11..* EstDans

UML

Page 30: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

30

Actions référentielles en SQL Le sort réservé aux tuples dʹune table enfant lors dʹune mise à jour ou dʹune suppression dans  la  table parent   est variable selon  les spécifications de  la  table enfant. Ces actions dites référentielles dans la proposition SQL‐92 sont  formulées en lien avec une action de mise à jour dans la table parent et de ses effets au niveau de la table enfant. Elles ne sont pas toutes l’objet d’une implémentation dans Oracle.  CASCADE  : Une modification (UPDATE ou DELETE) de tuples dans la table parent se propage  aux  autres  tables.  Ainsi,  une  suppression  dʹun  tuple  parent  entraîne  la suppression des tuples correspondants dans  la table enfant. Une modification de  la clé dʹun tuple de la table parent entraîne la suppression des tuples préalablement associés à lʹancienne clé.  NO  ACTION  :  Si  une  modification  (DELETE  ou  UPDATE)  viole  la  contrainte référentielle, la modification est refusée ou défaite (action par défaut);  SET NULL : Lorsque le tuple parent est supprimé (DELETE), lʹattribut de la clé étrangère devient NULL dans la table enfant. Il en est de même pour une modification (UPDATE) de la clé dans la table parent.  SET DEFAULT : Le tuple de la table parent est supprimé (DELETE)   et la clé étrangère des tuples de la table enfant est mise à une valeur définie par défaut lors de la création de la table enfant.   Avec  lʹexemple  ci‐dessous,  les  tables  sont  créées  en  SQL‐92  de  façon  à  respecter  les contraintes structurelles : 

CREATE TABLE Province( nomP char varying(45) NOT NULL PRIMARY KEY, populationP number(8) NOT NULL);

 N.B. Le type char varying() est le pendant SQL‐92 de varchar() et varchar2() deux types couramment implémentés dans les SGBD Oracle, DB2 et Informix.  

CREATE TABLE Ville( nomV char varying(50) NOT NULL PRIMARY KEY, populationV number(8), dateEntree DATE, nomP char varying(45) NOT NULL, CONSTRAINT fk_ville_province FOREIGN KEY(nomP) REFERENCES Province(nomP) ON DELETE CASCADE [ON UPDATE CASCADE] [ON DELETE SET NULL] );

 Si une province doit être supprimée de la table, tous les tuples de Ville qui le référencent sont aussi supprimés. De même, si une ville disparaît de  la carte administrative dʹune 

Page 31: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

31

province, elle ne peut pas rester dans la base avec une clé  composée de l’indicateur null. Les autres actions entre crochets ne sont pas  toujours  implémentées : si une province change de nom, tous les tuples dans Ville qui font référence à cette province par la clé étrangère sont modifiés  pour  refléter  le  changement  de  nomP.  La  troisième  option  permet  de supprimer un tuple référencé ; dans ce cas la clé étrangère des tuples de la table enfant sont mise à null. 

Autres langages de données Il existe quelques implémentations plus conviviales du langage algébrique (et du calcul relationnel)  qui  permettent  la  fouille  d’une  base  de  données  et  la  transmission  des résultats à l’utilisateur.  Voici quelques langages de requête implémentés : ‐ QUEL : langage convivial implémenté à partir du calcul de tuple (Berkeley University); ‐ QBE : langage basé sur le calcul de domaine (IBM‐IMF, crd et FORMS‐Oracle); ‐ RENDEZ‐VOUS : langage quasi naturel (IBM); ‐ CUPID : algèbre relationnelle utilisée par le biais de pictogrammes (IBM).  Depuis leur création, quelques‐uns de ces langages sont tombés dans l’oubli, parfois en raison de lʹabsence dʹune technologie appropriée ‐ CUPID, LAGRIF et RENDEZ‐VOUS. La  puissance  de  la  technologie  actuelle  permettra  éventuellement  à  de  nouveaux langages graphiques ou de type langage naturel de voir le jour et de trouver un créneau d’applications. 

7.7 Requête SQL Une requête SQL3, 4, 5 est un  énoncé de recherche, composé de clauses identifiées par le mot clé Select et dont lʹordre logique dʹexécution est indiqué ci‐dessous par lʹentier placé entre  parenthèses.  La  dernière  opération  est  le  tri  des  tuples  de  la  réponse. Concrètement, l’ordre d’exécution sera celui correspondant au plan d’exécution optimisé  et généré par le moteur SGBD. Voici la structure d’une clause SELECT complète :  (5) SELECT sélection des attributs (alias) de projection.  (1) FROM pour nommer  la ou  les relations en  jeu dans  le calcul de  la réponse. Ces relations sont des vues, des relations de base ou une expression de table. (2) [WHERE] prédicat  (formulé au besoin avec une sous‐requête) de sélection ou de jointure. (3) [GROUP BY ]  pour grouper les tuples selon des attributs. (4) [Having] pour  filtrer  les  groupes  à  retenir  sur  la  base  dʹun  prédicat    sur  le groupe. (6) [ORDER BY] pour trier les tuples de la réponse sur les attributs (incluant les alias) présents dans la réponse calculée.  Le format général de la requête comprend deux parties obligatoires : SELECT et FROM . Les  crochets  encadrant  les  autres  indiquent  qu’elles  sont  facultatives.  L’ordre 

Page 32: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

32

d’exécution  d’une  requête    sous‐tend  celui  de  l’exécution  de  l’expression  algébrique correspondante. Le début est marqué par l’étape (1), pour se terminer par l’étape (6), soit le  tri du  résultat. Les opérations pour  la mise à  jour de  lʹextension d’une  relation sont implémentées sous forme dʹordres DML dont la syntaxe est relativement simple :  

INSERT INTO <relation> VALUES (... )  ; UPDATE <relation> SET <attribut> = valeur  WHERE <prédicat de sélection> ; DELETE <relation> WHERE <prédicat de sélection>;

 Les  commandes de mise  à  jour  (UPDATE  et DELETE)  sous‐tendent  au préalable une recherche avec le prédicat formulé dans le WHERE, suivie de la modification des tuples trouvés. Les clauses DDL et DCL sont couramment ajoutés aux clauses du DML pour former un langage de données complet au sens de la norme ISO.  

Modèle dʹexécution d’une requête Lʹexécution logique de la requête débute par le calcul des sous‐requêtes qui sont définies par la clause FROM et/ou WHERE, et cela pour obtenir une table ou un scalaire. Dans le cas  d’une  sous‐requête  corrélée,  i.e.  qui  contient  un  prédicat  faisant  référence  à  un attribut de  la  requête parent,  elle devra  être  recalculée pour  chaque  tuple  sélectionné dans  la table parent, soit celle formulée par la clause FROM.                    Lʹexécution  de  lʹexpression  de  table  annoncée  dans  le  FROM  est  effectuée  en  filtrant immédiatement chaque tuple de la table par le prédicat . En ce faisant, on évite le calcul inutile dʹau moins une table intermédiaire qui peut devenir très volumineuse. Ce calcul peut faire référence à plusieurs tables de base si le From sous‐tend une jointure.  S’il  y  a  lieu,  les  tuples  de  la  table  intermédiaire  sont  regroupés  par  lʹexpression  du GROUP BY et les fonctions dʹagrégation sont exécutées sur chaque groupe formé.  Les colonnes du SELECT sont retenues dans la réponse transmise par lʹexécution dʹune projection.  Un tri éventuel est effectué (ORDER BY) à la fin des calculs et juste avant de transmettre la réponse au client.  N.B. Le prédicat annoncé par le WHERE peut avoir plusieurs formes : condition simple, un prédicat d’inclusion avec une ou des sous‐requêtes emboîtées, ou un prédicat vide ou absent toujours évalué à VRAI. Toute la puissance discriminante de la requête s’exprime par ce prédicat de sélection formulé dans le WHERE.  Lʹordre logique dʹexécution des clauses est tel que les alias des relations et des attributs ne sont  pas connus ou visibles quʹaprès les étapes où ils sont définis dans l’exécution de la  requête. Ainsi, un  alias d’attribut dans  la  clause SELECT  (étape  5) peut  être utilisé dans la clause ORDER BY (étape 6) pour ordonner les tuples de la réponse, parce qu’il a 

Page 33: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

33

été défini avant. Il est donc visible ou connu par lʹexécuteur au moment du tri. Toutefois, le même alias ne peut pas être utilisé dans le WHERE, car il est encore inconnu à lʹétape 2 de  lʹexécution de  la requête. Il sʹagit dʹun ordre  logique dʹexécution dont  le plan sera définitivement établi par lʹoptimiseur. Il est possible que les opérations soient formulées différemment dans un plan optimisé, mais le résultat devra être le même.  

Grammaire du SELECT (SQL‐92)  La  grammaire  SQL‐92  (englobant  SQL‐89)  de  la  clause  SELECT  est  représentée  sous forme dʹun graphe.  Les conventions utilisées dans un tel graphe sont les suivantes : Les mots clés et les symboles du langage sont de préférence en lettres majuscules   

SELECT liste-non-vide-attributs-ou-fonctions FROM liste-non-vide-de-relations WHERE prédicat simple-complexe-ou-sous-requête;

 Le souligné dʹun mot clé indique la valeur par défaut:  ORDER BY ASC .  Le  libellé  en minuscules  et  avec une majuscule  comme première  lettre utilisé dans  le FROM  représente le nom du schéma de la vue, de la relation ou de lʹattribut.                                   Graphe de la grammaire du SELECT                    

FROM

schéma vue

(sous‐requête)

snapshot

table

WHERE

@lien 

FROM

(1) 

(2)

condition

CONNECT BY condition

STARTWITH condition

GROUP BY expressionHaving condition

(2)  (3)

Page 34: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

34

                         

 Figure 7.14 

Expression SQL Une expression est constituée dʹune combinaison d’attributs, de constantes, de fonctions, d’opérateurs et dʹopérandes qui sont évaluables pour donner une  table ou un scalaire.  Le type du résultat de lʹexpression est défini. Le résultat peut être aussi un null lorsquʹun de ses opérandes est  un nul.   Par exemple,  les expressions suivantes sont correctes : 

Expression Type de la réponse CONCAT(ʹMme ʹ, nom)  Chaîne 

age_actuel = 35 + age  Entier ou null si âge est null total = AVG(prix) * 3.6    Réel total = AVG(prix) * 3.6    Réel salaire = (salaire * .15) + salaire  Réel res = (67* 5) /2  Réel  

SELECTUNION

UNION

INTERSECT 

MINUS 

(4)(3) 

,

,

ORDER 

FOR UPDATE

OF

NOWAIT

DESC

ASCposition

expression

colonne

table

vue

(4) 

Page 35: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

35

Dans  ce  dernier  exemple,  si  le  salaire  dans  un  tuple  est  null,  alors  le  résultat  de lʹévaluation de l’expression sera aussi l’indicateur null. Une expression peut être utilisée partout où peut apparaître un attribut ou une constante.  

Condition Une condition est un prédicat dont lʹévaluation fournit une valeur booléenne : TRUE ou FALSE. Avec SQL‐92  lʹévaluation peut  fournir une  troisième valeur, soit UNKNOWN. Elle est formée dʹune formule logique ou dʹun prédicat dʹinclusion dans un ensemble qui peut être énuméré ou calculé par une sous‐requête. Exemples de conditions  placées dans la clause WHERE :                                   

SELECT ville FROM Employe WHERE nom in ('Jacques', 'Laurence', 'Marie-Claude')

--énumération L’ensemble énuméré est calculé une seule fois par la sous‐requête. 

SELECT ville FROM Employe WHERE nom IN (SELECT nom FROM Etudiant WHERE age > 25); -- prédicat d’inclusion avec calcul par sous-requête)

Sélection (ou restriction de lʹextension) Les sélections ci‐dessous utilisent  la base de données BD1. A chaque  fois quʹun même attribut apparaît dans plus dʹune relation, il faut le préfixer par le nom de la relation et cela,  pour  éviter  toute  ambiguïté  pour  lʹinterpréteur.  Pour  quelques  clauses  SQL, lʹexpression  algébrique  correspondante  sera  formulée  pour  illustrer  le  passage  de l’algèbre au langage SQL. 

7.8 Expressions algébriques et requêtes SQL  Toute requête SQL correspond à une expression algébrique et vice versa.  Lister les articles vendus jusqu’à ce jour. L’expression algébrique correspondante est une projection d’une table de base.    

Πarticle (Ventes)

                                   En SQL, cette projection se traduit par la liste des attributs de la projection placée dans la clause SELECT.    

SELECT article FROM Ventes;

La projection supprime  les doublets de  la réponse, tandis que  la cluse SQL SELECT ci‐dessus ne le fait pas à moins dʹy ajouter le mot clé DISTINCT.   

SELECT DISTINCT article FROM Ventes;

Page 36: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

36

b) Lister  les  ventes  (avec  tous  leurs  attributs)  effectuées  jusqu’à  ce  jour  . Une  simple projection fournit la réponse demandée. 

Πnom,article, qte (Ventes)

 La projection de tous les attributs peut s’exprimer par la liste des attributs ou l’astérisque placé dans la clause SELECT. 

SELET * FROM Ventes;

 Lister le nom des acheteurs de l’article nommé ‘a2’ : 

Πnom(σVentes.article = ‘a2’(Ventes))

 SELECT nom FROM Ventes WHERE Ventes.article ='a2';

 /*(présume un type varchar2 pour article)*/

Ventes :  nom*  article*  qte*   Serge  a1  3   Ted  a2  5   André  a1  2   Serge  a2  4   Jocelyn  a1  2   Serge  a3  4   Valérie  a7  3 

  Lucie  a7  2   Serge  a5  3   Serge  a7  5   Christine  a3  6   Serge  a1  7 

Figure 7.15  d) Lister le nom des acheteurs de l’article ‘a2’ avec une quantité supérieure ou égale à 3 . Lʹexpression algébrique pour calculer cette réponse comprend une sélection exécutée en premier, suivie dʹune projection pour ne conserver que les attributs demandés. 

Πnom(σVentes.article =‘a2’and qte >= 3(Ventes))

     Cette expression est convertie en SQL très facilement  : le prédicat de sélection apparaît dans le WHERE et la liste des attributs de projection est ajoutée au SELECT.     

SELECT DISTINCT Ventes.nom FROM Ventes WHERE article = 'a2' and qte >= 3;

Page 37: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

37

La condition peut être formulée avec plusieurs opérateurs de comparaison : =, !=, > =, <=, <,  >  et des prédicats du  langage  comme  les  suivants  :   BETWEEN  x  b1 AND  b2,  IN, LIKE,  IS NULL,  IS NOT NULL. De même,  lʹexpression du prédicat peut être  formulée avec plusieurs attributs.  Exemple d’un prédicat conjonctif : … WHERE nom = ʹliseʹ and age = 25  Ce prédicat est équivalent au suivant : … WHERE  (nom, age) IN (ʹliseʹ, 25)   e) Lister le nom des acheteurs qui ont acheté entre 3 et 7 unités dʹun article. 

Πnom(σqte between 3 And 7(Ventes))

 SELECT nom FROM Ventes WHERE qte BETWEEN 3 AND 7; --les bornes sont incluses

 f) Lister  les acheteurs dont  le nom commence par  la  lettre  ʹSʹ au moyen de  l’opérateur d’appariement LIKE .          

SELECT nom FROM Ventes WHERE nom like 'S%';

 NB : Le caractère générique % représente une chaîne composée de 0 ou n caractères qui vient après le S.  Autres  formes possibles  : %S, %S%S, etc. Ce caractère spécial est  très utile si  la chaîne spécifiée dans  le  schéma  est de  longueur  constante  et  si  la  chaîne  recherchée  est plus petite. Les caractères spéciaux peuvent être aussi combinés.  Il est aussi possible de prendre en compte  les caractères spéciaux comme des  littéraux intégrés à  la chaîne par lʹentremise du caractère dʹéchappement annoncé par  le mot clé ESCAPE.    

SELECT nom FROM Ventes WHERE nom LIKE ‘Sans\_Chagrin’ ESCAPE '\' ;

N.B. Le caractère  ʹ\ʹ précède un caractère spécial  (soit  le _) pour    indiquer au système quʹil doit être  lu comme un  littéral. Finalement, dans  la version 10g et  les suivantes  les expressions régulières sont incluses et traitées lors de la recherche par Oracle.         g) Lister les articles achetés par les personnes dont le nom est Deschesnes, Descheynes, Deschaines et Descheines. 

Page 38: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

38

SELECT article FROM Ventes WHERE nom LIKE ‘Desch__nes’;

** Notez  que  le  caractère  _  (souligné)  représente  un  caractère  quelconque  dans  une position fixe de la chaîne.     Voici une autre formulation du prédicat :  

SELECT ARTICLE FROM VENTES WHERE NOM LIKE ‘Desch’||‘%nes%’;

Le deuxième % est nécessaire si l’attribut nom est déclaré CHAR(w) et non de longueur variable comme c’est le cas avec le type VARCHAR2(w).  h)  Lister  les  articles  en  inventaire  et  dont  le  prix  de  vente  est  entre  10  et  20  $ inclusivement : 

SELECT article FROM Inventaire WHERE prixVente Between 10 and 20;  ‐‐ Bornes incluses 

      À noter que  la négation du prédicat se  formule simplement par  le NOT BETWEEN et permet de  tester  lʹexclusion de  la valeur de  lʹattribut de  chaque valeur de  lʹintervalle. Pour que le prédicat soit vrai il faut que la borne inférieure soit plus petite que la borne supérieure.  Voici dʹautres formulations correctes, mais qui seront transformées par  lʹoptimiseur du SGBD : ‐ avec le prédicat  OR :  

prixVente = 10 or prixVente = 11 Or ...prixVente = 20  Après transformation : prixVente BETWEEN 10 And 20  ‐ avec la négation :  

NOT (prixVente = 10 or prixVente = 11 or ...prixVente = 20)

 Après transformation : prixVente NOT BETWEEN 10 and 20  i) Lister les articles achetés par les clients Serge, Valérie et Ted : 

SELECT article FROM Ventes WHERE nom IN ('Serge','Valérie','Ted');

 Le même prédicat peut être formulé sous la forme d’une disjonction d’égalités : 

Page 39: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

39

(nom = 'Serge' or nom = 'Valérie' or nom = 'Ted')  Le NOT permet aussi de  tester  lʹexclusion ou  lʹabsence de nom parmi  ceux de  la  liste énumérée.  Avec  la présence du NULL dans  la  liste énumérée,  le prédicat est évalué correctement avec  les    constantes  énumérées,  mais  ne  sélectionne  pas  les  tuples  dont  le  nom  est renseigné par l’indicateur  null.  

SELECT article FROM Ventes WHERE nom IN ('Serge', 'Valérie', null);

                                  La  recherche  des  ventes  à  un  client  inconnu  est  faite  inutilement,  car  le  nom  est  un attribut primaire  qui ne peut pas être un  null  lorsque la clé primaire est spécifiée dans le schéma de la table.   Suppression des doublets dans une réponse Les  tuples  identiques  de  la  réponse  peuvent  être  supprimés  par  une  variante  de  la sélection soit le SELECT DISTINCT. L’ordre dʹaffichage des tuples sélectionnés peut être aussi spécifié par la clause ORDER BY.  j) Lister les acheteurs ayant des noms différents.  

SELECT DISTINCT nom FROM Ventes;

 Quel est le résultat de la clause ci‐dessous?  

SELECT DISTINCT nom, article FROM Ventes;

 Les  doublets  sur  les  attributs  nom  et  article  (en  tant  que  tuple  de  la  réponse)  sont supprimés.              k) Lister en ordre alphabétique croissant de nom,  les  transactions de vente concernant les articles achetés en quantité plus grande que trois.    

SELECT article, nom, qte FROM Ventes WHERE qte > 3 ORDER BY nom ASC;

 Par défaut, la relation de la réponse constitue un seul ensemble de tuples trié en fin de calcul  selon  l’ordre  croissant  de  nom  (option  ASC).  L’option  DESC  permet  un  tri descendant  sur  le  ou  les  attributs mentionnés  dans  la  clause  ORDER  BY.  L’attribut 

Page 40: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

40

utilisé  comme  critère  de  tri  doit  être  obligatoirement  dans  la  table  obtenue  par  la projection (exprimée par la clause SELECT).                                    

7.9 L’indicateur null et lʹévaluation dʹune condition Un  attribut  peut  avoir  un  indicateur  de  l’absence  d’une    valeur,  le  null  (6)  si  la spécification du schéma de la table l’autorise explicitement (NULL et NOT NULL). Cet indicateur peut être aussi défini par  la clause DEFAULT IS NULL  lequel est attribué à un  attribut.  Comme  le  traitement  des  indicateurs  nulls  est  plus  complexe,  il  est préférable  de  privilégier,  lorsque  cela  est  possible  au  regard  de  la  sémantique,  la contrainte NOT NULL pour un attribut. La norme ISO définit le traitement suivant pour le NULL dans les expressions de comparaison :    a) Un NULL n’est  jamais égal à une valeur quelconque y compris à  lui‐même (0, blanc ou NULL) puisque le NULL n’est pas une valeur du domaine.   Par exemple :  

SELECT * FROM Employe WHERE salaire = null ;    ‐‐ FALSE y compris lorsque salaire est inconnu 

 Les  employés  dont  le  salaire  est  inconnu  ou  absent  ne  sont  par  retrouvés  avec  cette formulation. En effet,  l’indicateur null n’est pas une valeur du domaine, donc ne peut pas être l’objet d’une comparaison.                                b) Un NULL n’est jamais différent d’une autre valeur. En effet, parce que le NULL n’est pas une valeur du domaine. 

SELECT * FROM Employe WHERE salaire <> 25000; --FALSE pour les tuples avec salaire NULL)

 c) Un NULL n’est pas plus petit ou plus grand ni égal à une valeur.  

SELECT * FROM Employe ; WHERE salaire < 19 000 ‐ ‐ (FALSE pour les tuples dont le salaire est NULL) 

 d) Le résultat des fonctions dʹagrégation (sauf exception) n’est pas modifié par les nulls des  tuples, pour  autant  que  certains  non  nulls  existent dans  le  lot. L’exception  est  la fonction de  comptage Count() qui peut  ou pas prendre  en  compte  les valeurs nulles. Ainsi, Count(*) compte les tuples et donc considère le comptage des lignes (tuples) sans égard à  la présence des nulls. Par contre,  le Count(age) ne compte que  les valeurs non nulles  pour  cet  attribut.  Voici  dʹautres  exemples  singuliers  utilisant  le  null  dans  le prédicat. Ici, il y aura impression de la constante si le prédicat est évalué à VRAI. 

Page 41: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

41

 SELECT 'F' FROM DUAL WHERE 'Y' = NULL; -- aucun résultat !

SELECT 'F' FROM DUAL WHERE NULL = NULL; -- aucun résultat !

SELECT 'F' FROM DUAL WHERE NULL IN ('A','B',NULL); -- aucun résultat !

SELECT 'F' FROM DUAL WHERE'a' IN ('b', null); -- aucun résultat

Figure 7.16                                        Par contre, l’expression avec le prédicat IS NULL ou IS NOT NULL permet de traiter les tuples ayant l’indicateur de valeur nulle. 

SELECT nom FROM Client WHERE credit IS NULL;

 Cette expression donnera le nom des clients dont le crédit nʹest pas encore  déterminé ou inexistant. 

Exceptions dans le traitement du null Il  y  a  certaines  exceptions  dans  le  traitement  de  l’indicateur  d’absence  de  valeur,  le NULL :                               a) Fonction DECODE :  DECODE(note,'A','excellent','B','tres_bien','C','bien',NULL,'échec') Les tuples dont la note est ʹAʹ sont lʹobjet dʹun remplacement de cette note par la chaîne ʹexcellentʹ et si la note est NULL , elle est remplacée par la constante de chaîne ʹéchecʹ.  b) Dans le GROUP BY  

SELECT matricule, age FROM Employe GROUP BY matricule, age; -- null dans certains tuples.

Le groupement tiendra compte de la valeur NULL pour les attributs du GROUP BY.  c) Avec le qualificatif DISTINCT :

SELECT DISTINCT qte --les nulls sont distincts; FROM Ventes;

d) Avec les opérateurs UNION, MINUS et INTERSECT qui tiennent compte des nulls. 

Prédicat IS NULL et IS NOT NULL de SQL‐92 Ce prédicat est proposé dans  la norme SQL‐86 afin de  tester si une expression, qui est très souvent formée dʹun seul attribut, est évaluée à NULL lors de son instanciation par un tuple. 

Page 42: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

42

SELECT * FROM Ouvrier WHERE age IS NULL ;

Tous les tuples de Ouvrier dans lequel lʹâge est inconnu (ou null) seront sélectionnés.                                                                                               La norme SQL‐92 a étendu cette notion pour y  inclure  le  test de plusieurs attributs au moyen du  constructeur de  tuple. Ce dernier est de degré 1  sʹil est  constitué dʹun  seul attribut, tandis quʹil a un degré supérieur lorsquʹil y a  plusieurs attributs. 

SELECT * FROM Ouvrier WHERE(noAtelier, age) IS NULL; --expression de degré 2

 Lorsque  lʹexpression  du  prédicat  contient  deux  attributs,  elle  est  de  degré  2.  Elle  est TRUE  si les deux attributs ont une valeur NULL dans un même tuple.   

Degré 1  E IS NULL  E IS NOT NULL  NOT E IS NULL  NOT E  IS NOT NULL Expression ‐‐> (E)         si E = NULL  TRUE  FALSE  FALSE  TRUE AUCUN NULL dans E  FALSE  TRUE  TRUE  FALSE 

Degré > = 2  E IS NULL  E IS NOT NULL  NOT E IS NULL  NOT E  IS NOT NULL Tous NULL dans E  TRUE  FALSE  FALSE  TRUE Quelques NULL  FALSE  FALSE  TRUE  TRUE Aucun NULL  FALSE  TRUE  TRUE  FALSE 

Figure 7.16a  Par  contre,  si  lʹon  veut  sélectionner  les  ouvriers  dont  lʹun  des  deux  attributs  de l’expression est inconnu, il suffira de faire appel à la négation du prédicat.     

SELECT * FROM Ouvrier WHERE NOT (noAtelier, age) IS NULL;

 Cette clause est équivalente à la suivante :  

SELECT * FROM Ouvrier WHERE noAtelier IS NULL or age IS NOT NULL;

La  norme  SQL‐92  introduit  aussi  de  nouveaux  prédicats  du  genre  IS  TRUE,  IS UNKNOWN  et  IS FALSE.  Ils permettent de  tester  la valeur de vérité dʹune  condition pour chaque tuple dʹune table. 

SELECT * FROM Usine WHERE (production >200 And ville = 'Québec') IS UNKNOWN;

Page 43: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

43

 Les usines dont le volume de production ou la ville sont inconnus seront sélectionnées. En effet, si un des attributs est NULL, la condition est donc évaluée aussi à NULL et le prédicat qui vérifie la valeur de vérité UNKNOWN est donc TRUE.    

Plus  de détails concernant la notion dʹexpression SQL  Une expression fournit, après évaluation, une valeur (et éventuellement le NULL) dʹun type  donné. Une  expression,  notamment  en  SQL‐92,  est  formée  de  divers  éléments  ‐ constantes,  variables,  fonctions  ‐  qui  peuvent  apparaître  dans  les  clauses  SELECT  et WHERE.  Une  expression  peut    être  aussi  combinée  avec  dʹautres    au  moyen  des opérateurs  arithmétiques,  logiques  et  de  chaîne.  Considérons maintenant  la  base  de données suivante composée de quatre tables normalisées :  Atelier (noAtelier*, chef, site, debit, volume, classe, noUsine,specialite, dateOuverture) Specialite (specialite*, classe, description) Usine (noUsine*, libelle, adresse, ville, codePostal, production) Ouvrier (nas*, nom, age, dateEmb, noAtelier)  1‐ Expression incluant un littéral Une expression peut être formulée avec une constante numérique, une chaîne, une date, un attribut, un temps et une estampille. Voici quelques exemples de constantes de types divers :   entiers : ‐97, 45, +67  nombre décimal : 45.6, ‐34.567 virgule flottante : 1.56E2  chaîne : ʹprogrammation à objetsʹ chaîne UNICODE : ʹGʹæÕÕʹ  nombre hexadécimal : XʹFFFFʹ date : ʹ1998‐12‐25ʹ  temps : ʹ13:45ʹ ou 13.45 ou ʹ1:45 PMʹ estampille : ʹ2000‐01‐06‐13:45:00:00000’   

Figure 7.16b     SELECT volume * 1.5 FROM Atelier WHERE debit <= 500 * .6;

L’expression arithmétique est évaluée une fois au début du traitement de la requête.  2‐ Expression incluant un nom dʹattribut avec ou sans opérateur La plus simple des expressions est un attribut seul, tandis que  la transformation d’une valeur ou d’un attribut par  les  fonctions et  les opérateurs  fournit aussi une expression qui est plus complexe.     Exemples d’expression avec les attributs :  

volume  nom || ʹ  ʹ || prenom Usine.production  volume * prixUnitaire 

 

Page 44: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

44

SELECT volume * 1.5 FROM Atelier Where debit > volume * .2 ;

 Une expression complexe est construite en combinant plusieurs expressions au moyen des opérateurs suivants : ‐ Opérateurs arithmétiques: +, ‐, *, /;   Exemple évaluée pour chaque tuple testé  : (tarif * heures * 52) / (1.8 * bonus) - Opérateur de concaténation : || Exemple : nom || '--' || adresse /* insertion de deux tirets  3‐ Expression incluant un appel de fonction interne et externe Tout  appel  de  fonction  est  une  expression  dont  lʹévaluation  sous‐tend  lʹexécution  du corps  de  la  fonction.  Une  fonction  peut  être  aussi  combinée  avec  les  opérateurs arithmétiques et de chaîne pour retourner une valeur typée.  

LENGTH(adresse || ville) SUBSTR(code_postal, 1,3) Trunc(salaire * 1.2, 0) Trunc(date_in, 'YYYY' )

Round(salaire,0)--arrondi

SELECT Concat(libelle||adresse) FROM Usine WHERE SUBSTR(codePostal, 1, 3) = 'G1K';

 Une  expression  peut  comprendre  une  fonction  dont  un  argument  peut  être  aussi  un appel de fonction.  Exemple dʹemboîtement de fonctions : 

SELECT U.libelle, U.adresse, U.noUsine FROM Atelier A, Usine U WHERE A.noUsine = U.noUsine and LENGTH(SUBSTR(site,1,(INSTR(site,'ing')))) = 5;<--

 4‐ Expression avec une constante de type Date Une expression dans  laquelle une constante entière est ajoutée à une date  fournit une autre  date.  Souvent,  l’unité  par  défaut  pour  un  entier  ajouté  à  une  date  est  le  jour (DAYS). Les autres unités ne sont pas toujours implémentées. Par exemple, Oracle offre que l’unité DAYS.                            Exemples d’unités de date : 

   DAYS   MONTHS   HOURS   MINUTES 

 SELECT DateE + 3 DAYS /* ajout des jours à une date */

Page 45: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

45

FROM Ouvrier WHERE TRUNC(DATE_E,'YY')BETWEEN TRUNC(1992,'YY') And TRUNC(1998,'YY');

 La  fonction TRUNC() permet de  tronquer  la date  conformément au masque  et  enlève toutes les autres parties incluses dans la date.   Dans  l’exemple  suivant,  les  embauches  entre  92  et  98  sont  affichées  avec  une  date augmentée de 30 mois. 

SELECT DateE + 30 MONTHS /* date augmentée de 30 mois */ FROM Ouvrier WHERE To_Number(To_Char(DATE_E,'YY')) Between 92 And 98;

 5‐  Expression incluant une variable hôte Une  variable  hôte  (dont  la  valeur  est  fournie  par  une  variable  du  langage  de programmation) dans une clause SQL est déclarée dans le contexte d’un programme de type L3G    (ex.: C, C++,  Java  et  elle  est précédée du  caractère deux points  ( :  )  comme délimiteur de variable hôte. Exemple (:x) : 

SELECT volume + :x FROM Atelier;

 Le  caractère deux points dans :x  indique  à  lʹinterprète  SQL  quʹil  sʹagit dʹune  variable hôte et que la valeur de cette variable est accessible en lecture et en écriture.  6‐ Expression  incluant une variable dʹenvironnement ou une  fonction particulière sans argument.  Voici quelques fonctions sans argument : CURRENT DATE; CURRENT SERVER USER,  USER implémentées dans certains SGBD : 

SELECT A.volume * 1.5 FROM Atelier A, Ouvrier O WHERE A.noAtelier = O.noAtelier and O.dateEmb = CURRENT DATE;

7‐ Expression incluant une structure CASE (prévu dans SQL‐92) Cette  clause CASE  est  une  expression  qui  fournit  après  évaluation,  une  constante de type chaîne de caractères ou numérique.       

CASE classe WHEN SUBSTR(classe, 1,1) = 'A' THEN 'excellent' WHEN SUBSTR(classe, 1,1) = 'B' THEN 'très bon' WHEN SUBSTR(classe, 1,1) = 'C' THEN 'bon' END;

Page 46: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

46

Exemple : SELECT noSpecialite,

CASE noSpecialite WHEN noSpecialite = 1 THEN 'fraisage'||'aluminium' WHEN noSpecialite = 2 THEN 'perçage du fer' WHEN noSpecialite = 3 THEN 'tournage acier' ELSE 'autres opérations'

END, volume FROM Atelier WHERE site = 'Québec';

Sous‐requête à valeur unique  (scalaire) Lʹévaluation  dʹune  sous‐requête  qui  donne  une  seule  valeur  typée  est  aussi  une expression. Dans  lʹexemple  ci‐dessous,  la  sous‐requête  est  évaluée dès  le départ  et  sa réponse,  composée obligatoirement dʹun  seul numéro d’atelier,  est un  scalaire qui  est substituée à la sous‐requête avant de poursuivre lʹévaluation. 

SELECT nom, dateEmb, noAtelier FROM Ouvrier WHERE noAtelier = (SELECT noAtelier FROM Atelier WHERE site = 'Québec');

Tri des données du résultat La clause ORDER BY est exécutée à la toute fin du calcul et permet dʹordonner les tuples de la réponse selon un ou plusieurs attributs ou alias utilisés dans le SELECT. 

SELECT nom, ville FROM Empl WHERE age >20 ORDER BY nom, ville ASC ;

 Tri avec un alias :

SELECT noVente, montant *.15 [as] taxe FROM Ventes WHERE mois = 'juin' ORDER BY taxe DESC; <-- tri décroissant par alias

7.10 Conversion de type dans SQL :  CAST (SQL‐92) Lʹopérateur CAST() sous‐tend une opération de  transposition du  type dʹune valeur ou celui d’un  résultat ou dʹune expression  (y compris  le NULL) en celui dʹun autre  type. Comme SQL est un langage typé, lʹopérateur CAST() permet plus de souplesse dans la formulation des expressions. Par exemple, lʹajout dʹun attribut numérique à un autre de type chaîne est autorisé à la seule condition que la chaîne soit au préalable l’objet d’une conversion  de  type.  Il  n’est  possible  de  faire  une  conversion  que  pour  changer  les caractéristiques dʹun même type.    Exemples : CAST (classe as INTEGER) -- le type chaîne de l’attribut classe est converti en entier.

Page 47: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

47

                       Exemple :   Select classe,      

CASE classe  WHEN CAST(classe as INTEGER) = 1 Then . . . ;

 La transposition suivante permet de modifier les caractéristiques du type de l’attribut : 

CAST (nom as char(45)) pour modifier la longueur de la chaîne; CAST (volume as decimal(2,4)--modifie nb chiffres après point décimal

 SELECT U.production, cast(A.debit as integer) * 3 FROM Usine U, Atelier A WHERE Cast(ville as varchar2(25))='Québec'And U.noUsine = A.noUsine;

En général, les conversions automatiques sont possibles pour plusieurs changements de type , notamment dʹun  type numérique  vers  tout  autre  type numérique. Toutefois,  la conversion signale une erreur lorsquʹune valeur numérique cible a une taille insuffisante pour  exprimer  totalement  la valeur de  la  source. Cependant,  si  lʹespace ne permet de loger  que  les  chiffres décimaux  avant  le point décimal,  il  y  aura  alors un  arrondi du nombre  converti.  Les  conversions  possibles  pour  SQL‐DB2‐V2  sont  présentées sommairement  dans  le  tableau  ci‐dessous. Des  conversions  similaires  sont  autorisées avec Oracle et les autres systèmes.  

type de la source  type de la cible char, varchar, clob, long varchar  char, varchar, clob, long varchar char, varchar  char, varchar date, time, timestamp  char, varchar date  date time  time blob  blob timestamp  date, time, timestamp graphic, vargraphic, long vargraphic  graphic, vargraphic, long vargraphic smallint, integer, decimal, double  smallint, integer, decimal, double 

Figure 7.16c  La  conversion  est possible  selon  le  tableau  en passant par  le  chemin date  ‐>  char. Le même  résultat  peut  être  obtenu  par  la  fonction  TO_CHAR()  fournie  par  les  diverses implémentations de SQL, notamment celle dʹOracle.  Par exemple : la conversion de lʹannée dont le type est Date : la conversion date vers char est possible avec la clause : CAST (annee as char(8)).

SELECT Cast(nom as char(15)) FROM Ouvrier;

Page 48: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

48

Supposons  que  la  date  dʹouverture  de  lʹatelier  est  de  type  Date  et  que  celle  de lʹembauche dʹun ouvrier est de  type chaîne de caractères. Pour  faire une  jointure entre les deux tables Atelier et Ouvrier, il faut effectuer une conversion de type avec lʹattribut de jointure dateEmb.  

SELECT O.nom, A.noAtelier FROM Atelier A, Ouvrier O WHERE A.dateOuverture = CAST(O.dateEmb as Date); SELECT CAST(nom as varchar(50) [as] nomFamille FROM Ouvrier WHERE age < 30;

 Cas spécial : Compatibilité de deux structures de table dans une opération binaire telle que lʹunion.  Certaines  implémentations  de  SQL  ne  permettent  pas  dʹexécuter  une  requête  pour obtenir la liste combinée des ouvriers qui travaillent à lʹusine et ceux qui travaillent sur les chantiers, si la chaîne est déclarée avec des longueurs différentes. 

OuvrierUsine (nas* : number(4,0) , usine : varchar2(2)) OuvrierChantier (nas* : number(4,0),chantier : varchar2(4))

  OuvrierUsine :  nas*  usine  OuvrierChantier : nas*  chantier 

  234  u1    873  C500   456  u2        La réponse recherchée est une table de 3 colonnes, puisque les attributs usine et chantier ne sont par entièrement compatibles.   

nas*  usine  chantier 234  u1  null 456  u2  null 873  null  C500 

Figure 7.16g  Pour effectuer une telle union et obtenir la liste demandée, il faut avoir une compatibilité des schémas. Il y aura donc augmentation du schéma de OuvrierUsine en insérant une colonne d’indicateurs de nulls typés comme une chaîne varchar(4). Il en sera de même avec OuvrierChantier. La requête suivante devient donc  calculable :  

SELECT nas, usine, CAST(NULL as varchar(4)) FROM OuvrierUsine UNION SELECT nas, CAST( NULL as varchar(2)), chantier FROM OuvrierChantier;

 

Page 49: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

49

Voici  une  autre  requête  qui  donne  essentiellement  les  mêmes  données  avec  un arrangement différent dans  lequel  il nʹest plus possible de distinguer  les chantiers des usines, sauf si la valeur même de la donnée le permet.  

SELECT nas, CAST(usine as varchar(4)) [as] lieu_de_travail FROM OuvrierUsine UNION SELECT nas, chantier as varchar(4) [as] lieu_travail FROM Ouvrier_Chantier;

 réponse :  nas   lieu_travail 

  234  u1   456  u2   873  500  <‐ chantier 

7.11 Emboîtement des requêtes (jointure) Une  requête  emboîtée7  (nested  query)  est  composée  d’une  requête  principale  dite  de niveau ou bloc 1 avec au moins une sous‐requête de niveau ou bloc 2 dont lʹévaluation est  préalable  à  celle  de  la  requête  supérieure  de  niveau  1.  Il  peut  y  avoir  jusquʹà  16 niveaux dʹemboîtement.    Il y a aussi une  requête  emboîtée  et  corrélée. Dans une  telle requête corrélée, une des variables  (attribut) de  la sous‐requête est globale, c’est‐à‐dire qu’elle prend sa valeur dans le tuple courant obtenu par la requête principale (de niveau 1). Avec une telle requête corrélée, la sous‐requête est évaluée à chaque changement de la valeur globale, i.e. à chaque lecture d’un tuple dans la table de la requête principale. La  réponse  à  une  requête  emboîtée  n’est  formée  qu’avec  les  attributs  de  la  requête principale ;  ceux de la sous‐requête n’étant pas visibles au premier niveau.   Voici  quelques  exemples  de  requêtes  comprenant  une  sous‐requête  mais  sans corrélation.  a) Lister le nom des personnes qui ont acheté des articles qui ne sont plus en inventaire.  Pour calculer cette réponse, il y a d’abord présélection des articles encore en inventaire (dont le coût nʹest pas nul), formulée par une sous‐requête. L’affichage est  fait avec juste les attributs de  la  relation du bloc 1. Les articles vendus  sont  sélectionnés que  s’ils ne sont pas inclus parmi ceux encore en inventaire.  

SELECT nom FROM Ventes WHERE article NOT IN <-- prédicat d’inclusion (SELECT article FROM Inventaire WHERE cout is NOT NULL);

                                    Le  calcul de  la  sous‐requête  (de niveau  2)  est  entièrement  effectué  (matérialisé)  avant celui de la requête principale. En effet, la sous‐requête ne renferme aucun attribut global et son calcul fournit une table dont le contenu est constant pour cette requête. Ce résultat 

Page 50: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

50

intermédiaire est constitué de tuples qui constituent un ensemble transitoire stocké dans une  table  temporaire  utilisée  pour  lʹévaluation  de  la  requête  principale.  La  même requête peut être formulée avec une jointure et des alias de relation:  

SELECT nom FROM Ventes [as] V, Inventaire [as] I WHERE V.article = I.article and I.cout is NOT NULL;

Lʹalias  est  défini  avec  ou  sans  le  mot  clé  AS  selon  la  version  de  la  norme  SQL implémentée par le SGBD. Le calcul de la jointure se fait par un balayage des deux tables avec vérification de la condition de jointure formulée avec les deux attributs partageant le  même  domaine.  Au  besoin,  ces  deux  attributs  sont  libellés  différemment,  mais  doivent avoir un type ou un domaine compatible. Une jointure peut donc être exprimée par une requête utilisant un prédicat dʹinclusion. Très souvent, la jointure exploite le lien d’association entre les tables Inventaire et Ventes par l’entremise de la clé primaire et de la clé étrangère. La jointure n’est cependant pas limitée à ce cas.   Ventes :  nom*  article*  qte*  Inventaire :  article* prixVente  cout   Serge  a1  3    a5  12  8   Ted  a2  5    a1  10  5   André  a1  2    a2  20  15   Serge  a2  4    a7  15  15   Jocelyn  a1  2    a3  25  null   Serge  a3  4    a16  45  34   Serge  a5  3           Serge  a7  5           Christine  a3  6           Serge  a1  7         

Figure 7.17             Voici un  autre  exemple de  la  formulation de  la  jointure  en  SQL‐92. Le mot  clé  JOIN permet d’exprimer explicitement la notion de jointure :  

SELECT V.nom FROM Ventes as V JOIN Inventaire as I ON V.article = I.article and I.cout is NOT NULL;

 La condition de jointure peut être incluse dans la clause From avec le mot clé ON :  

SELECT V.nom FROM Ventes as V JOIN Inventaire as I ON V.article = I.article WHERE I.cout is NOT NULL;

 

Page 51: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

51

Le ON spécifie la condition de  jointure, tandis que le WHERE exprime un filtrage avec les autres attributs.    b) Lister  le nom des clients qui ont acquis des articles en rupture de stock. Cet état de l’inventaire  est  marqué  par  l’absence  de  coût  (indicateur  null)  pour  un  article  en inventaire.  

SELECT nom From Ventes WHERE article IN (SELECT article FROM Inventaire

WHERE cout is NULL );                                                  

Ventes :  nom*  article*  qte*  Inventaire : article*  prixVente  cout   Serge  a1  3    a5  12  8   Ted  a2  5    a1  10  5   André  a1  2    a2  20  15   Serge  a2  4    a7  15  15   Jocelyn  a1  2    a3  25  null   Serge  a3  4    a16  45  34   Valérie  a7  3           Lucie  a7  2           Serge  a5  3           Serge  a7  5           Christine  a3  6           Serge  a1  7         

Figure 7.17a  Une telle requête fait appel à un test dʹinclusion par lʹentremise du prédicat IN afin de ne sélectionner que les articles qui ne sont pas dans lʹinventaire courant. Pour chaque tuple de  la  table Ventes,  il  y  a  rétention de  ce  tuple dans  la  réponse  si,  et  seulement  si,  le prédicat est TRUE. Si le prédicat est évalué à UNKNOWN, le tuple de Ventes nʹest pas retenu. De plus,  l’information  affichée ne doit provenir que de  la  relation de premier niveau.  

Expression de table Parmi les exemples précédents, il y a ceux dont la sous‐requête est évaluée dès le début pour retourner une valeur scalaire. Il est aussi prévu dans la norme SQL‐92 quʹune sous‐requête retourne une table temporaire qui peut être nommée. Une telle expression peut être similaire à une vue relationnelle.  Exemple : SELECT ArtProfit.article, ArtProfit.marge*1.15 AS margeplus FROM  (SELECT  article, (prixVente ‐ cout) as marge FROM Inventaire WHERE prixVente > cout) AS ArtProfit WHERE ArtProfit.article = ʹa1ʹ 

Page 52: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

52

ORDER BY margeplus;                                                 Dans cette clause, lʹexpression de table donne une table dont le nom est ArtProfit et son schéma est global à la clause. Il peut donc être réutilisé dans la clause From ou dans les opérations subséquentes conduisant à la réponse. Finalement, lʹalias margeplus est connu au moment du tri et peut donc être un critère de celui‐ci.  

 Voici une autre expression de table qui permet de grouper les tuples par la marge, elle‐même calculée par lʹexpression (prixVente ‐ cout). Comme le GROUP BY nʹaccepte pas les expressions, il faut définir et travailler avec un alias.  

SELECT ArtProfit.marge, Count(ArtProfit.article) FROM (SELECT article, round((prixVente - cout),0) AS marge FROM Inventaire WHERE prix_vente > cout) as ArtProfit GROUP BY ArtProfit.marge;

ALL et ANY et un ensemble de valeurs Le mot clé ALL signifie pour chaque valeur ou pour chacune des valeurs et ANY,  avec le sens de SOME, signifie pour au moins une valeur sélectionnée par la sous‐requête. Si la  sous‐requête  identifie  au moins  un  tuple,  elle  est  évaluée  à  TRUE,  sinon  elle  est évaluée à FALSE. Cet opérateur  indique comment  les valeurs retournées par une sous‐requête sont prises en considération par le WHERE de la requête.  Exemples : a) Lister les articles déjà vendus en quantité inférieure ou égale à celles des ventes faites pour l’article ʹa2ʹ :   SELECT distinct article FROM Ventes WHERE qte < all(SELECT qte FROM Ventes WHERE article = 'a2');  

nom*  article*  qte*  tableT : qte Serge  a1  3    5 Ted  a2  5    4 André  a1  2     Serge  a2  4     Jocelyn  a1  2  réponse:  article Serge  a3  4    a1 Valérie  a7  3    a7 Lucie  a7  2    a5 Serge  a5  3     Serge  a7  5     Christine  a3  6     Serge  a1  7     

Figure 7.18    

Page 53: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

53

                                   Remarque : La quantité sera plus petite que  le plus petit nombre d’articles  ʹa2ʹ vendus jusqu’à  présent  par  toute  transaction  inscrite  dans  l’extension  courante.  La  fonction Min() permet aussi une autre formulation  avec une sous‐requête.  

SELECT article FROM Ventes WHERE QTE < ( SELECT Min(qte) FROM VENTES WHERE article = 'a2');

La  complexité  de  cette  requête  tient  au  fait  que  le  prédicat  de  sélection  réfère  à  une quantité qui doit être calculée d’abord et cela, avant que le premier tuple de lʹextension de Ventes ne soit testé. La fonction Min() a un ensemble de valeurs comme argument et retourne une seule valeur, soit la plus petite parmi celles de l’ensemble‐argument.  b) Lister les articles vendus en quantité supérieure à celles des ventes de l’article ʹa7ʹ : 

SELECT article FROM Ventes WHERE qte > all (SELECT qte -- plusieurs valeurs FROM Ventes WHERE article = ‘a7’);

Dans cet exemple,  la plus grande valeur de  l’attribut qte est utilisée pour  la  sélection.  Voici une autre formulation de la même requête. Elle est possible en raison de la relation dʹordre implicite aux valeurs entières du sous‐ensemble calculé. 

SELECT article FROM Ventes WHERE qte > (SELECT max(qte)

FROM Ventes WHERE Ventes.article = 'a7');

La sous‐requête est matérialisée et la table temporaire est utilisée pour la recherche de la plus grande valeur de l’attribut qte de la relation Ventes.  c) Lister  les articles vendus en quantité plus grande que celle de nʹimporte quel article vendu. 

SELECT article FROM Ventes WHERE qte > any (SELECT qte FROM Ventes);

 Autre formulation : 

SELECT article FROM Ventes WHERE qte > (SELECT Min(qte)FROM Ventes);

Page 54: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

54

Les  opérateurs  relationnels  peuvent  être  combinés  pour  former  diverses  conditions exotiques de comparaison :  < = any, <= all, != any, != all, < any, < all. 

7.12 Requête corrélée Un  requête  corrélée  est  une  requête  emboîtée  avec  au moins  un  attribut  global.  La réponse à une  requête  corrélée est  composée de  tuples  sélectionnés dans une  table de niveau 1 en fonction de  la présence d’un autre  tuple dans une autre table de niveau 2. C’est  une  requête  dite  de  corrélation  qui  se  formule  au  moyen  d’une  sous‐requête utilisant  une  variable‐attribut  globale.  L’information  qui  peut  être  affichée  provient uniquement de la première relation (externe à la requête ou de premier niveau). Ce type de requête implémente le quantificateur existentiel dont la formulation correspond aussi à une jointure.  Exemple : Lister les transactions de vente (donc tous les attributs de cette table) pour les articles encore en inventaire. Un article est en encore en inventaire si l’attribut cout a une valeur autre que l’indicateur NULL.     

SELECT * FROM Ventes [as] V WHERE Exists (SELECT article FROM Inventaire [as] I

WHERE V.article = I.article And cout is NOT NULL);

 où V.article  est  la variable‐attribut  globale  qui  est  instanciée pour  chaque  tuple de  la table Ventes. Le préfixe avec  l’alias  est nécessaire pour  éviter  toute  confusion dans  la corrélation avec la sous‐requête. Le prédicat WHERE est évalué pour chaque tuple de la relation Ventes. S’il est vrai pour un  tuple, celui‐ci est retenu dans la réponse. La clause EXISTS est vraie si au moins un tuple est trouvé par la sous‐requête.  Elle permet aussi de formuler une jointure avec la négation du prédicat.       

nom*  article*  qte*  Inventaire :  article*  prixVente  cout Serge  a1  3    a5  12  8 Ted  a2  5    a1  10  5 

André  a1  2    a2  20  15 Serge  a2  4    a7  15  15 Jocelyn  a1  2    a3  25  null Serge  a3  4    a16  45  34 Valérie  a7  3         

Lucie  a7  2         Serge  a5  3         Serge  a7  5         Christine  a3  6         

 

 

Serge  a1  7         Figure 7.19    

Page 55: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

55

                            Par exemple, une requête corrélée  négative est utile pour lister les pièces déjà vendues, mais qui ne sont plus en inventaire. 

SELECT nom, article, qte FROM Ventes [as] V WHERE not exists

(SELECT article FROM Inventaire [as] I WHERE V.article = I.article and cout is null);  L’attribut V.article est global et prend sa valeur à l’extérieur de la sous‐requête. Avec un tel attribut, la sous‐requête n’est pas évaluée totalement au départ. Lʹévaluation est faite pour chaque  instanciation de  l’attribut article avec  la valeur  fournie par un  tuple de  la relation Ventes. Dans une  telle  requête,  les  seuls attributs pouvant  être  inclus dans  la réponse  sont  ceux de  la  table de premier niveau.   Ainsi,  la  requête  suivante nʹest pas exécutable parce que l’attribut coût en est un de la table référencée par la sous‐requête.     

SELECT V.nom, V.article, V.qte, I.cout FROM Ventes V WHERE not exists (SELECT I.article FROM Inventaire I WHERE I.article = V.article);

Autres exemples avec BD3 : Dotation des ressources humaines Reprenons  le  schéma de  la BD3  libellé DOTATION  et  composé des  trois  relations  ci‐dessous. 

Empl (noEmpl*, nom, tauxH, noPoste) Assignations (noPoste*, noEmpl*, debut, quart) Postes (noPoste*, titre)

Deux contraintes référentielles sont aussi définies.  a) Lister  le nom et  le  taux horaire des employés qui ont au moins une assignation de travail : 

SELECT nom, tauxH FROM Empl [as] E WHERE EXISTS (SELECT * FROM Assignations [as] A WHERE E.noEmpl = A.noEmpl);

 Le prédicat de la sous‐requête utilise un attribut global préfixé par E.  La valeur d’un tel attribut est fixée à  l’extérieur de  la sous‐requête pour chaque tuple  lu  lors du balayage de  la  table. Notez  aussi  que  les  attributs  de  la  réponse  ne  sont  pas  obligatoirement préfixés parce que seuls les attributs de Empl peuvent être inclus dans la réponse.  b) Lister le nom et le taux horaire des employés qui n’ont pas d’assignation de travail. 

Page 56: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

56

SELECT nom, tauxH FROM Empl [as] E WHERE NOT EXISTS (SELECT *FROM Assignations [as]

WHERE E.noEmpl = A.noEmpl); Un  alias  de  relation  peut  être  utilisé  pour  remplacer  le  nom  d’une  table  de  base  de données dans une clause WHERE. Dans ce cas, l’alias préfixe un attribut global.  b)Lister le nom et le titre du poste des employés qui ont une assignation de travail.  Dans ce cas il faut afficher les attributs provenant de deux relations et cela en fonction de l’existence d’un tuple dans une troisième relation. 

SELECT nom, titre FROM Empl [as] X, Postes [as] Y WHERE X.noPoste = Y.noPoste and EXISTS (SELECT * FROM Assignations WHERE X.noEmpl = Assignations.noEmpl);

                                 Les tables Empl et Postes sont en premier l’objet d’une  jointure pour former la relation intermédiaire interne (connue seulement par le système) dont le schéma est le suivant :   

Rtemp (noEmpl, nom, tauxH, noPoste, noPoste, titre)  Chaque  tuple de  cette  relation  intermédiaire est prise en  compte  successivement pour vérifier  la  clause EXISTS. Lorsque  le prédicat EXISTS  est vérifié  et  si  la  réponse de  la sous‐requête est non vide, alors le tuple de premier niveau   est retenu dans la réponse. La variable de tuple X est globale et prend sa valeur à lʹextérieur de la sous‐requête. 

Expression de table partagée (DB2) Avec certaines clauses il est utile de référer à une vue dans une sous‐requête même si la requête principale est très occasionnelle. Par exemple, pour trouver les ateliers dont lʹâge moyen des ouvriers dépasse  celui de  lʹensemble des ouvriers,  il  est possible dʹutiliser une vue relationnelle par une clause CREATE VIEW.  Atelier (noAtelier*, chef, site, debit, volume, classe, noUsine, noSpecialite) Specialite (noSpecialite*, classe, description) Usine (noUsine*, libelle, adresse, ville, codePostal, production) Ouvrier (nas*, nom , age, dateEmb, noAtelier)  

CREATE VIEW Ancien (noAtelier, age_moy_at) AS SELECT noAtelier, AVG(age) [as] age_moy_at FROM Ouvrier GROUP BY noAtelier;

 

Page 57: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

57

La requête suivante permet dʹafficher le numéro des ateliers où lʹâge moyen des ouvriers est supérieur à lʹâge moyen des ouvriers peu importe lʹatelier.    

SELECT noAtelier FROM Ancien -- référence à la vue relationnelle WHERE age_moy_at >(SELECT AVG(age_moy_at) FROM Ancien);

 Le  calcul  de  la  réponse  sous‐tend  la  création  dʹune  vue  correspondant  à  une  table temporaire. Lors de sa formation, il y a accès au catalogue du système et calcul de la vue (matérialisation) pour chaque référence à celle‐ci dans une clause SQL.  Dans  lʹexemple  ci‐dessus,  il  y  a  deux  références  à  la  vue  relationnelle  Ancien,  qui entraînent  normalement  deux  matérialisations  de  la  vue.  De  plus,  entre  les  deux matérialisations, une mise à  jour peut  être  faite  sur  la base de données par une autre application    changeant  lʹextension  de  Ancien.  Pour  éviter  ce  double  calcul  et  lʹincohérence  de  lecture,  le  système  DB2‐V2  exploite  la  notion  dʹexpression  de  table partagée. Il sʹagit de la factorisation de la vue dans une clause qui débute avec le mot clé WITH placé en tout début de la requête :  

WITH Ancien (noAtelier, age_moy_at) AS (SELECT A.noAtelier, AVG(O.age)FROM Atelier A, Ouvrier O WHERE A.noAtelier = O,noAtelier GROUP BY A.noAtelier SELECT noAtelier FROM Ancien WHERE age_moy_at > SELECT (AVG(age)FROM Ancien); 

 Cette clause effectue un seul calcul de lʹextension de lʹexpression de table identifiée par le WITH  et du même    coup  supprime  tout danger dʹincohérence  lors du  calcul de  la réponse suite aux actions d’une autre application.  

7.13 Fouille hiérarchique de lʹextension dʹune relation  en Oracle Les données organisées avec une structure arborescente et stockées dans une relation de base  ou  obtenues  par  calcul  peuvent  être  extraites  par  une  expression  SQL  (Oracle) caractérisée par un CONNECT BY. On a vu que  lʹalgèbre  relationnelle ne permet par dʹexploiter directement les structures arborescentes, parce quʹelle nʹest pas récursive.   

parent :  nas*  pren  nase*  prene   50  Paul  55  Lise   55  Lise  65  Jacques   65  Jacques  75  Patricia   65  Jacques  95  Sylvie   95  Sylvie  185  André   55  Lise  100  Luce   100  Luce  200  Renée 

Figure 7.20 

Page 58: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

58

 Les  structures  arborescentes  peuvent  représenter  différentes  situations  comme  la généalogie  des  personnes,  lʹinclusion  des  parties  dans  un  tout,  la  composition  dʹun équipement  formé  avec des  composants mécaniques  ou  la hiérarchie des postes dans une organisation. Voici un exemple dʹune table représentant la hiérarchie parentale.                              Lʹexemple de la Figure 7.20 concerne la représentation des personnes qui sont un parent dʹune ou de plusieurs autres personnes,  toutes  représentées dans  la même  relation de base.  Toute  personne  peut  être  successivement  parent  et  enfant  selon  le  niveau  de représentation dans  l’arbre. Chaque personne est  identifiée par son nas et son prénom.  La personne qui est parent de lʹautre apparaît en première position dans le tuple.                                    Cette relation représente donc  les personnes ayant un rang de parenté du  type parent‐enfant entre elles. Ainsi,  Jacques, dont  le nas est 65, est parent de Patricia et de Sylvie, dont le nas est respectivement 75 et 95.  Pour  trouver  toutes  les personnes  ayant une  filiation donnée,  le  système  exécute une requête  initiale pour  trouver  tous  les  tuples de  la  relation,  considérés  comme  formant lʹensemble de départ D  (identifié par un  START WITH). A partir de  cet  ensemble de départ, le système exécute une requête pour trouver en premier toutes les personnes qui sont juste en dessous et ces tuples sont notés par le système comme étant de niveau 1. Ils sont ajoutés à  lʹensemble de départ. Les  tuples ajoutés ont un  lien parental direct avec une personne de lʹensemble D. A chaque fois quʹun tuple de lʹensemble de départ D est traité par la recherche, il est marqué comme traité. Le résultat de la recherche est ajouté pour obtenir un ensemble de départ augmenté D*. La deuxième opération se poursuit avec chaque tuple de niveau 1 pour trouver ceux de niveau 2 et ainsi de suite. Lʹarrêt est signalé lorsque toutes les personnes de lʹensemble de départ augmenté D* ne sont plus parent ou encore lorsquʹils ont tous été testés (condition dʹarrêt). 

Sommaire de lʹalgorithme Les  tuples de  lʹensemble de départ  sont  trouvés  avec  la  clause  START WITH  et  sont regroupés  dans  lʹensemble  setD.  Pour  chaque  tuple  parent  (en  commençant  avec  les parents des tuples de lʹensemble de départ, soit setD), les tuples enfants sont trouvés par 

50, Paul

55, Lise

65, Jacques100, Luce

95, Sylvie200, Renée 75, Patricia

185, André

Enfant de 

Page 59: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

59

le  prédicat  CONNECT  BY  et  ne  sont  retenus  dans  la  réponse  que  sʹils  vérifient  le WHERE.  Lʹopération  recommence  pour  trouver  les  enfants  de  ces  tuples,  et  ainsi  de suite.  La  condition  dʹarrêt  est  vérifiée  lorsquʹil  nʹy  a  plus  de  tuples  parentaux    dans setD*, cʹest‐à‐dire quʹaucun tuple de setD* a un enfant. 

Algorithme de calcul dʹune requête hiérarchique Dans cet algorithme, il y a deux métafonctions :  f_enf(t) et f_start(p) ainsi qu’une variable de tuple t.  f_enf(t): fournit les tuples enfants (par le CONNECT BY) du tuple t. f_start(p): fournit les tuples de D qui vérifient le prédicat p dans R;  début; SetD = vide; SetD = SetD + f_start(p);   /*tuples du start with*/ SetD* = SetD; For each t non marqué in SetD* [WHERE p1];/*filtre avec WHERE*/  Marquer le tuple t courant du SetD*; SetD* = SetD* + f_enf(t);    /*tuples identifiés par Connect By */ end_for; Affiche SetD*;‐‐(au besoin avec LEVEL); Fin. 

Figure 7.22  Cet algorithme est celui du SGBD Oracle pour implémenter lʹexploration itérative dʹune arborescence. L’opérateur  unaire  PRIOR  est  associé  au CONNECT BY  qui  précise  au moyen dʹune condition la relation entre le tuple parent et les tuples enfants et cela,   au moyen dʹun attribut qui concrétise le lien.  Clause SQL (Oracle) pour fouiller une arborescence : 

SELECT LEVEL, nas, LPAD(' ',2*(LEVEL-1))||TO_CHAR(nase) [as] NASEENF FROM Parent START WITH nas = 55 --calcul de D CONNECT BY PRIOR nase = nas --PRIOR attribut du parent ORDER BY LEVEL, nas;

 LEVEL  NAS  NASEENF (alias de NASEE) 

1  55  65 1  55  100 2  65  75 2  65  95 2  100  200 3  95  185 

Page 60: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

60

Figure 7.23  Les  requêtes  récursives ou hiérarchiques  sont prévues dans SQL‐93. Toutefois, Oracle, DB2  et  WATCOM  SQL  ont  déjà  implémenté  leur  propre  version  de  la  recherche hiérarchique. Le système DB2‐V2 a une implémentation plus poussée de cet algorithme afin de permettre aussi  les  requêtes  récursives. Prenons un autre cas, celui de  la  table Produit qui  représente  les pièces  finies obtenues par  lʹassemblage de pièces  fabriquées en sous‐traitance.  Ces dernières pouvant être aussi composées avec des pièces elles‐mêmes fabriquées en sous‐traitance. Le produit p1  comprend  2  composantes p22  et  3  composantes p23. Le produit  p20  est  composé  lui‐même  de  6  composantes  p26  et  4  composantes  p34.  Le produit p23 comprend 2 composantes p20. Comment formuler  la requête pour afficher les composantes et les sous‐composantes des produits p1?                       

Produit :  noProd*  composante*  qte   p1  p22  2   p1  p23  3   p20  p26  6   p20  p34  4   p2  p33  3   p23  p20  2 

Figure 7.23a  Une  requête  d’exploration  pseudo  récursive  est  toute  désignée  pour  effectuer  cette recherche.  

SELECT LEVEL, noProd, composante FROM Produit Start with noProd = ‘p1’ Order by Level;

La réponse est constituée des pièces : {p1, p22, p23, p20, p26, p34}.   

7.14 Récursivité avec le SGBD DB2‐V2 Une  expression  de  table  en  DB2‐V2  a  une  autre  propriété  très  importante,  soit  la récursivité dont elle peut être  lʹobjet dans son traitement. En effet, une  telle expression peut être définie en se référant à elle‐même. Par exemple, si dans la relation Ouvrier on ajoute lʹattribut nasChef, il devient possible de demander quels sont les ouvriers qui sont sous  la supervision directe ou  indirecte du chef  ʹPatronetʹ dont  le nas est  ʹn1ʹ. En effet ʹPatronetʹ  peut  superviser  directement  lʹemployé  ʹGuyʹ  qui  supervise  lʹemployée ʹPatriciaʹ qui à son  tour supervise  lʹemployé  ʹJulienʹ. La réponse à  la première question est donc lʹensemble suivant {‘Guy’, ‘Patricia’, ‘Julien’}  

Ouvrier (nas*, nom , age, dateEmb, nasChef, noAtelier) 

Page 61: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

61

 Pour  calculer  cette  réponse,  il  est  possible  de définir  une  expression  de  table  qui  est calculée  une  première  fois  pour  former  lʹensemble  setD,  et  ensuite  recalculée  aussi longtemps  que  de  nouveaux  tuples  sont  ajoutés  à  lʹensemble  précédent  pour  former setD*. Lʹalgorithme utilisé  est  similaire  à  celui de Oracle.  Il  consiste  à  calculer dès  le départ  lʹensemble  setD,  i.e.  les personnes  supervisées directement par  le  chef  ʹPatronʹ dont  le nas est  ʹn1ʹ. Cʹest  la sous‐requête  initiale. Ensuite,  il faut calculer récursivement les Ouvriers supervisés par chaque ouvrier de  lʹensemble  initial. Les employés doivent être  reliés  aux  tuples  existants  dans  lʹensemble  précédent.  La  syntaxe  en DB2  est    la suivante :  

WITH Supervises (nas) AS <-- ensemble de départ (SELECT nas -- requête initiale FROM Ouvrier O WHERE O.nasChef = 'Patronet') UNION ALL

(SELECT O.nas <-- requête récursive FROM Supervises [as] S, Ouvrier [as] O WHERE O.nas = S.nas);

 SELECT nas <-- requête finale FROM Supervises;

 Lʹopérateur UNION ALL est  similaire à  lʹUNION,  incluant  cependant dans  le  résultat tous les tuples, y compris ceux qui sont  dupliqués. 

7.15 Fonctions SQL Les fonctions du langage8 sont divisées en deux groupes selon qu’elles s’appliquent à un tuple (fonction scalaire) ou à un ensemble de tuples (fonction d’agrégation).  7.15.1 Fonctions appliquées à chaque tuple sélectionné Les fonctions scalaires sont classées selon la nature des arguments et de leur traitement particulier : ‐ Fonctions numériques : opérateurs mathématiques, arrondi, troncature, valeur absolue,  ‐ Fonctions caractères (chaînes) : recherche d’une sous‐chaîne, longueur, transformation,  ‐ Fonctions avec la date : transformation en format date et inversement ... Fonction de conversion : conversion numérique, de monnaie, de calendrier, ...  Les opérateurs arithmétiques et les fonctions incorporés dans une expression du langage peuvent être utilisés dans la clause SELECT et/ou WHERE à la place dʹun attribut. Une fonction  ne  diffère  d’un  opérateur  que  par  la  forme  externe  de  ses  arguments.  La fonction a zéro ou plusieurs arguments spécifiés dans sa liste. L’opérateur a au moins un argument  et,  s’il  en  a  deux,  ils  sont  spécifiés  en  notation  arithmétique  usuelle.    La fonction  à  plusieurs    arguments  sʹécrit  sous  la  forme  bien  connue  avec  la  liste  des 

Page 62: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

62

arguments entre parenthèses. Finalement, la librairie des fonctions peut être augmentée à volonté, tandis que les opérateurs sont figés par la grammaire du langage de données. 

Fonctions et opérateurs numériques La gamme des fonctions peut varier dʹun système à lʹautre. Par exemple, certains SGBD offrent  les  services dʹun générateur de nombres aléatoires,  la  fonction RAND(),  tandis que cette même fonction doit être implémentée par l’utilisateur au moyen de la fonction modulo.  

Fonction numérique Description ABS (n)   Valeur absolue du nombre n CEIL (n)  Plafond d’une valeur réelle n MOD (m, n)   Le modulo : le reste de m/ n  GREATEST (v, w)  La plus grande des  deux valeurs v et w LEAST(v, w)  La plus petite des deux valeurs v et w 

 Fonction numérique Description 

POWER  (m, n)  Exponentiation : mn ROUND (m, n)  Arrondi du nombre m avec n chiffres après le point. SQRT (m)  Racine carrée de m TRUNC (m, n)**  Troncature du nombre m   à n chiffres décimaux; ** si m 

est une date, alors pour n = 0, suppression de la partie du temps: hh:mm:ss 

Figure 7.24                            ** La fonction TRUNC() joue un rôle particulier dans le traitement des dates. En effet, un attribut déclaré de  type date  est  codé à  lʹinterne avec un  format particulier qui  inclut aussi le temps correspondant à la création du tuple dans la base. Ce temps est composé de lʹheure, la minute et la seconde : hh:mi:ss . A chaque insertion ou modification dʹune date, lʹheure peut être ajoutée, sinon elle est annexée automatiquement par Oracle selon une  valeur  par  défaut  généralement  définie  dans  un  fichier  système  d’initialisation comme  étant    00:00:00.  Pour  supprimer  le  temps  dans  la  date,  il  est  aussi  possible dʹutiliser le masque de la fonction TO_CHAR() ou de faire appel à la fonction TRUNC(). Dans ce dernier cas, la troncature sʹopère en enlevant la partie temps de la date.   Exemples :  

TRUNC (SYSDATE) supprime le temps de la date du jour. TO_CHAR(dateIn, 'DD-MM-YYYY')

—chaîne date retournée sans le temps SELECT To_Char(trunc(SYSDATE), ‘DD-MM-YYYY’) FROM DUAL;

  Rép :   24‐11‐2000          ‐‐  le  temps  est absent de  la  réponse,  car  il a  été  supprimé par  la fonction Trunc(). 

Page 63: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

63

 Voici quelques exemples qui  illustrent  lʹusage des opérateurs binaires et des  fonctions scalaires :  a) Calculer la racine carrée de la marge bénéficiaire sur les articles en inventaire dont le coût d’achat est plus grand que 10 $ .  

SELECT article, SQRT(prixVente - cout) [as] marge FROM Inventaire WHERE cout > 10.00;

 Remarque :   La marge bénéficiaire est égale à  la différence entre  le prix de vente et  le coût  de  l’article.  Cette  différence  est  calculée  pour  chaque  tuple  sélectionné  par  le prédicat de la clause WHERE.    b) Afficher le nom des articles en inventaire dont le carré du bénéfice est compris entre 5$ et 15 $ . 

SELECT article FROM Inventaire WHERE POWER((prixVente - cout), 2) between 5 and 15;

c) Afficher le montant total de la vente de 23 articles au prix de 45 $ l’unité. Pour obtenir la réponse, il faut effectuer une simple multiplication en utilisant la table DUAL : 

SELECT 23 * 45.00 -- simple multiplication avec affichage FROM DUAL;--table fictive ayant le type table par SQL

 Le calcul est possible dans un SELECT ou dans un WHERE à condition de référer à une table de  la base de données. En effet,  la grammaire exige  la présence d’une  table pour que  l’analyse  syntaxique  accepte  la  clause  SQL.  La  table DUAL  est  en  quelque  sorte virtuelle et permet de satisfaire aux exigences de la grammaire SQL.   d)Lister les articles en inventaire dont le prix de vente est inférieur à 90 % du montant le plus élevé entre le prix  de vente et le coût.    

SELECT article FROM Inventaire WHERE prixVente < .90 * GREATEST(cout, prixVente);

 Lʹappel de  la  fonction et  lʹévaluation de  lʹexpression sont  faits pour chaque  tuple de  la table Inventaire.                                      e) Lister les articles en inventaire et le  montant le plsu élévé entre le prix de vente et le coût: 

Page 64: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

64

SELECT article, Greatest (prixVente,cout) FROM Inventaire ;

Fonctions SQL pour les chaînes Un seul opérateur de chaîne est défini dans le langage, soit celui de la concaténation (||). Cʹest un opérateur binaire dont  les opérandes peuvent  être une  expression  simple ou complexe, dont lʹévaluation fournit une chaîne, i.e. une constante de chaîne. Cependant, plusieurs fonctions de chaîne sont implémentées dans tous les langages de données.   Les  arguments des  fonctions  sont des  constantes, des  attributs  ou des  expressions de chaîne. La valeur retournée est typée. Cependant, une fonction dont un des arguments est NULL retourne une valeur qui est un null, sauf pour  la fonction REPLACE(). Cette dernière fonction accepte le NULL et permet son remplacement par un autre caractère. Les fonctions ont un comportement général prédéterminé lorsque tous les arguments de son prototype sont fournis. Elles ont aussi un comportement particulier lorsque certains arguments sont absents ou réduits à leur plus simple expression.                                      

Fonctions de chaîne  Description LPAD(ch1,n[,ch2])  Remplissage par la gauche avec les car. ch2 jusquʹà ce que la 

longueur  totale de ch1 soit n. Si ch2 est absent,  le caractère de remplissage est le blanc. 

LTRIM(ch1[, setcar])  Suppression des  car. par  la gauche dans  ch1    jusquʹau  1er car. qui nʹest pas dans setcar. Si cet argument est absent, tous les blancs sont supprimés par la gauche. 

RPAD(ch1, n [, ch2])  Remplissage droit avec ch2  jusqu’à l’atteinte de la longueur n pour la chaîne ch1. 

RTRIM(ch1[, setcar])  Suppression des car. par la droite  dans ch1  jusquʹau 1er car. qui nʹest pas dans setcar. 

CHR(n)  Caractère ASCII équivalent à lʹentier n. INITCAP (ch1)  Retourne ch1 avec une majuscule pour  le premier caractère 

de chaque mot de ch1. Deux mots sont séparés par un blanc. CONCAT (ch1, ch2)  Concaténation de ch1 et ch2 dans l’ordre des arguments. LOWER (ch1)  Retourne ch1 en minuscules. UPPER (ch1)  Retourne ch1 en majuscules. SOUNDEX (ch1)  Code  pseudo  phonétique de  ch1  (signature  phonétique de 

Oracle) SUBSTR (ch1, m, n)  Extraction dʹune sous‐chaîne à partir de la position m (incl.) 

et de longueur n. TRANSLATE(ch1, s, c)  Transcodage de ch1: chaque car. de ch1 retrouvé en position 

i dans  la chaîne s est  remplacé par celui de même position dans  la  chaîne  c. Le  caractère de  remplacement dans  c  ne peut pas être un null, car  la  fonction retournerait alors une valeur  nulle.  Si  la  position  i  est  absente  dans  c,  alors  le caractère est supprimé dans ch1.  

INSTR(ch1,ch2,n,[i])  Retourne  la position de  la  i ème occurrence de ch2 dans  la chaîne ch1 et cela à partir de la position n. Si i est absent, sa valeur par défaut est 1. 

Page 65: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

65

LENGTH (ch1)  Longueur de  la  chaîne  ch1. Le  caractère NULL n’occupant aucun espace pour la fonction LENGTH. 

REPLACE (ch1, si, par)  Retourne  ch1  dans  laquelle  toute  occurrence  de  si  est remplacée par celle de par  (N.B. par   peut être un null). 

TO_NUMBER(ch1[,fmt[,nls]])  Transforme  la  chaîne  ch1  représentant  un  nombre  dont  le format peut être donné par fmt. 

Figure 7.25                        

Légende : ch1, ch2, par  : pour chaîne de caractères;      n pour un entier;  setvar = jeu de caractères (constante de chaîne)  pos :  position dans la chaîne fmt = format de la chaîne         nls : paramètre de langue nationale  Voici  quelques  exemples  avec  BD3  pour  illustrer  lʹusage  des  fonctions  de  chaîne, notamment lʹemboîtement des fonctions.  a) Afficher le nom et le numéro des employés dont le nom dépasse 40 caractères 

SELECT noEmpl, nom FROM Empl WHERE LENGTH(nom) > 40;

                     b)  Extraire une sous‐chaîne du nom des employés dont le numéro est supérieur à 400 à partir de la position où se trouve la première occurrence de la lettre ʹiʹ et cela jusquʹà la position où se trouve la première occurrence du premier blanc. 

SELECT SUBSTR(nom, INSTR (nom, 'i'), INSTR (nom, ' ' )) FROM Empl WHERE noEmpl > 400;

 c) Affichez  le  nom  des  ouvriers  dont  les  voyelles  sont  supprimées  sauf  une  qui  est remplacée par le caractère souligné  ʹ_ʹ. 

SELECT TRANSLATE(nom, 'aeiouy', '_') FROM Empl;

 d) Afficher  en minuscules  le  nom  des  employés  dont  la  première  lettre  est  un  T  et compléter par  la gauche avec des tirets de manière à afficher au total une chaîne de 30 caractères.   La fonction RTRIM() permet de supprimer par la droite les caractères  jusquʹau premier absent de la liste fournie comme deuxième argument.   

SELECT LPAD(nom,30,' ')), FROM Empl WHERE SUBSTR (nom, 1,1 ) = 'T';

 

Page 66: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

66

 e)    Afficher  le  numéro  et  le  nom  des  employés  dont  le  nom  a  une  prononciation similaire à Durand et dont la longueur est inférieure à 25 caractères.   SELECT noEmpl, nom FROM Empl WHERE SOUNDEX(nom) = SOUNDEX('durand') and LENGTH (nom) < = 25;

À propos du code Soundex Lʹalgorithme graphico‐phonétique Soundex a été proposé il y a quelques décennies par Margaret K. et Robert C.  Odell (1918) 9 dans le but de faciliter la recherche des auteurs dans  les  catalogues  de  bibliothèques  lorsque  lʹorthographe  du  nom  de  famille  était imprécise.  Il  consiste  à  générer  une  signature  Soundex  pour  un  nom  et  ses  graphies similaires. Lʹobjectif était de pouvoir  rechercher un nom dont  l’orthographe  imprécise fournissait une  phonétique similaire à la graphie correcte du nom. La prononciation de Smith et Smithes ou de Durant et Durand est  similaire, mais  la graphie est différente. Son efficacité est variable et dépend de la nature et de lʹemplacement des modifications ou des omissions qui peuvent être au début ou à  la  fin du nom. Plus  le nom est  long, plus la signature regroupe correctement  les noms erronés dont les différences se situent à  la  fin  de  la  chaîne.  Il  est  efficace  pour  la  langue  anglaise,  notamment  les  versions avancées du Soundex, et un peu moins pour  le  français poour  lequel des algorithmes modifiés  ont  été  proposés  récemment.  Il  peut  être  utilisé  avec  certaines  langues  non romanisées  à  la  condition  de  redéfinir  les  familles  phonétiques.  Plusieurs  versions améliorées et adaptées ont été proposées par Russell10, et plus récemment  par Baird de Georgia Tech11 et par Philips12.                                                   Le principe général  repose  sur  le  fait que  les  consonnes  susceptibles dʹengendrer des confusions sont celles qui appartiennent à la même famille phonétique. En anglais, il y a 6 familles phonétiques : bilabiale, labiodentale, dentale, alvéolaire, nasale et laryngale. Il suffirait  en  principe  donc  de  remplacer  les  consonnes  dʹune  même  famille  par  un caractère  unique  pour  résoudre  plusieurs  cas  dʹambiguïté.  Finalement,  comme  les erreurs dans  la graphie sont plus probables avec un nom  long qu’avec un court et que les erreurs se situent  très souvent à  la  fin du nom,  le code Soundex   ne retient que  les premiers caractères du code généré. 

Algorithme Soundex (version Odell) 1‐ Le nom initial est placé dans la variable Code_S; 2‐ Supprimer tous les caractères non alphabétiques de Code_S.     La chaîne restante est affectée à la variableCode_C initial; 3‐ Transformer les lettres restantes dans Code_C en lettres majuscules; 4‐ Le premier caractère du Code_C est gardé tel quel; 5‐ Les autres caractères du Code_C sont traités et transformés ainsi :  5.1 Les voyelles et les caractères H et W sont supprimés dans Code_C; 5.2 Les caractères B, F, P, et V du Code_C  sont remplacés par le chiffre‐caractère 1; 5.3 Les caractères C, G, J, K, Q, S, X, Z du Code _C sont remplacés par le chiffre‐caractère 2; 5.4 Les caractères D et T du Code _C sont remplacés par le chiffre‐caractère 3; 

Page 67: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

67

5.5 Le caractère L du Code _C est remplacé par le chiffre‐caractère 4; 5.6 Les caractères M et N du Code _C sont remplacés par le chiffre‐caractère 5; 5.7 Le caractère R du Code _C est remplacé par le chiffre‐caractère 6; 6‐ Toute paire de caractères Soundex identiques dans Code_C est remplacée par un seul caractère; 7‐  Les  caractères  représentant  les  voyelles  encore  présentes  dans    Code_C  sont supprimées; 8‐ Le premier caractère et les trois chiffres suivants sont conservés comme code Soundex; si Code_C nʹa pas  suffisamment de  chiffres,  la  chaîne est  complétée avec  le  caractère‐chiffre 0.                          

Exemple :  Langue  Code_S  Code_C     anglais  Rogerson  R262       Rogerson  R262       Rogers  R262  <‐‐     Roger  R260  <‐‐‐     Rodger   R326  <‐‐   français  Durant  D653       Durand  D653  <‐‐‐     Duran  D650  <‐‐‐ 

Figure 7.25a  Le calcul de  la  signature est en quelque  sorte un Hashing avec cette différence que  le nombre de collisions est sensiblement important, pour peu que les racines des noms de la source soient similaires. Lʹefficacité de la signature du Soundex peut être mesurée par le nombre de signatures similaires générées par lʹalgorithme :   

E = 1 - (nb_signatures_identiques / nb_de_noms_différents).  Pour un ensemble sans conflit de signatures, E = 1  ; avec une seule signature pour un ensemble de noms, E = 0.                               

7.15.3  Fonctions SQL pour le traitement des dates  Les dates13 sont des données  importantes dans une base de données et  leur  traitement est  plus  complexe  qu’on  l’imagine  à  priori.  Lʹhistoire  du  calendrier  remonte  au  grec Meton  (400 B.C.) qui découvrit  le  cycle  lunaire de  19  ans  et  son  effet  sur  la  façon de reconnaître correctement les saisons. À cette époque la connaissance du cycle des saisons était une question importante pour l’agriculture et de survie! Il sʹen est suivi à travers les siècles une série de repères pour du temps au moyen de la notion de date intégrée dans divers  calendriers,  chacun  dénommé  par  le  nom  de  son  auteur.  Ainsi  pour  les musulmans, c’est la fuite de Mahomet de la Mecque vers Médine en 622 qui marque le point  de  départ  du  calendrier.  Pour  le  monde  hébreu  le  calendrier  débute  avec  la création  du  monde  fixée  à  3760  ans  avant  Jésus‐Christ.  Pour  les  chrétiens,  c’est  la 

Page 68: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

68

naissance  de  Jésus  fixée  qui  détermine  l’année  0.  C’est  donc  dire  que  l’an  2000  en Occident correspond à l’an 5760 pour les hébreux et à l’année 1377 pour les musulmans! Sur  le plan planétaire, une date est une  convention dʹécriture dʹune  réalité  temporelle fortement  influencée  par  le  système  des  planètes.  Plus  concrètement,  un  système informatique moderne  doit  tenir  compte  de  plusieurs  éléments  pour  représenter  une date de calendrier, notamment du caractère conventionnel de son origine qui varie selon le système politico‐religio‐culturel de référence.                Dans un SGBD, chaque date est stockée dans un  format  interne complexe particulier à chaque  système  SGBD. Elle  comprend, pour un  calendrier  Julien  qui utilise  la notion d’écart avec un point temporel fixe, outre le jour, le mois et lʹannée, le siècle, l’heure, la minute et la seconde.         

Figure 7.25b Les dates en  format  interne obéissent à une  relation dʹordre;  elles peuvent  être  l’objet d’une comparaison ou dʹun calcul par  les opérateurs de date, comme une addition ou une  soustraction.  Le  format  des  dates  doit  être  valide  au‐delà  du  siècle  courant  afin dʹéviter  les  problèmes  du  passage  du  millénaire  débusqués  dans  les  anciennes applications (legacy applications). Passage bi‐directionnel dʹune date en format interne au format externe piloté par un gabarit (masque).  Les fonctions To_Date() et To_Char() sont importantes pour la manipulation dʹune date. Ces  fonctions  comportent plusieurs  arguments qui  seront  expliqués un peu plus  loin. Plusieurs autres fonctions utilisent un argument du type date pour faire des opérations sur celles‐ci.                   Fonctions pour les dates  Description SYSDATE  Date du système (du jour); fonction sans argument. LAST_DAY (d)  Date du dernier jour du mois comprenant la date d  MONTHS_BETWEEN(d1, d2)  Nombre de mois entre deux  dates d1 et d2 ADD_MONTHS(d, n)  Retourne la date en y ajoutant n mois à la date d. Le n peut 

être positif ou négatif. NEXT_DAY(d, j)  Retourne la date du prochain jour j qui suit la date spécifiée. 

Le dimanche est codé avec  J=1 ou ‘SUNDAY’ Figure 7.26 

 

xx.ee.sss.uuu.urruu.ttt 

21 :24‐Jan‐2000 16 :45 :32 

To_Date ( ) 

Date dans un des formats externes disponiblesTo_Char( )

Page 69: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

69

La valeur retournée peut être un entier ou une date. Par exemple, si on ajoute un entier à une  date,  la  réponse  est    une  date.  Par  contre,  si  on  soustrait  deux  dates,  la  valeur obtenue est un entier. Exemples : a) Afficher la date du jour  

SELECT SYSDATE FROM DUAL ; /*DUAL est une table virtuelle nécessaire dans une clause pour satisfaire la grammaire de SLQ */

                     Lors de lʹaffichage piloté par SQL*Plus, le temps est enlevé et seulement les éléments de la date, formée du jour, du mois et de lʹannée sont affichés par cette clause.  Cet  affichage  peut  être  aussi  bien  contrôlé  par  un  format  explicite  au moyen  de  la fonction TO_CHAR() qui comporte un masque.   

SELECT TO_CHAR (debut, 'DD-MON-YYYY') FROM Empl WHERE quart = 'soir' ;

 Pour afficher  le mois en  français  lorsqu’il a été enregistré en anglais,  il  faut utiliser  le masque de la fonction To_Char().  

SELECT TO_CHAR(dateEmbauche,'DD-MON-YYYY', 'NLS_DATE_LANGUAGE = french')

FROM Employe;  La date  affichée  aura  le  format  suivant:  23‐DEC‐1998  et  le mois  sera  exprimé dans  la langue spécifiée par le paramètre NLS.                                                                    b) Afficher le dernier jour du mois :  

SELECT LAST_DAY(SYSDATE) "dernier jour du mois" <-libellé FROM DUAL;

                        La chaîne devient lʹintitulé de la colonne de la table réponse. Les guillemets doubles sont utilisés parce que le libellé contient des espaces.                                 c) Afficher l’arrondi de la date du jour : 

SELECT ROUND(SYSDATE) FROM DUAL;

 d) Afficher la date du prochain lundi après le 31 décembre 1999. 

SELECT NEXT_DAY('31-dec-1999', 'MONDAY') FROM DUAL;

Date par défaut 

Page 70: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

70

Le système SGBD a normalement un format de date par défaut défini dans un fichier de paramètres pris en compte au lancement de lʹinstance. Avec Oracle, ce format peut être DD‐MON‐YYYY;  dans  ce  cas  le  gabarit  ne  spécifie  pas  le  temps  qui  est  par  défaut 00:00:00, soit minuit. Ce paramètre peut être spécifié ou redéfini dans le fichier système INIT.ORA.  Il  est  aussi  possible  dʹinclure  le  temps  réel  en  spécifiant  le  paramètre NLS_DATE_FORMAT  comme  étant  ʹDD‐MM‐YYYY  HH:MI:SSʹ.  Ainsi,  lʹinscription dʹune date par  la  fonction SYSDATE  inclut aussi  le  temps courant. Ce paramètre peut être  temporairement  changé  pour  la  durée  dʹune  session  avec  la  commande ALTER  SESSION.  Il est   possible de  connaître  la valeur  courante de  ce paramètre défini dans lʹinstance en consultant la table GV$NLS_PARAMETERS.      ALTER SESSION SET NLS_DATE_FORMAT = 'DD/MM/YYYY HH24:MI:SS' ; INSERT INTO Ouvrier ('200056345','Vézina,'Claude','M', '33.8',SYSDATE,'u12', 'ps75'); -- temps est inséré avec SYSDATE --25-DEC-1999 23:54:49 (à l'interne) ;  SELECT TO_CHAR(dateP,'DD/MM/YYYY HH:MI:SS') FROM Tplan_Mois; réponse --> 22/02/1998 23:11:56 --le temps est affiché  Avec la suppression du temps : 

ALTER SESSION SET NLS_DATE_FORMAT = 'DD/MM/YYYY' ;  À partir de  cet  instant,  les  insertions de  tuple  avec une date peuvent  se  faire  avec  le nouveau  format  de  date.  À  lʹinterne,  le  temps  sera  celui  défini  par  défaut,  soit  par exemple 00:00:00 :  INSERT INTO TABLE1 Tplan_Mois

('machine2376',To_Date('24-01-1998','DD-MM-YYYY')); Il  est  cependant  toujours  possible  dʹinsérer  le  temps  courant  en  utilisant  le  gabarit approprié.  INSERT INTO TABLE1 Tplan_Mois ('machine2376',To_Date('24-01-1998','DD-MM-YYYY HH:MI:SS'));                                        Il  est  aussi  possible  de  changer  temporairement  ce  format  par  défaut  en  utilisant  le paramètre NLS_DATE_FORMAT. 

ALTER SESSION SET NLS_DATE_FORMAT = 'DD/MM/YYYY HH24:MI:SS';

SELECT TO_CHAR(datep, 'dd-mm-YYYY hh:mi:ss') FROM Tplan_Mois;

Page 71: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

71

 réponse ‐‐>  12‐DEC‐1998 23:25:56 

Fonctions SQL de conversion des types Quelques fonctions jouent un rôle particulier dans la conversion du type interne vers un format  externe  compatible  avec  lʹenvironnement.  Le  paramètre  NLSP  permet  de spécifier  le mois dans une  langue naturelle particulière. Par exemple, pour obtenir une date avec  le mois en  français à partir de  la date stockée en  format   américain,  il suffit  dʹutiliser le troisième paramètre de la fonction TO_CHAR()  :   

Fonctions conversions  Transformation TO_CHAR(d, masque[, nlsp]))  Retourne une chaîne pour la date d conformément au masque 

fourni. TO_DATE(ch1,masque[,nlsp]))  Conversion de ch1   au format  interne date en  interprétant  la 

chaîne selon le masque fourni. TO_NUMBER(ch1,masque[,nlsp])  Fournit  la valeur numérique de  la chaîne ch1 conformément  

au masque du nombre ROWIDTOCHAR (ROWID)  Version chaîne du ROWID CHARTOROWID (ch1)  Conversion de la chaîne en ROWID  de tuple 

Figure 7.27 SELECT TO_CHAR(date_nais,'YYYY-MON-DD',

'NLS_LANGUAGE_FORMAT = french') FROM Employe WHERE TO_CHAR(date_nais, ‘YYYY’) = ‘1984’;

 La date n’est pas stockée comme une constante, mais avec un format interne particulier à Oracle qui inclut les éléments suivants : siècle, année, mois, jour, heure, minute et seconde. La date représentée avec un tel format  ne peut donc pas être utilisée directement dans un prédicat comme peut l’être une constante de chaîne telle que ‘JAN‐25‐94’. Elle doit être transformée  pour  obtenir  une  chaîne  qui  peut  être  comparée  à  une  autre  chaîne.  La transformation  inverse  de  la  date  en  une  date  de  format  interne  est  effectuée  par  la fonction  To_Date(). L’importance  des  dates  justifie  l’implémentation  d’une arithmétique simplifiée avec les  dates (avec les opérateurs arithmétiques  +  et  ‐).                                                                                                       Dans certains systèmes SGBD, la constante ajoutée ou retranchée peut être assortie d’une unité : DAYS ou MONTHS. Chez Oracle,  l’unité est exclusivement et  implicitement  le jour (DAY). Les exemples suivants illustrent cette arithmétique :  a)SYSDATE  +  1,    pour  obtenir  la  date  du  lendemain  (DAY  est  l’unité  par  défaut  de Oracle); b)SYSDATE ‐ 7 DAYS, donne la date du même jour de la semaine précédente (Oracle); c) SYSDATE ‐ EMBAUCHE, l’évaluation donne le nombre de jours de travail.   d)SYSDATE+10  MONTHS  donne  la  date  du  jour,  10  mois  plus  tard  [pas  toujours implémentée]; 

Page 72: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

72

 La date peut être exprimée de la façon traditionnelle avec lʹannée, le mois et le  jour, ou selon  le calendrier  Julien  (depuis  le 1er  janvier 4712 BC) ou, autrement, en mois ou en jours  depuis  le  début  de  l’année.  Les  fonctions  de  conversion  utilisent  des masques (synonymes : gabarit, modèle, patterns) pour spécifier le résultat. Un masque de date est une composition avec les éléments syntaxiques ci‐dessous.  

Éléments  Exemples de masque  Exemple de sortie YYYY  ʹYYYY‐MMʹ  1994‐12 MM  ʹMMʹ  12    (mois de décembre) DD  ʹYYYY/MM/DDʹ  1994/12/22 MON  ʹMON DD YYYYʹ  DEC 22 1994 MONTH  ʹMONTH**DDʹ  FEVRIER**24 

Figure 7.28   Où  les  caractères  ‐  ,  .  /  et  \  sont  des  caractères  littéraux  du  masque  reproduits intégralement dans le résultat de la fonction. Exemple :    TO_DATE(dateIn, ʹMM//YYYYʹ) ‐‐ La fonction retourne :  ʹ11//1998ʹ 

Transformation dʹune date externe en format interne  Une date en format externe est stockée dans la base de données avec un format interne très particulier.  Il  faut donc  convertir  le  format  lors de  lʹécriture  et de  la  lecture dʹun attribut du  type date. La  fonction To_Date()  transforme une date de  format externe en une date codée en format interne :  

To_Date(chaîne, masque [,nlsp])               Le masque (ou le gabarit) de la fonction précise comment doit être interprétée la chaîne de caractères lors de la transformation par la fonction To_Date().                                         Les paramètres : chaîne : est une chaîne de caractères représentant une date; masque :  ou  gabarit  sous  forme  dʹune  constante  de  chaîne  incluant  des  littéraux dʹaffichage nlsp :  constante  pour  spécifier  la  langue  nationale  :  'NLS_DATE_LANGUAGE =

'french' .  Exemple : INSERT INTO Ouvrier ('200056345', 'Vézina,'Claude','M','33.8',

To_Date(‘24-Jan-2000’,’DD-MON-YYYY’, ’NLS_DATE_LANGUAGE = french’),'u12', 'ps75');

Suppression du temps dans la date   Une date  insérée dans  la base de données Oracle par  la fonction SYSDATE est suffixée automatiquement par le temps composé de lʹheure, la minute et la seconde (le siècle est 

Page 73: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

73

aussi ajouté  et  rendu accessible). Cet   ajout  est  rendu possible  si  le  format par défaut permet lʹadjonction du temps réel. La fonction TRUNC() joue un rôle particulier dans le traitement des dates en supprimant le temps annexé à toute date créée et stockée dans la base.    Si le temps est  explicitement exclu par le masque, le système lʹenregistre comme étant 00:00:00  (minuit).  Pour  supprimer  le  temps  dans  la  date,  il  est  possible  dʹutiliser  le masque de  la  fonction TO_CHAR() ou de  faire appel à  la  fonction TRUNC(). Dans  ce dernier cas, la troncature sʹopère en enlevant la partie temps de la date.   Exemples:     TRUNC(SYSDATE) /*supprime le temps dans la date du jour retournée par la fonction SYSDATE*/  TRUNC(dateP)    /*retourne  seulement  la partie date de  lʹattribut datep. Le  temps  est supprimé de la date*/ 

Transformation dʹune date du format interne vers une chaîne de caractères Cette transformation consiste à passer du format interne de la date en un format externe utilisé par une application. 

TO_CHAR (attribut, masque [, nlsp]) où    

attribut : attribut du type DATE dans une relation masque : format de date pour la chaîne d sortie  nlsp :  spécification  de  la  langue  nationale  (american,  french,  english,....)  pour lʹexpression du mois. 

 La fonction TO_CHAR   peut supprimer le temps inclus dans le format dʹun attribut de type date.                                        Exemples : a) Afficher le numéro des employés embauchés après le 23 décembre 90 : 

SELECT noEmpl FROM Assignations WHERE TO_CHAR(debut,'DD/MON/YYYY) >'23/DEC/1990';--supp.du temps

 b) Afficher le nom, le numéro de poste et le rowid ( ou rid) de l’employé qui a débuté son travail le 24 septembre 1994 :  

SELECT nom, noPoste, ROWIDTOCHAR(ROWID) FROM Empl E, Assignations A WHERE E.noPoste= A.noPoste and

Page 74: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

74

To_Date('24/sept/1994','DD/MM/YYYY',NLS_DATE_LANGUAGE = french') = Trunc(debut);

 Cette adresse de tuple (rid) peut varier au cours du temps, car elle ne correspond pas à une  identité  d’objet  immuable.  Le  ROWID  sera  plus  utile  avec  le  SQL  intégré  parce qu’une variable hôte peut  l’utiliser dans un autre SELECT et accéder directement aux tuples. Le temps du  format interne de lʹattribut embauche est supprimé par la fonction Trunc  (debut,  ʹDDʹ). La  fonction de  troncature modifie  la date pour  conserver  que  le jour.   c) Afficher le mois en anglais du début (typé Date) de contrat et le numéro des employés embauchés après le 23 février 1990 : SELECT TO_CHAR(debut, 'MONTH', 'NLS_DATE_LANGUAGE= american'), noEmpl FROM ASSIGNATIONS WHERE debut>TO_DATE('23-FEV-1990','DD-MON-YYYY,'NLS_DATE_LANGUAGE = french');                          La comparaison est  faite selon  lʹordre  lexicographique des chaînes.   La  fonction MIN() retournera donc  la  plus  petite date dans  lʹensemble des dates,  tandis  que  la  fonction MAX(), la plus grande. 

SELECT MAX(debut) FROM Employe WHERE age between 18 and 45;

Cette clause fournit la date de début la plus récente pour les employés de 18 à 45 ans. 

7.16 Fonction définie par l’utilisateur Il est possible de définir une fonction dʹutilisateur qui est stockée dans le dictionnaire de la  base  de  données  sous  forme  dʹun  objet  (persistant  et  sans méthode)  et  que  toute application peut utiliser dans une expression SQL, et cela partout où il peut y avoir un attribut. Cet accès est possible sous réserve que lʹutilisateur ait reçu les droits appropriés par le propriétaire de la fonction. La définition de nouvelles fonctions enrichit la librairie des fonctions SQL et permet d’adapter le système aux besoins de traitement.   

CREATE FUNCTION Profit (prixVente IN real, cout IN real) return real is diff real; BEGIN diff := prixVente - cout; return (diff); END Profit;

.   ‐‐ Notez bien  le point  ‘’.’’ qui arrête lʹéditeur PL/SQL du module Oracle SQL*Plus]   

Page 75: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

75

Il  faut noter que  chaque paramètre  est  fourni avec  son  type qui ne  comprend pas  les éléments de longueur pour la chaîne et ceux de précision et d’échelle pour les nombres.   Cette fonction de lʹutilisateur peut être appelée dans une requête SQL comme toute autre fonction interne de SQL . 

SELECT article, Profit(prixVente, cout) FROM Article_v WHERE prixVente > cout;

 Cette fonction est stockée dans le dictionnaire comme un objet.  Ces objets sont identifiés en  consultant  la  table  USER_OBJECTS.  De  plus,  le  texte  de  la  fonction  est  aussi disponible dans la table USER_SOURCE.  

SELECT OBJECT_NAME, OBJECT_TYPE FROM USER_OBJECTS; SELECT TEXT FROM USER_SOURCE WHERE NAME = 'Profit';

                         Le corps de la fonction est un bloc de PL/SQL pouvant incorporer, selon les besoins, une ou plusieurs clauses SQL ou des appels de fonction.  Voici une autre fonction dʹutilisateur Longc pour compter le nombre de consonnes dans une valeur dʹattribut   dont  le  type correspond à celui dʹun attribut du dictionnaire. La  fonction TRANSLATE() ne peut pas être utilisée avec un NULL comme 3e argument, car la valeur retournée est alors aussi null.  CREATE FUNCTION LONGC(nom IN varchar2) return number

IS nom_fam Ouvrier.nom%type; /* type de nom_fam équivalent à celui défini dans le dictionnaire pour nom */ lon number :=0; BEGIN nom_fam := REPLACE(TRANSLATE(nom,'aeiouy','2'),'2', null); lon := LENGTH(nom_fam); return(lon); END;

                            La  fonction est  stockée dans  le dictionnaire de  la base de données  sous  la  forme dʹun objet appelé LONGC. Cette fonction est appelée dans une clause SQL standard : 

SELECT nom, LONGC(nom) FROM Ouvrier;

La réponse est le nombre de consonnes présentes dans le nom de chaque ouvrier inscrit dans la base. 

Page 76: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

76

Récursivité des fonctions   Une fonction dʹutilisateur ou un bloc PL/SQL peut être récursif. Par exemple, la fonction factorielle est définie en exploitant la récursivité de la fonction. 

CREATE FUNCTION Fact (n Integer) return Integer is begin if n = 1 THEN return 1; else return (n* fact(n-1)); END IF; END FACT; /

La  fonction  Fact  est  appelée  et  exécutée  pour  calculer  par  exemple  le  factoriel  des nombres inférieurs à 20. 

SELECT Fact(nombre) FROM TableNombres WHERE nombre < 20;

 La définition de nouvelles  fonctions permet au développeur de  réutiliser  le  code déjà testé et dʹaccélérer le développement des applications.             

7.17 Fonctions SQL diverses 

Fonction NVL() La fonction NVL() permet de simuler l’alternative et de traiter la valeur nulle. 

NVL(expr1,expr2)  Fonction NVL  : 

Si la valeur de expr1 est non nulle  alors retourner la valeur de expr1; sinon retourner la valeur de expr2; 

  Le type de la valeur retournée est celui de expr1.                                  Exemple : Afficher  le numéro des  employés  et  leur quart de  travail.  S’il n’y  a pas de quart de travail spécifié (null), afficher le message suivant :  ‘quart_libre’.  

SELECT noEmpl, NVL(quart,'quart_libre') FROM Assignations;

 Fonction DECODE() La  fonction DECODE()  du  système Oracle  implémente  une  alternative multiple.  Elle correspond à la clause CASE de la norme SQL‐92.   DECODE (source,expr1,expr1.1,expr2,expr2.1,expr3,expr3.1,val_defaut)                            

Page 77: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

77

Fonction algorithmique du Decode() : Si source = expr1 THEN return(expr1.1)   si source = expr2 THEN return(expr2.1)     si source = expr3 THEN return (expr3.1) else return(val_defaut); ‐‐ si aucun match nʹest trouvé  La fonction DECODE() est de type tuple et compare la valeur de lʹexpression source avec le  résultat  de  l’évaluation  de  l’expression  expr1  et,  si  la  comparaison  est  vérifiée  la fonction  retourne  expr1.1.  Dans  le  cas  contraire  la  comparaison  se  poursuit  avec l’expression espr2 et ainsi de suite. Si aucun  test n’est positif,  la valeur ou  l’expression par défaut est évaluée et le résultat retourné par DECODE.   La fonction DECODE peut être utilisée avec un nombre variable dʹarguments. 

Employe(matricule*, nom, age, sexe, salaire, noDep)  SELECT matricule,CONCAT(decode(sexe,’F’,’Mme’,’M ’,’Mr ’,’?‘),nom) FROM Employe WHERE (salaire /12) > 3450.00);

Fonction  SIGN() La fonction Sign(n) évalue le nombre  n.  Si n est positif, elle retourne +1; si n est 0, elle renvoie 0;  si la valeur est négative, la fonction retourne la valeur  ‐1 : Voici  une  requête  plus  complexe  qui  utilise  la  fonction  SING(n)  pour  augmenter  de moitié le salaire des employés de moins de 45 ans dont le salaire actuel est supérieur à 15 000 $ et pour doubler le salaire de ceux qui gagnent moins de 15 000 $.   SELECT noDep, Sum(Decode(Sign(salaire-15000),+1, salaire*1.5,-1, salaire *2, salaire)) FROM Employe WHERE age < 45;

COALESCE() Cette  fonction  a  un  nombre  variable  de  paramètres  typés;  elle  retourne  la  valeur  du premier paramètre parmi ceux de  la  liste dont  la valeur est non nulle. Par contre, elle retourne la valeur NULL si tous les paramètres sont nuls après leur évaluation.  Soit A,  B,  C  dont  les  valeurs  sont  respectivement  5,  3,  4.  L’exécution  de  la  fonction COALESCE (A, B, C) retourne 5 avec un type correspondant à celui du paramètre typé ou à celui obtenu après conversion. Ainsi si A est typé Float(2, 2), B  est typé Float(5, 2) et C est typé entier, le résultat de la fonction sera 5, et la valeur  typée Float(5, 2).                            SELECT article, COALESCE (prixVente, cout) 

FROM Inventaire;  

Page 78: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

78

Par  exemple,  la  figure  ci‐dessous  donne  les  règles  de  transformation  pour  les  types implémentés dans DB2‐V2.  La longueur, la précision et lʹéchelle sont fournies ou imposées par le type cible résultant de  la  transformation.  Pour  bien  comprendre  ce  résultat,  il  faut    se  rappeler  que lʹinterprète  SQL  traite  une  fonction  par  une  recherche  de  son  nom  dans  le  schéma spécifié. Par la suite, il   vérifie si le type de chaque paramètre est identique ou, dans le cas contraire, il cherche un type commun à tous les paramètres en les transformant selon des règles propres à chaque SGBD, voir le tableau ci‐dessus).  

smallint ‐‐>  integer ‐‐>   decimal ‐‐>  double char  varchar ‐‐>  long varchar ‐‐>  cblob graphic ‐‐>  vargrahic ‐‐>   long vargraphic ‐‐>  dbclob blob ‐‐>   blob  cible idem   date ‐‐>  date  cible idem   time ‐‐>  time  cible idem   timestamp ‐‐>  timestamp  cible idem                 

 Exemple avec DB2‐V2  Soit le schéma  de la relation UsineProd comprenant les attributs typés ci‐dessous :   UsineProd(no_us char(2), production  integer, cMateriau decimal(6,1), coutTot decimal (4,2))                            

UsineProd :  noUs  production  cMateriau  coutTot   u2  25  234.2  456.78   u1  null  1764.8  null   u3  null  null  876.41   u5  ‐1  ‐1  ‐1 

 N.B.  la  valeur  ‐1  pour  lʹattribut  production  signifie  que  lʹon  ignore  sʹil  y  a  eu  une production à lʹusine, tandis que le NULL signifie que  la production a eu lieu, mais elle est nulle, i.e. nʹa pas été gardée.  SELECT noUsine, COALESCE(production, c_materiau, cout_tot) pmc FROM Usine_Prod WHERE no_us IN ( 'u1', 'u2', 'u3', 'u4', 'u5', 'u6');  La réponse est la suivante :                 

nomUs  pmc  type du résultat u2  25.0 ‐‐> le type est décimal 6.1 u1  1764.8 ‐‐> le type est décimal 6.1 

Page 79: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

79

u3  876.4 ‐‐> le type est décimal 6.1 u5  ‐1.0 ‐‐> ? pour la production 

NULLIF() Cette  fonction a deux paramètres, p1 et p2 de  type compatible et  retourne une valeur NULL si p1 = p2, sinon p1.     La réponse contient deux nulls pour  lʹattribut pmc, dont lʹune est justifiée par la présence dʹune instance ayant la valeur ‐1. 

SELECT noUs, NULLIF(c_materiau,-1)AS pmc FROM UsineProd;

 noUs  pmc u2  234.2 u1  1764.8 u3  NULL u5  NULL 

                   7.18 Fonctions pour les agrégats avec les tuples sélectionnés  Ces  fonctions de  type ensembliste  sont appliquées à un groupe de  tuples et  renvoient une valeur calculée en ignorant les valeurs nulles dans les tuples (sauf pour la fonction Count(*)).  Ces  fonctions  dʹagrégation  acceptent  aussi  les  modificateurs ALL    et DISTINCT. Les fonctions peuvent être utilisées dans le SELECT et dans le WHERE d’une requête. 

Fonctions SQL dʹagrégation Ces fonctions sont appliquées à des groupements de tuples préalablement formés par le GROUP BY. En dʹautres mots, lorsquʹil y a formation de groupements, cela définit aussi la portée des fonctions dʹagrégation du SELECT .                                                     

Fonctions dʹagrégation  Description  AVG  (attribut)   Moyenne  Count (*) | (DISTINCT  attrib)   Comptage (NULL inclus)  MAX et MIN  ([distinct] expr1)   Val max ou min dans un ensemble  SUM  ([DISTINCT,] tauxH)   Somme de valeurs  STDDEV  (DISTINCT|ALL], attrib)   Ecart‐type de l’argument  attrib  VARIANCE([DISTINCT|ALL],attrib)   Variance 

Figure 7.29  La portée de toute fonction dʹagrégation est limitée à chaque groupe ou partition d’une relation  de  base  ou  d’une  relation  intermédiaire  calculée  au  regard  de  la  liste  des attributs  utilisée  pour  définir  le  groupement    listé  dans  le GROUP  BY.  Lʹabsence  du GROUP BY définit  implicitement  la portée comme étant celle de toute  la table obtenue par le calcul de la requête.  Exemples avec la base BD1 

Page 80: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

80

a) Lister pour  les  clients  ʹSergeʹ  et  ʹTedʹ  la moyenne des  articles  achetés  (Ventes) peu importe la transaction. 

SELECT Avg(qte) [as] moy_Serge_ted FROM Ventes WHERE nom = 'Serge' or nom = 'Ted';

 Lʹabsence du GROUP BY fait en sorte que la moyenne est calculée avec tous les tuples de la  table  Ventes.  L’attribut  nom  ne  peut  pas  apparaître  dans  le  SELECT,  puisque  la fonction AVG()  s’applique  sur  l’ensemble des  tuples  sélectionnés,  la  réponse  ne  peut avoir qu’un seul tuple et excluant la possibilité d’avoir une moyenne pour les achats de ʹsergeʹ et une autre pour ʹtedʹ. Cette ambiguïté est détectée dès lʹétape dʹinterprétation de la clause SQL.   b) Lister les quantités maximale et minimale des articles vendus jusqu’à maintenant : 

SELECT Max(qte), Min(qte) FROM Ventes;

 La  sélection  est  formée  de  tous  les  tuples  en  raison  de  l’absence  du  prédicat.  Les fonctions  max()  et  min()  sont  alors  appliquées  sur  cet  ensemble  de  tuples,  en  ne considérant que  l’attribut qte pour afficher  la plus grande et  la plus petite valeur. Les fonctions d’agrégation peuvent être aussi imbriquées à plusieurs niveaux.   c) Compter les articles en inventaire dont la vente entraîne une perte. 

SELECT Count(article) FROM Inventaire WHERE prixVente < cout;

 d) Compter le nombre de ventes faites à des personnes de noms distincts : 

SELECT Count(DISTINCT nom) FROM Ventes;

 Remarque : S’il existe un index sur lʹattribut nom, le calcul de la requête en tirera profit, puisqu’il  s’agit  essentiellement d’un  comptage possible par  la  consultation de  lʹindex. Dans  le  cas  contraire,  cette  requête  est  exécutée  par  une  projection  de  l’extension  de Ventes,  la  suppression des doublets par un  tri et    finalement,    le comptage des  tuples dans la relation intermédiaire du calcul.  Lister  le nom des clients ayant achetés des articles dont  la quantité correspond au plus grand nombre d’un article quelconque déjà vendu dans une même transaction.  

SELECT nom FROM Ventes WHERE qte = (SELECT Max(qte) FROM Ventes);

 

Page 81: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

81

La sous‐requête est évaluée au début de l’exécution et la valeur obtenue est substituée à la sous‐requête placée entre parenthèses.                               

7.19 Formation de groupements avec les tuples sélectionnés Il  est  possible  de  regrouper  les  tuples  sélectionnés  dans  le  calcul  dʹune  requête  en fonction d’un  ou plusieurs  attributs. Le  groupement  inconditionnel  implique  tous  les tuples,  tandis que  le groupement  conditionnel  impose un  critère  supplémentaire pour que les tuples regroupés soient retenus dans la réponse. Cette opération de filtrage des groupes est réalisée dans lʹavant dernière étape. i.e. avant  celle qui précède le tri. 

7.19 .1 Regroupement inconditionnel des tuples Tous  les  groupes  formés  avec  l’extension  de  la  réponse  et  sur  la  base  dʹune  liste dʹattributs  sont  retenus  et  affichés  sans  faire  l’objet  d’aucun  autre  filtrage.  Chaque groupe correspond obligatoirement à un tuple de la réponse.  Exemples : a) Lister  le nom des clients et  la quantité  totale de produits achetés qui sont encore en inventaire. 

SELECT nom, sum(qte) FROM Ventes WHERE article IN

(SELECT article FROM Inventaire WHERE cout is NOT NULL ) --articles en inventaire

GROUP BY nom;  Remarque : L’argument du GROUP BY doit  inclure  obligatoirement  tous  les  attributs présents dans le SELECT, sauf ceux traités par une fonction dans la clause de 1er niveau. Cette fonction de groupement est exécutée après la sélection et la projection. Le schéma de  la  réponse  est  formé  des  attributs  de  la  fonction  de  groupement  plus  ceux  des fonctions d’agrégation. Les articles vendus encore en inventaire sont regroupés par nom d’acheteur et la somme est calculée pour chaque groupe.                    b) Lister  les  transactions de Ventes  (tous  les  attributs)  concernant  les  achats d’articles effectués avec une quantité égale à la quantité maximum déjà vendue pour cet  article.     

SELECT article, qte, nom FROM Ventes WHERE (article, qte) IN -- notez l'usage des parenthèses

(SELECT article, max(qte) FROM Ventes GROUP BY article);

 

Page 82: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

82

La  sous‐requête  est  calculée  en  premier;  l’extension  de  Ventes  fait  l’objet  d’une projection  et  le  résultat  est  trié  pour  former  des  groupes  virtuels  au  sein  de  la  seule relation  intermédiaire  constituée  des  tuples  formés  avec  les  articles  et  les  quantités maximales pour  chacun. Le prédicat d’inclusion du premier WHERE utilise un  tuple comme argument.                      

nom*  article*  qte*    article*  max(qte)   Serge  a1  3    a5  3   Ted  a2  5    a2  5   André  a1  2    a7  5   Serge  a2  4    a3  6   Jocelyn  a1  2    a1  7   Serge  a3  4         Valérie  a7  3         Lucie  a7  2  réponse    article  qte  nom Serge  a5  3    a1  7  Serge Serge  a7  5    a2  5  Ted Christine  a3  6    a3  6  Christine

 

Serge  a1  7    a5  3  Serge Figure 7.30 

La réponse sous‐tend  le choix de tuples en fonction d’une condition qui est évaluée au regard du contenu d’une autre table. C’est en quelques sorte une expression de jointure.                                                 

Formulation du GROUP BY avec une fonction Le  GROUP  BY  peut  contenir  un  ou  plusieurs  attributs  ou  des  fonctions.  Lorsquʹil contient une  fonction, celle‐ci doit être en  tout point  identique à  la même  fonction qui apparaît dans le SELECT.  

SELECT sum(QTE), TO_CHAR(dateDebut,'YYYY-month')as mois_an FROM Production WHERE TO_CHAR(dateDebut,'YYYY') = '1998' GROUP BY TO_CHAR(dateDebut,'YYYY-month') ORDER BY To_Date(TO_CHAR(dateDebut,'YYYY-month'),'YY-MM');

 Une  petite  différence  syntaxique  rend  lʹexpression  du  groupement  inacceptable  pour lʹanalyseur syntaxique !  

SELECT sum(QTE), TO_CHAR(dateDebut,'YYYY-MONTH')as mois_an FROM Production WHERE TO_CHAR(dateDebut,'YYYY') = '1998' GROUP BY TO_CHAR(dateDebut,'YYYY-month') ORDER BY To_Date(TO_CHAR(dateDebut,'YYYY-month'),'YY-MM');

 La différence  syntaxique apportée par  le gabarit  ʹmonthʹ   écrit en minuscules  invalide lʹexpression du GROUP BY  ! Notez  aussi que,  si  le groupement doit utiliser une vue 

Page 83: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

83

relationnelle,  il  faut que  chaque  colonne de  celle‐ci    transformée par une  fonction  soit définie avec un alias.   

CREATE OR REPLACE view V2 [as] SELECT Trunc(dateP), sum(QTE) FROM Production;

Groupement avec une vue relationnelle Le groupement  utilisant une vue doit définir un libellé simple ou un alias pour chaque colonne de la vue. Le renommage de la colonne dʹune vue transformée par une fonction est obligatoire.  Create or Replace view V2 [as]

SELECT Trunc(DATEP) [as] dateProduction, Sum(QTE) [as] total_production FROM Production Group By Trunc(DATEP);

 Les alias peuvent être lʹobjet dʹune référence dans une clause SQL :      

SELECT dateProduction, total_production FROM V2 WHERE Trunc(dateP), = Trunc(SYSDATE);

7.19.2 Regroupement avec filtrage conditionnel des groupes Les tuples sélectionnés dans une première étape forment une table temporaire au sein de laquelle  les  tuples  sont partitionnés par  le GROUP BY. Une partition  n’est  conservée dans la réponse que si la condition de filtrage exprimée par le Having est vérifiée.  Exemples :  a)Lister  le  nom  des  acheteurs  qui  ont  fait  plus  de  deux  achats  (chaque  groupe  ou partition devra comprendre plus de deux tuples) dʹun article en inventaire. 

SELECT NOM FROM VENTES WHERE ARTICLE in (SELECT ARTICLE FROM INVENTAIRE

WHERE COUT is NOT NULL) GROUP BY NOM Having COUNT(*) >2; --*signifie un comptage de tuples

 La  clause HAVING Count()  est  appliquée  à  chaque  partition  (interne)  formée  par  le GROUP BY. Cette clause agit comme un mécanisme de filtrage des groupes. Le résultat de  la  sous‐requête  est  toujours  une  seule  relation  dont  l’extension  est  ordonnée  par l’argument  simple  ou  complexe  du GROUP  BY  .    Ensuite,  la  projection  sur  nom  est effectuée sur nom.  b)Lister  en  ordre  alphabétique  de  nom,  le  nombre  des  achats  effectués  par  chaque personne. 

Page 84: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

84

SELECT NOM, Count(nom) [as] Total FROM VENTES WHERE article in (SELECT article FROM INVENTAIRE

WHERE COUT is NOT NULL) GROUP BY nom Having Count(*) > 2; ORDER BY Total;

Le tri final des tuples de la réponse est effectué après la dernière projection de sorte quʹà ce moment lʹalias Total est défini et peut être utilisé par le tri.  c) Lister  le nom des acheteurs d’articles présentement en  inventaire et dont  le coût est plus élevé que 10 $. Regrouper les transactions par nom en ne gardant que les groupes dont la quantité totale est supérieure à 10 et afficher le total des achats effectués.     

SELECT NOM, Sum(qte) FROM VENTES WHERE article in (SELECT article FROM Inventaire WHERE COUT is NOT NULL and cout > 10) GROUP BY nom HAVING Sum(qte) > 10;

 Une fonction d’agrégation ou de groupement est utilisée partout où il peut y avoir une variable ou un attribut. La projection est calculée comme dans la dernière opération, i.e. après le filtrage des groupes.  Exemple : Identification des doublets dans une relation  Pour définir une clé primaire à la table Employe, il faut au préalable vérifier lʹabsence de tuples identiques dans lʹextension courante de Employe.  a‐ Modification du schéma de la table Employe. ALTER TABLE EMPLOYE ADD PRIMARY KEY(noEmpl);

**** ERROR 02299 DUPLICATE ROWS **** b‐ Identification des tuples dupliqués. Le groupement peut être utilisée pour vérifier les doublets : 

SELECT noEmpl FROM Employe Having Count(*) > 1;

 noEmpl 

995  Ensuite, il suffit de faire l’affichage des tuples dupliqués. 

SELECT * FROM Employe WHERE noEmpl = 995; 

Page 85: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

85

                                            noEmpl  nom   ville 995  Paul  Québec 995  Paul  null 

 d‐ Suppression des tuples inutiles dans la table Employe 

DELETE FROM EMPLOYE WHERE NOEMPL = 995 AND VILLE IS NULL;

 e‐ Modification du schéma de Employe et création de la clé primaire. 

ALTER TABLE EMPLOYE ADD PRIMARY KEY(NOEMPL);  

7.20 Jointure SQL Lorsquʹune requête utilise les attributs de deux ou plusieurs tables, soit dans la réponse, soit dans le prédicat, le calcul fait appel à une jointure naturelle ou à une jointure thêta. Cet  opérateur binaire permet de joindre les tuples des tables référées par les opérandes et cela, chaque fois qu’une paire de tuples vérifie la condition de jointure (thêta).                                                            

7.20.1 Jointure naturelle La jointure naturelle implique une condition de jointure particulière qui utilise tous (ou avec SQL‐92 une partie des attributs communs) les attributs de même nom dans lʹune et lʹautre des relations opérandes.  Avec la base BD3 Dotation des ressources humaines, la jointure  entre  les  tables  Assignations  et  Postes  est  possible  par  lʹentremise  de  la condition de jointure dans laquelle les attributs communs jouent un rôle essentiel.  Par exemple, trouver le matricule (noPoste) des employés qui occupent un poste.   

SELECT noEmpl FROM Assignations A, Postes P WHERE Assignations.noPoste = Postes.noPoste;

 Cette jointure est naturelle parce que lʹattribut utilisé dans la jointure porte le même nom dans les deux tables opérandes. En SQL‐92, la formulation de cette jointure naturelle est plus simple. 

SELECT NOEMPL FROM ASSIGNATIONS NATURAL JOIN POSTES;

 La  formulation demeure  la même, quʹil y ait un ou plusieurs attributs dans  la  jointure naturelle.   Si la jointure naturelle doit être restreinte à un seul attribut de même nom dans chaque opérande,  il  suffit de  le nommer  explicitement avec  la  clause USING(). Ce  sera  le  cas 

Page 86: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

86

lorsque la clé est composée de plusieurs attributs qui sont aussi la clé étrangère dans une autre relation.   Une  jointure pourrait nʹexploiter quʹun  seul  attribut de  la  clé  étrangère. Par  exemple, dans  la  base Dotation  des  Ressources Humaines,  il  suffit  dʹenrichir  le  schéma  de  la relation Postes avec lʹattribut villePoste pour obtenir une clé composée. Du même coup, le schéma de la table Assignations est aussi enrichi du même attribut et la clé étrangère est composée de trois attributs.      

Postes (noPoste*, villePoste*, description) Assignations(noPoste*, villePoste*, noEmpl*, debut, quart)

                                       Pour faire une jointure naturelle en nʹutilisant que lʹattribut noPoste, il suffit de formuler la clause ainsi : 

SELECT noEmpl FROM Assignations JOIN Postes USING (noPoste);

 Pour faire une jointure basée sur les deux attributs de la clé étrangère :     

SELECT noEmpl FROM Assignations JOIN Postes USING (noPoste)

Assignations JOIN Postes USING (villePoste);                             NB  : En SQL‐92, les attributs de  jointure naturelle explicitement utilisés dans le USING ne doivent pas être préfixés dans la liste du SELECT et dans le WHERE.                 

7.20.2 Jointure thêta (jointure sous condition thêta) Pour la jointure thêta, la jointure naturelle est augmentée dʹune sélection formulée avec une  condition plus  ou moins  complexe. Cette  sélection  est  effectuée de préférence  en même temps (mode pipeline) que la  jointure. Par exemple, sʹil faut trouver les matricules (noEmpl) des employés qui occupent un poste de mécano, la jointure est de type thêta et est  légèrement  plus  complexe  que  celle  de  type  naturel.  En  SQL‐92,  cette  première jointure est formulée avec lʹopérateur JOIN.   

SELECT noEmpl FROM Assignations [as] A JOIN Postes [as] P

ON A.noPoste = P.noPoste and description = 'mécano';  Dans ce cas‐ci, la clause ON permet de spécifier la condition de jointure avec les attributs qui peuvent avoir un nom différent tout en partageant le même domaine. Il est toutefois possible de formuler une jointure thêta sans faire appel à l’égalité sur les attributs. Dans ce cas, la jointure sʹapparente à un produit cartésien assorti dʹune condition de filtrage.                                    

Page 87: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

87

7.21 Division relationnelle Lorsqu’une requête suppose  la quantification universelle d’au moins un attribut d’une relation de base ou dʹune relation intermédiaire, il faut songer à la division relationnelle. C’est  un  opérateur  utile, mais moins  utilisé  dans  les  activités  courantes  que  les  cinq opérateurs  dits  essentiels  ou  de  base.    Le  dividende  de  la  division  est  une  relation intermédiaire  constituée  avec  un  lot  dʹattributs  de  la  sortie  augmenté  avec  l’attribut quantifié.  Le  diviseur  est  une  relation  intermédiaire  formée  de  l’attribut  quantifié universellement.  Ces  relations  intermédiaires  sont  calculées  par  des  opérations relationnelles sur les relations de base de données.                           Exemple :  Lister le nom des clients ayant acheté un exemplaire de tous les articles actuellement en inventaire dont le prix de vente est inférieur à 35 $.  En  algèbre  relationnelle  la  réponse  serait  obtenue  simplement  par    la  division algébrique.    

Ventes1**(article, nom) ÷ Inventaire1** (article)      Les  relations Ventes1** et  Inventaire1**  sont des  relations  intermédiaires obtenues par une projection appropriée sur une relation de base. Par exemple au regard de la question précédente,  le diviseur  Inventaire1 est  formé des articles en  inventaire dont  le prix de vente est moins que 35.00 $. La division relationnelle n’est pas un opérateur essentiel, car elle  peut  se  formuler  avec  une  expression  complexe  composée  que  des  opérateurs élémentaires  comme  la projection,  la  sélection  et  la différence. Les points  essentiels  à retenir dans la formulation d’une division sont  les suivants :    a) Le dividende est une relation qui fournit les attributs de la réponse recherchée.  b) Le diviseur est une relation qui contient l’attribut quantifié universellement. Le point critique est l’identification de l’attribut quantifié universellement. Il est souvent précédé du mot tous ou toutes.  

7.21.1 Division relationnelle en SQL Une implémentation possible en SQL de la requête ci‐dessous fait appel au GROUP BY et au Having  Count().   Lister le nom des clients ayant acheté un exemplaire de tous les articles actuellement en inventaire dont le prix de vente est inférieur à 35 $. Rappelons qu’il s’agit de trouver le nom des clients actuels qui apparaissent dans la table Ventes en combinaison avec tous les articles qui sont dans la table Inventaire. 

SELECT nom FROM Ventes V WHERE article in

(SELECT article FROM Inventaire I

Page 88: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

88

WHERE I.prixVente < 35.00 and cout is NOT NULL) GROUP BY nom Having Count(DISTINCT V.article) =

(SELECT Count(DISTINCT article) FROM Inventaire WHERE prixVente < 35.0);

                  Inventaire :  article*  prixVente  cout    Count (DISTINCTarticle)   a5  12  8    4 (diviseur)  a1  10  5       a2  20  15       a7  15  15    Nombre d’articles vendus à moins de 35$   a3  25  null       a16  45  34                                                           

Ventes :     nom*     article*  qte*   Serge  a1  3   Ted  a2  5   André  a1  2   Serge  a2  4   Jocelyn  a1  2   Serge  a3  4   Valérie  a7  3      Lucie  a7  2      Serge  a5  3      Serge  a7  5     Christine  a3  6 

 

    Serge  a1  7 Figure 7.30a 

                     N.B. Le groupement est fait avec lʹattribut de la réponse et la sous‐requête est formulée avec  lʹattribut du diviseur. Notez aussi que  lʹattribut du diviseur et celui du dividende nʹétant pas la clé, il faut supprimer les valeurs en double par le mot clé DISTINCT. Le HAVING Count() permet de garder que les tuples des clients qui ont acheté tous les articles encore en inventaire et dont le prix de vente est inférieur à 35 $.   Si  l’opérateur de division était directement  implémenté dans  le  langage ou disponible comme une  fonction en  librairie,  la  formulation de  la requête deviendrait relativement simple en dépit de sa complexité inhérente. 

SELECT nom FROM Ventes WHERE FOR_ALL article in (SELECT article FROM Inventaire WHERE prixVente < 35.00 and cout is NOT NULL);

Serge 

Having Count(*) = 4

Page 89: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

89

 Une  autre  façon moins  élégante, mais  qui  fournit  un  résultat  correct  est  le  calcul  de l’expression algébrique  équivalente à  la division au moyen des opérateurs de base de l’algèbre relationnelle:    (r ÷ s) = ΠR-S(r) - ΠR-S((ΠR-S(r) x s) - r) où R-S est une différence entre les attributs du schéma R et ceux de S.

Formulation de la division en SQL La  formulation de  la division  algébrique peut  être  réalisée  sans  trop de difficultés  en SQL. Nous  allons  illustrer  lʹalgorithme  de  passage  de  lʹalgèbre  à  La  clause  SQL  au moyen de lʹexemple suivant: Question  :  Lister  le  nas  des  étudiants  qui  sont  inscrits  à  tous  les  cours  offerts présentement. Lʹexpression relationnelle correspondante est la suivante :   

R1 (nas, noCours) ÷ R2 (noCours)  Les  dividende  et  diviseur  sont  obtenus  par  des  opérations  sur  les  relations  de  base. L’attribut noCours  partage le même domaine sémantique.  

Etudiant :  nas*  age  noCours*  frais  Classe :  noCours*  prof   n20  23  ift‐5  50    ift‐5  Audy   n30  21  ift‐8  40    mat‐10  Gagnon   n40  19  art‐5  60    art‐5  Gagnon   n20  23  mat‐10  55    soc‐20   Laurence   n20   23  soc‐20  65    ift‐8  Bouquier   n20   23  art‐5  40    soc‐22  Dumas   n20  23  soc‐22  50         n25  22  art‐5  35         n50  20  mat‐10  45         n50   20  ift‐5  55       

Figure 7.30b          

a‐ Les cours dont  il est question dans  le dividende sont ceux choisis par  les étudiants. Cette relation intermédiaire peut être fournie par lʹexpression algébrique suivante : 

Π nas, noCours (Etudiant)

 b‐ Les cours dont il sʹagit dans le diviseur sont ceux offerts présentement et listés dans la table Classe. Cela  comprend  les  cours  qui  n’ont  pas  été  choisis,  bien  que  ceux‐ci  ne seront jamais dans la réponse. 

Π noCours (Classe)

La  division s’exprime alors avec ces deux opérandes de la manière suivante : Π nas, noCours (Etudiant) ÷ Π noCours (Classe)

 

Page 90: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

90

Les deux opérandes sont eux‐mêmes des expressions algébriques aussi complexes que cela est nécessaire. Si dans une SGBD, l’opérateur SQL pour la division est implémenté, alors  la  formulation  de  la  clause  est  immédiate. Mais  cet  opérateur  n’est  pas  encore présent dans le SQL. 

Algorithme général Pour  formuler  une  division  en  SQL,  on  peut  adopter  une  approche  basée  sur  le comptage des  tuples    (lʹautre  est  fondée  sur  la  logique du  1er ordre). Dans  lʹexemple précédent,  il  sʹagit  de  compter  combien  de  cours  différents  sont  choisis  par  chaque étudiant et ne retenir un étudiant dans la réponse que si ce nombre égale celui des cours distincts offerts par les classes présentement à lʹhoraire pour le trimestre en cours.   En premier, il  faut savoir que :  ‐ Lʹattribut (ou les attributs) de la réponse est celui qui sera utilisé dans le GROUP BY. ‐  Lʹattribut  quantifié  universellement  (tout)  et  qui  est  aussi  l’attribut  de  la  relation diviseur sera utilisé pour filtrer les partitions formées  par le Having. ‐  La  sous‐requête  dans  le Where  du  bloc  principal  exprime  la  relation  de  lʹopérande diviseur.   À partir de ces considérations l’algorithme d’écriture de la division est la suivante :  Protocole d’écriture de la clause SQL pour la division : 1‐ Exprimer  le dividende de  lʹexpression  algébrique  en  tenant  compte du prédicat de sélection imposé aux tuples. Exemple : tous les cours de 1999, ne sont pas tous les cours présents dans la relation Cours, mais bien une sélection de ceux‐ci.  2‐ Regrouper les tuples du dividende calculé par un GROUP BY formulé avec lʹattribut de la du schéma de la réponse escomptée.                                               3‐  Filtrer  les  partitions  par  un  Having  Count([distinct]  <attrib‐diviseur>)  qui  utilise lʹattribut du diviseur. Le DISTINCT est essentiel si lʹattribut du diviseur nʹest pas aussi la clé.                   4‐ Filtrer les partitions par un prédicat inclus dans la clause Having et qui comporte une comparaison avec une sous‐requête  formulée avec  lʹexpression algébrique du diviseur. Le DISTINCT n’est nécessaire que si lʹattribut du diviseur nʹest pas aussi la clé.  5‐ Supprimer dans le SELECT du début, les attributs qui ne sont pas dans le GROUP BY et y ajouter, au besoin, les fonctions désirées.  En SLQ :  noCours est une clé primaire, donc il n’y a pas de redondance à supprimer si la table est cohérente : 

SELECT nas FROM Etudiant

Page 91: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

91

GROUP BY nas Having Count(noCours) = (

SELECT Count(noCours) FROM Classe);

 Une fonction dʹagrégation peut être incluse dans la réponse : 

SELECT nas, Count (noCours), FROM Etudiant GROUP BY nas Having Count(noCours) = (

SELECT Count (noCours) FROM Classe);

Diviseur et dividende plus complexes  Le diviseur  est une  relation quelconque qui peut  être  fournie par un  calcul préalable rendu plus complexe en y ajoutant des sélections ou des jointures.  Exemple : Lister le nas des étudiants en informatique qui sont inscrits à toutes les classes de sociologie. Le dividende est ainsi ramené aux seuls étudiants en informatique  :  (σ SUBSTR(noCours, 1, 3) =  ʹiftʹ (Π noCours, nas (Etudiant) ))  De même pour le diviseur qui n’inclut que les cours de sociologie : (σ SUBSTR(noCours, 1, 3 = ʹsocʹ (Π noCours (Classe)))  La division est alors exprimée ainsi : (σ SUBSTR(noCours, 1, 3) = ‘ift’ (Πcours, nas (Etudiant) )) ÷  

(σ SUBSTR(noCours,  1,  3)  =’soc’ (Πcours (Classe))) 

 En SQL :   SELECT nas  

FROM Etudiant WHERE SUBSTR(noCours, 1,3) = 'ift' GROUP BY nas Having Count (noCours ) = (

SELECT Count(noCours) WHERE SUBSTR(noCours, 1,3) = ‘soc’ FROM Classe);

 2‐ Le dividende peut être aussi plus complexe si on ajoute un prédicat de sélection plus sélectif pour le regroupement des tuples. Lister le nas des étudiants ayant plus de 22 ans qui  suivent  des  cours  en  informatique  et  qui  sont  inscrits  à  toutes  les  classes  de sociologie.  Le dividende est transformé pour ne retenir que les tuples des étudiants ayant plus de 22 ans.                                    

Page 92: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

92

(σ age > 22 and SUBSTR(noCours, 1,3)='ift' (Π nas, noCours (Etudiant))

 La division est alors exprimée ainsi : (σ age > 22  and SUBSTR(noCours, 1,3)='ift' (Π nas, noCours (Etudiant) )   ÷   (σSUBSTR(noCours, 1,3)=  ʹsocʹ (Πcours (Classe) ))  En SQL :  

SELECT nas FROM Etudiant WHERE age > 22 and SUBSTR(noCours, 1,3)='ift' GROUP BY nas Having Count (noCours) = (

SELECT Count(noCours) FROM Classe WHERE SUBSTR(noCours, 1,3)= 'soc');

Mise à jour de l’extension d’une table : UPDATE  ( et DELETE) Il est possible aussi de réutiliser la même question fondée sur la division pour mettre à jour une relation. En effet la mise à  jour est précédée dʹune recherche, qui est formulée par un prédicat  de sélection qui peut être aussi complexe que l’exige la requête. Le but de cette sélection est d’identifier le ou les tuples à mettre à jour.  Exemple :  Diminuer de 10.00 $  les  frais pour  les étudiants qui ont été  inscrits à  toutes  les classes dʹinformatique.  

UPDATE Etudiant SET frais = frais - 10.00 WHERE nas IN ( SELECT nas FROM Etudiant WHERE SUBSTR(noCours, 1,3)='ift'

GROUP BY nas Having Count (cours) = (

SELECT Count(noCours) FROM Classe WHERE SUBSTR(noCours, 1,3)='ift'));

6.21.2 Approche par la logique On  peut  aussi  créer  une  autre  expression  SQL  en  utilisant  la  clause  EXISTS  pour implémenter  l’équivalent  de  la  division  relationnelle.  Prenons  comme  exemple  la question ci‐dessous avec la base DB3.  ‐ Lister le nom des clients ayant acheté un exemplaire de tous les articles actuellement en inventaire.  

Page 93: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

93

Cette  question  a  pour  réponse  le  nom  des  clients  ayant  une  certaine  propriété,  celle dʹavoir  acheté  tous  les  articles  en  inventaire. Examinons  en premier  le  cas particulier dʹun seul client dont le nom est ʹn5ʹ; ensuite nous généraliserons la requête. L’assertion, il  n’existe  pas  un  article  en  inventaire  qui  n’est  pas  vendu  à  ʹn5  doit  être  vraie.  Pour infirmer  ce  test,  il  suffit de  trouver un  contre‐exemple d’un  article  en  inventaire, par exemple ‘a2’ qui n’est pas mentionné dans une transaction de vente au client ʹn5ʹ. Si un tel article  (le contre‐exemple) existe,  il   est alors évident que  le client  ʹn5ʹ   ne peut pas être  dans  la  réponse  de  la  division,  puisqu’il  n’a  pas  acquis  cet  article  ʹa2ʹ.  Pour démontrer que  cet article  ʹa2ʹ est absent de  la  table Ventes pour  le  client  ʹn5ʹ,    il  faut effectuer une recherche dans la table Inventaire afin de confirmer que ʹa2ʹ est bel et bien en  inventaire  et vérifier quʹil nʹexiste pas une  transaction de vente pour  cet article au nom du client ʹn5ʹ  (représenté par la variable v.nom).  

SELECT ‘n5’ /*vide car 'n5' pas acquis tous les articles */ FROM Ventes V WHERE NOT EXISTS (

SELECT * FROM Inventaire I WHERE NOT EXISTS (

SELECT * FROM Ventes X WHERE X.article = 'a2' and X.nom = 'n5'));

 Si cette clause affiche une réponse, alors cela confirme que  l’article  ʹa2ʹ  est en inventaire et  n’a  pas  été  l’objet  d’une  transaction  dans  la  relation  Ventes.  Il  faut  maintenant formuler  une  condition  qui  garantit  qu’aucun  contre‐exemple  n’existe  pour  chaque client de la réponse, peu importe lʹarticle. On vérifie l’absence de contre‐exemple et, du même coup, les clients qui ont acheté tous les articles sont identifiés.  

SELECT nom FROM Ventes V WHERE NOT EXISTS (un contre-exemple pour le nom de chaque client testé un à un)

 Cette  clause  fournit  donc  les  clients  qui  ont  acheté  tous  les  articles  sur  la  base  de lʹabsence dʹun contre‐exemple. Le contre‐exemple correspond à un article en inventaire qui nʹest pas acheté par le client courant. Pour chaque article, il est formulé ainsi :  

(SELECT * FROM Inventaire I WHERE NOT EXISTS (aucun client pour l'article courant tel que testé par la sous-requête qui suit)

Page 94: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

94

La sous‐requête est donc formulée ainsi : (SELECT * FROM Ventes X WHERE I.article = X.article and X.nom = V.nom) ;

 En intégrant toutes ces clauses, on obtient la requête suivante :  

SELECT DISTINCT nom FROM Ventes V WHERE NOT EXISTS (

SELECT * FROM Inventaire I WHERE NOT EXISTS (

SELECT * FROM Ventes X WHERE X.article = I.article AND X.nom = V.nom)

) ;  Cette clause peut se  lire ainsi : Retenir  les  tuples dans  la  table Ventes, pour  les   clients ayant achetés un article de sorte qu’aucun tuple dans la table inventaire soit absent dans la table Ventes pour ce client et cet article.                                        Ventes :        Inventaire :     

nom*  article*  qte*    article*  prixVente  cout Serge  a1  3    a5  12  8 Ted  a2  5    a1  20  15 Serge  a5  3         

 Voici  une  trace  de  lʹexécution  de  cette  requête  SQL  formulée  avec  la  clause  logique EXISTS et avec les deux tables ci‐dessus :                                                                                          T u p l e   d e   V e n t e s    Tuple de Inventaire     Tuple de Ventes V    I    X   S e r g e , a 1 , 3      a5, 12, 8 (x)      Serge, a1, 3  (x)          Ted, a2, 5     (x)           Serge, a5, 3  ok                       a1, 20, 15 (x)      Serge, a1 ,3     (ok)   S e r g e ,   a 1 ,   3            Ted, a2, 5  (x)           Serge, a5, 3 x)   . . .  . . .    . . .             T e d , a 2 , 5              a5, 12, 15  (retenu)      Serge, a1, 3 (x)           Ted, a2, 5     (x)           Serge, a5, 3  (x) 

Page 95: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

95

          T e d ,   a 2 ,   5                    a1, 20, 8 (x)      Serge, a1, 3 (ok)           Ted, a2, 5  (x)         Serge, a5, 3 (x)              S e r g e ,   a 5 ,   3                a5, 12, 8  (x)       Serge, a1, 3 (x)           Ted, a2, 5 (x)            Serge, a5, 3 (ok)            S e r g e ,   a 5 ,   3          a1, 20, 15 (x)        Serge, a1, 3 (ok)            Ted, a2, 5  (x)             Serge, a5, 3 (x) 

 Suivi de l’évaluation de la clause SQL avec EXISTS 

Figure 7.31  Le  tuple  le  plus  à  gauche  n’est  conservé  que  s’il  n’y  a  pas  de  tuples  sélectionnés immédiatement à sa droite. L’implémentation directe du quantificateur universel dans le langage SQL rendrait la formulation plus naturelle et largement plus simple.   Exemple :   SELECT nom 

FROM Ventes  WHERE FOR ALL Inventaire.article;

 Le mot‐clé FOR ALL proposé   comme ajout possible dans  la dernière norme  sous‐tend alors la division relationnelle. L’attribut opérande du diviseur est celui qui est quantifié. Une autre solution hypothétique serait la suivante :  

SELECT nom FROM Ventes, Article DIVIDE [EXACTLY] Ventes BY Article ON Article ;

                7.22 Jointure externe gauche (left outer join) La jointure externe gauche est utile pour calculer efficacement certaines réponses que la jointure simple ou complète ne peut pas trouver directement. Par exemple, pour obtenir le  nom  des  articles  vendus  et  leur  prix  de  vente  s’il  est  connu,  il  suffit  de  faire  une jointure externe gauche. L’ajout des tuples qui ne participent pas à la jointure est effectué en dernier lieu, après la jointure.  

SELECT V.article, I.prixVente FROM Ventes V, Inventaire I Where V.article = I.article(+) ;

       

Page 96: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

96

nom*  article*  qte*  Inventaire :  article*  prixVente  cout Serge  a1  3    a5  12  8 Ted  a2  5    a1  10  5 André  a1  2    a2  20  15 Serge  a2  4    a7  15  15 Jocelyn  a1  2    a16  45  34 Valérie  a7  3         Lucie  a7  2  réponse :  article  prixVente   Serge  a5  3    a1  10   Serge  a7  5    a2  20   Christine  a3  6    a7  15   

 

Serge  a1  7    a5  12           a3  null   

Figure 7.31a  

La jointure est effectuée selon les termes de la condition de jointure, ensuite les tuples de la relation Ventes n’y participant pas sont ajoutés à l’extension de la réponse. Le résultat fournit  le nom  et  le prixVente des  articles  vendus,  incluant  ceux  qui ne  sont plus  en inventaire.  Le  (+)  identifie  la  table  qui  fournit  les  valeurs  nulles  aux  tuples  ajoutés, lesquels sont concaténés avec les tuples de la table de gauche qui ne participent pas à la jointure.  Il y aura autant de  (+) quʹil y a dʹattributs mis en relation par  la condition de jointure. Cependant, la grammaire SQL impose une contrainte qui limite la participation d’une même table à une seule jointure externe dans une requête. Si la requête exige une double jointure externe, il faudra soit renommer la table résultat de la première jointure externe par un alias, soit restructurer la requête.  En SQL‐92, la syntaxe de la jointure externe gauche est plus simple et plus explicite.  

SELECT V.article, I.prixVente FROM Ventes V LEFT OUTER JOIN Inventaire I ON V.article = I.article ;

 La clause ON indique les attributs de jointure qui peuvent avoir un libellé différent.                   

7.23 Jointure droite (right outer join) Dans ce cas, il y a ajout à la jointure, les tuples de la relation de droite ne participent pas à celle‐ci.  Exemple : Lister le nom et le coût des articles en inventaire déjà vendus et y ajouter ceux qui ne sont plus en inventaire, qu’ils aient été vendus ou pas.     

SELECT article, cout FROM Inventaire I, Ventes V WHERE I.article = V.article(+) and cout is NOT NULL;

Page 97: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

97

 Voici une clause SQL différente de la même requête. 

(SELECT article, cout FROM Inventaire WHERE cout is NOT NULL and article IN

(SELECT article FROM Ventes))

UNION (SELECT DISTINCT article, cout FROM Ventes);

Jointure complète Une telle jointure peut être calculée par l’union de deux tables de même schéma.  Par exemple, supposons  la base suivante représentant  les employés travaillant dans  les départements. Un  employé  travaille dans un  seul département, mais un département encadre le travail de plusieurs employés.  

Departement(noDep*, ville) Employe(noEmpl*,nas, nom, age, noDep)

  La  requête  consiste  à  lister  le  nas  des  employés  et  le  nom  du  département  où  ils travaillent, en incluant aussi les employés dont le nas est inconnu et qui travaillent dans certains départements dont le nom est aussi inconnu.  

(SELECT nas, nom FROM Departement D, Employe E WHERE D.noDep = E.noDep(+))

UNION (SELECT nas, nom FROM Departement D, Employe E WHERE D.noDep(+)= E.noDep);

 La première partie de  la clause fournit  les données sur  les départements encadrant des employés et inclut aussi les départements dont le nom est inconnu. La deuxième partie de  la  même  clause  donne  aussi  les  données  sur  les  départements  encadrant  des employés, mais  ajoute  aussi  les  employés  n’ayant pas  encore d’assignation de  travail dans un département.  Autres opérateurs : union, différence, intersection.  Ces  opérateurs  exigent  une  conformité  du  schéma  des  tables  opérandes. Ainsi,  pour faire l’union de deux extensions, il faut que leur schéma respectif ait le même nombre de colonnes et que chaque colonne correspondante ait un même domaine.  

Page 98: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

98

7.23 Union  Lʹunion relationnelle est similaire à  lʹunion ensembliste et requiert  lʹidentité du schéma pour  les  deux  opérandes. Ainsi,  on  obtiendra  une même  liste  des  articles  vendus  en quantité supérieure à 5 et ceux dont le prix de vente est supérieur à deux fois le coût par lʹexpression suivante :    

(SELECT article FROM Ventes WHERE qte > 5)

UNION (SELECT article FROM Inventaire WHERE prixVente > 2 *cout);

 Un tel énoncé est dit composé d’un bloc de niveau 1 et de 2 blocs de niveau 2. Il est traité en  trois étapes  : calcul de  la première sous‐requête de niveau 2, calcul de  la deuxième sous‐requête de niveau 2 et finalement, la réalisation de l’union (niveau 1) accompagnée de la suppression des doublets.   Pour garder  tous  les  tuples des deux ensembles y compris  les doublets,  il  faut utiliser lʹopérateur UNION ALL. Le  tri d’une  telle clause composée de deux sous‐requêtes  fait appel au rang des attributs (puisque les deux sous‐requêtes ont le même schéma) ou aux attributs de la première sous‐requête.      

(SELECT article FROM Ventes WHERE qte > 5)

UNION ALL (SELECT article FROM Inventaire WHERE prixVente > 2 *cout); ORDER BY 1; <- usage du rang pas recommandé!

        Le  résultat de  cette union  est  trié par un ORDER BY qui  se  réfère aux attributs de  la première relation soit par  leur rang, soit de préférence par  leur nom. En effet, certains changements  ultérieurs  faits  au  schéma  auront  des  effets  sur  la  requête  exprimée  au moyen du rang. 

7.24 Intersection Cet opérateur permet de trouver les tuples qui sont présents dans deux tables et dont le schéma  est  mutuellement  compatible.  Par  exemple,  la  clause  ci‐dessous  fournit  les articles vendus en quantité supérieure à 5 et qui sont toujours dans l’inventaire.  

(SELECT article FROM Ventes

Page 99: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

99

WHERE qte >5) INTERSECT

(SELECT article FROM Inventaire WHERE cout is NOT NULL);

7.25 Différence  

Cet opérateur  calcule  tous  les  tuples d’un premier  ensemble qui ne  sont pas dans un deuxième  ensemble.  Par  exemple,  pour  trouver  les  articles  en  inventaire  encore invendus, il suffit d’exécuter la clause ci‐dessous. 

(SELECT article FROM Inventaire WHERE cout is NOT NULL) MINUS (SELECT article FROM Ventes);

 Bien  entendu,  la  différence  peut  aussi  être  formulée  avec  la  négation  dʹun  prédicat dʹinclusion (NOT  IN). 

SELECT article FROM Inventaire WHERE article NOT IN (SELECT article FROM Ventes;

7.26 Mise à jour de lʹextension d’une table L’extension  d’une  relation  de  base  est mise  à  jour  par  lʹajout,  la  suppression  ou  la modification d’un ou de plusieurs  tuples. Les opérations de mise  à  jour peuvent  être effectuées si  l’utilisateur a  les droits requis sur  les relations ou  les tables ciblées par  les modifications.  S’il  est  propriétaire  de  la  relation,  il  a  tous  les  droits.  Si  la  relation appartient à un autre utilisateur, il lui faudra obtenir les droits d’accès appropriés. Ceux‐ci sont spécifiés par la commande GRANT.  Tout propriétaire d’une  table peut utiliser  cette  commande avec  l’une de  ses  tables  et autoriser d’autres comptes à  faire des manipulations sur sa  table, notamment celles de mise à jour et de suppression des tuples.  GRANT SELECT,DELETE, UPDATE ON Empl TO util3 [With Grant Option] Dans cet exemple, l’option [WITH GRANT OPTION] permet à utilisateur3 de propager à d’autres les droits reçus du premier utilisateur. Si cette option ne lui est pas accordée, il ne pourra pas propager  les droits à d’autres utilisateurs, même s’il est propriétaire des tables. 

Ajout de tuples dans une relation Pour ajouter des tuples dans une extension, on utilise la commande INSERT dans un des formats possibles : ‐ Insertion dʹun seul tuple de valeurs : Format 1:   

Page 100: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

100

INSERT INTO <nom-relation> (attrib1, attrib4, attrib5) VALUES (liste de valeurs);

 L’ordre  des  valeurs  doit  être  celui  des  attributs  du  schéma.  Il  est  aussi  possible  de fournir la liste des attributs dans lʹordre correspondant à celui des valeurs fournies. Les attributs absents du schéma correspondent alors à des indicateurs de nulls dans le tuple créé.   ‐  Insertion  dʹun  ensemble  de  tuples  obtenus  par  une  sous‐requête  et  en  provenance d’une autre table : Format 2:  INSERT INTO <nom-relation> (liste-attributs-du-schéma)

SELECT <liste des attributs> FROM <relation1> [WHERE <prédicat>];

 Les tuples proviennent des tables existantes de la BASE DE DONNÉES. Cette insertion peut être effectuée par un bloc de PL/SQL. Si une table est créée pour ranger les ventes importantes définies comme ayant une quantité supérieure à 10, elle pourra être chargée par le format 2 du DML INSERT :   INSERT INTO Ventes_avant2000 (article, nom, qte)

SELECT article, nom, qte FROM Ventes WHERE qte > 10;

 7.27 Suppression de tuples dans une relation  Pour effectuer cette opération, il faut d’abord rechercher le ou les tuples à supprimer. Si la condition est spécifiée avec une clé, un seul tuple sera supprimé; autrement, tous les tuples vérifiant le prédicat de sélection   seront supprimés. La suppression est autorisée par le propriétaire de la table ou par lʹutilisateur qui a le privilège RESOURCE 

DELETE FROM <relation> [WHERE <prédicat>];  où  le  prédicat  est  une  formule  logique  comportant  au  besoin  une  combinaison  de conditions dont lʹévaluation fournit une valeur booléenne.                             Lors de lʹopération de suppression des tuples, les déclencheurs de suppression de tuples sont activés, lʹespace disque alloué reste monopolisé par cette table et la journalisation de la suppression est  faite à  la  fois dans  le  journal et dans  les segments de rollback de  la transaction. Pour éviter cette lourdeur qui accompagne une telle suppression de tuples, il  faut  utiliser  la  commande  TRUNCATE  TABLE. Cette  dernière  supprime  les  tuples sans qu’il y ait une journalisation dans les segments de rollback (Voir sur l’architecture du SGBD,  liste LRT de  la ZMP) et une autre dans  le  journal  interne. De plus,  lʹespace peut être conservé ou supprimé et lʹindex est mis à jour.   

TRUNCATE TABLE Empl {REUSE STORAGE | DROP STORAGE } ;

Page 101: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

101

Exemples : a) Supprimer les ventes faites à Renée ou à Marie‐Claude. 

DELETE FROM Ventes WHERE nom = 'Renée' or nom = ‘Marie-Claude’;

                               b) Suppression de tous les tuples de la table Ventes.  

DELETE FROM Ventes;  TRUNCATE TABLE Ventes REUSE STORAGE; ‐‐supprime le contenu de la table sans faire de journalisation    c) Supprimer les transactions de vente concernant les articles sans marge bénéficiaire, ou ceux qui  sont en  rupture de  stock  (null pour cout). Chaque  tuple  supprimé est  inscrit dans le journal.   

DELETE FROM Ventes WHERE article NOT IN SELECT article

FROM Inventaire WHERE (prixVente - cout) < 0 or cout is null);

                                  La sous‐requête est en premier évaluée afin d’identifier  les  tuples correspondant à des articles vendus avec perte ou ceux dont le coût est inconnu. Par la suite, la table Ventes est balayée pour  supprimer  les  tuples présents dans  le  sous‐ensemble  identifié par  la sous‐requête. 

7.28 Mise à jour des tuples Les tuples sont modifiés après une recherche implicite des tuples vérifiant le prédicat de recherche. 

UPDATE <relation> set <expression> WHERE <prédicat>;  Par  exemple,  pour  corriger  la  transaction  d’achat  faite  en  janvier  par  Valérie  pour inscrire neuf(9) articles  ‘a7’ et non pas  trois(3) comme cela  fut enregistré dans  la  table Ventes par la transaction initiale. La recherche est en premier faite en spécifiant les trois attributs  de  la  clé  de  sorte  quʹun  seul  tuple  sera  trouvé,  soit  celui  de  lʹachat  fait  en janvier.  

UPDATE Ventes SET qte = 9 WHERE nom = ‘Valérie’ and article = 'a7' and qte = 3;

                                En supposant que la transaction soit aussi inscrite dans une table des ventes du mois et qu’elle soit  faite correctement par Valérie  ,  la nouvelle valeur pour  la mise à  jour peut être obtenue par une sous‐requête sur la table Ventes_Janvier. 

Page 102: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

102

UPDATE Ventes SET qte = (SELECT qte FROM Ventes_Janvier) WHERE nom =‘Valérie’and article =‘a7’);

 La nouvelle valeur est fournie par le résultat dʹune sélection dans une autre relation. La sous‐requête doit retourner un seul tuple, sinon il y aura une erreur dans lʹopération de comparaison.      

7.29 Modification du dictionnaire de données (DD) La modification du dictionnaire de données est une opération plutôt rare et réservée au DBA et aux quelques utilisateurs dotés exceptionnellement des privilèges  sous‐tendus par  les  rôles  RESOURCE  et  CONNECT  ou  les  privilèges  équivalents  accordés  à l’utilisateur par le DBA.  La commande CREATE pour  la création dʹune  table peut être  très complexe et  inclure notamment, lʹespace de table et les paramètres PCTFREE et PCTUSED.  

CREATE TABLE <nom-table>( attribut-i spec-colonne,...) ;

      

       

   

Figure 7.31b 

Affichage du type des attributs dʹune relation Le module SQL*Plus a une commande DESCRIBE qui affiche la description des attributs dʹune relation ou dʹune vue relationnelle stockée dans le dictionnaire.  DESCRIBE  <nom‐relation> SQL> DESCRIBE Parent 

spec‐colonne := 

typ

DEFAULT expr contrainte‐

,

PCFREE entier PCTUSED entier INITRANS entier MAXTRANS entier TABLESPACE param STORAGE param CLUSTER param

Page 103: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

103

                       réponse :     Name  Null?  Type   nas  NOT NULL  number(3,0)   pren    varchar2(25)   nase  NOT NULL  number(3,0)   prene    varchar2(25) 

                                                                             La  réponse  exige  aussi  de  paramétrer  correctement  lʹenvironnement  SQL*Plus  pour limiter la largeur des colonnes et remplacer la valeur par défaut fournit par la longueur du type.  

COLUMN nas FORMAT 999; COLUMN NASEENF FORMAT A20; /*col.20 car. pour afficher NASEENF*/

 Exemple: DES[CRIBE] Client  Voici les types  de la table Client fournis par la commande DESCRIBE :  DESCRIBE Client   Client :  Attribut    Type   nom  NOT NULL  varchar2 30   adresse    varchar2 20   ville    varchar2 20   tel     char 13  La commande DESCRIBE donne la liste des attributs de la relation et leur type respectif, et  cela,  à  partir  du  dictionnaire  de  données.  Selon  la  norme  SQL/92  de  lʹISO,  la commande de création  spécifie  la  clé primaire et  les clés étrangères d’une  relation, de même que les vérifications du domaine des attributs.   La création d’une table peut donc être plus complexe et inclure aussi des contraintes du domaine définies au niveau de l’attribut ou au niveau de  la table. En voici un exemple en SQL92.  CREATE TABLE Empl(

matricule integer CHECK (matricule < 99999), nom char varying (40) check (LENGTH (nom > 3), salaire real NOT NULL, tauxOfficiel real NOT NULL, noDep integer check( noDep >= 10 and noDep <= 30), CONSTRAINT cp_empl primary key (matricule), CONSTRAINT fk_empl_depart FOREIGN KEY (noDep) REFERENCES Depart(noDep) MATCH FULL (SELECT noDep FROM Depart)) CONSTRAINT tauxHoraire check(salaire/35 > tauxOfficiel));

Page 104: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

104

La création de la même table avec le SQL‐DDL d’Oracle est spécifiée par la clause DDL suivante :  CREATE TABLE Empl(

matricule number(5) NOT NULL check (matricule < 99999), nom varchar2(40) check (LENGTH (nom > 3), salaire number(8,2) NOT NULL, tauxOfficiel number(4,2) NOT NULL, noDep number(3)NOT NULL check (between 10 and 30), CONSTRAINT cp_empl primary key (matricule), CONSTRAINT fk_emplDepart FOREIGN KEY (noDep) REFERENCES Depart(noDep), CONSTRAINT tauxHoraire check(salaire/35 > tauxOfficiel));

Selon  le  SGBD,  le  système  peut  créer  automatiquement  un  index  unique  (SYSTEM Index) pour la clé primaire ou lancer une procédure interne pour valider tout ajout dans Empl afin de vérifier que cet employé est absent de la table. De même, le SGBD vérifie si le département auquel est associé le nouvel employé existe déjà dans la base de données en exploitant l’index système créé pour la clé primaire de la table Depart. Lʹindex interne du système sur la clé principale peut être temporairement désactivé par le DBA. Lorsque l’index deviendra actif,  le SGBD vérifiera  l’unicité des  tuples présents dans  la  table de manière à vérifier la contrainte de clé.  En SQL de Oracle, il est possible de contrôler le placement  de  la  table  en  précisant  le  tablespace. De  plus,  le DBA  a  la  possibilité  de contrôler  le  rangement  des  tuples  en  accordant  les  droits  d’accès  appropriés  aux différents schémas.  CREATE TABLE Inventaire(

article varchar2(10) CONSTRAINT cp_inventaire PRIMARY KEY CHECK(article = UPPER(article)), prixVente NUMBER(5,2), cout NUMBER(5,2));

 CREATE TABLE Ventes(

nom VARCHAR2(35) NOT NULL CHECK (nom = UPPER(nom)), article VARCHAR2(10) NOT NULL, qte NUMBER(2) CHECK (qte < 99), CONSTRAINT cp_ventes PRIMARY KEY (nom, article, qte), CONSTRAINT fk_ventes_inventaire FOREIGN KEY(article) REFERENCES Inventaire (article)tablespace donnees_bd1);

 Les contraintes dʹune  table peuvent être modifiées par un ALTER TABLE MODIFY ou une combinaison de ALTER TABLE DROP et ALTER T ABLE ADD.  

ALTER TABLE Ventes MODIFY article number CHECK (article <100);

Page 105: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

105

                                            Pour désactiver temporairement  une contrainte référentielle :  

ALTER TABLE Ventes DROP fk_ventes_inventaire; ALTER TABLE Ventes ADD fk_ventes_inventaire FOREIGN KEY (article) REFERENCES Inventaire(article));

                                              La  contrainte  référentielle  est  supprimée  et  peut  être  recréée  par  la  suite  par  la commande ALTER TABLE ADD. Au moment de la création, la contrainte doit être vraie pour tous les tuples de la table. La validation est rétrospective.  La suppression d’une  table  requiert  le privilège RESOURCE si  lʹutilisateur nʹest pas  le propriétaire de la table.  

DROP TABLE <relation> [CASCADE CONSTRAINTS];  Supprimer la table Client et du même coup son schéma et son extension :  

DROP TABLE Client [CASCADE CONSTRAINTS];  La  table est  supprimée ainsi que  tous  les  index et contraintes  (CHECK et  les  triggers) définis sur celle‐ci. 

Ajout d’un nouvel attribut dans un schéma de relation Une modification à un objet‐table du dictionnaire de base de donnéesse fait par la clause ALTER TABLE : 

ALTER TABLE <relation> ADD (< col spec>); ALTER TABLE <relation> MODIFY (< col spec>);

                       Exemple : Ajouter la colonne (attribut) taxe à la relation Ventes :  

ALTER TABLE Ventes ADD (taxe number(5,2));  La valeur du nouvel attribut est nulle pour les tuples déjà présents dans l’extension au moment de l’ajout du nouvel attribut. Cette valeur initiale nulle peut être modifiée par une mise à jour subséquente. L’insertion automatique du null dans les tuples déjà dans la  table  avant  l’ajout  de  l’attribut  fait  réapparaître  les  problèmes  d’interprétation  des nulls. 

Modification du type d’un attribut dans un schéma Modifiez le schéma de la relation Ventes pour que le nom de l’article occupe dorénavant trois caractères au lieu de deux initialement prévus : 

Page 106: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

106

ALTER TABLE Ventes MODIFY (article Char (3));                                       

Éditeur et format dʹaffichage du logiciel SQL*Plus (Rappel) Le module SQL*Plus a son petit éditeur de ligne. Il affiche les résultats selon des formats précisés  par  des  directives  simples  dont  les  valeurs  par  défaut  sont  dérivées  de  la spécification du  type des attributs.  Il est aussi possible de  faire appel à un éditeur du système dʹexploitation par la commande EDIT. 

7.30 Directives de SQL*Plus 1‐ Pour initialiser les variables dʹenvironnement de lʹéditeur : 

SET PAUSE 'appuyer sur le ENTER' SET PAUSE ON -- activation de la pause dans le déroulement

 Pour arrêter  le déroulement de  lʹaffichage des données et solliciter  lʹutilisateur dans  le but dʹamorcer la suite de lʹaffichage :

SET PAUSE OFF -- désactivation de la pause  2‐ Pour remplacer le tampon SQL*Plus par un autre qui devient le courant 

SET BUFFER tampon1.sq1 Le  tampon  courant  pour  le  module  SQL*Plus  est  changé  pour  un  autre  nommé tampon1.sql  3‐ SET  PAGESIZE 40  Pour spécifier le nombre de lignes sur chaque écran de sortie.        4‐ Pour garder dans un fichier, une trace de lʹaffichage :  

SPOOL C:\trace1.sql –trace dans fichier C:\trace1.sql SPOOL OFF --arrête la trace et retour au fichier par défaut

            5‐ Pour spécifier le format dʹaffichage par SQL*Plus et spécifier la largeur des colonnes pour les valeurs numériques et les chaînes. 

COLUMN salaire FORMAT 999.99 COLUMN nom FORMAT A25

 Cette directive permet de remplacer les largeurs dérivées du type des attributs par celles fournies pour la durée de la session.   6‐ Éditeur de ligne : L’utilitaire a quelques fonctions d’édition plutôt élémentaires :  

CHANGE .chaine.nouvelleChaine.    

Page 107: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

107

Le  caractère  ʹ.ʹ  est  le  délimiteur  de  chaîne  et  permet  de  trouver  la  chaîne  pour  la remplacer  par  une  nouvelle.  Ce  délimiteur  peut  être  quelconque  et  son  choix  exige seulement quʹil nʹapparaisse pas dans la chaîne qui fait l’objet de la recherche.  Exemple :  Remplacement de la chaîne ‘ function’ par ‘ fonction’  change .function.fonction. ou encore change ;function;fonction; -- si le . est présent dans la chaîne recherché, il faut utiliser un autre caractère, par exemple le ;. - LIST pour lister le contenu du buffer SQL.  2     ‐‐ pour positionner la ligne 2 comme ligne courante de lʹéditeur.  - RUN pour lancer l'exécution de la clause SQL placée dans le tampon SQL.                      - START A:\creation.sql -- pour lancer un fichier de commandes.  - SAVE A:\fichier.sql  Pour sauvegarder dans un fichier la clause SQL dans le tampon. ‐ GET A:\fichier.sql  Pour  rappeler  le  contenu  du  fichier  et  le  placer  dans  le  tampon  de  lʹéditeur.  Il  peut ensuite être exécuté.

EDIT nom_fichier  Pour ouvrir un fichier avec  lʹéditeur  local et y  insérer  les commandes SQL. La suite de commandes peut aussi être terminée par le caractère /, auquel cas, le fichier est exécuté lors de sa fermeture. Autrement, le fichier est « exécuté » par la suite par la commande : 

start C:\nom_fichier ou @ A:\nom_fichier.  7‐ Pour appeler lʹéditeur par défaut du système et éditer le fichier nom_fichier ou celui nommé dʹaprès le tampon de SQL*Plus, il suffit de faire :   

EDIT [A:\fichier.sql].  Il devient alors facile de modifier le fichier et de lʹexécuter soit par @ ou par un START. Si le nom du fichier est absent dans lʹappel de lʹéditeur, le fichier ouvert porte le nom du buffer interne de SQL*Plus. Par exemple : En entrant EDIT, lʹinterprète appelle lʹéditeur par défaut de manière à vous permettre de le modifier par lʹentremise des fonctions de lʹéditeur. Ensuite, il suffit dʹexécuter ce fichier avec la commande suivante :         

START A:\fichier1.sql.                  

Page 108: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

108

Exercices résolus    1‐Voici une instance de la base de donnée JMC  dans laquelle le type de lʹattribut date‐m a été modifié pour devenir une date de type Date.  

Joueur :  nom*  prenom  age  nationalite  societe   Tremblay   Patricia               22  fr   CGI   Gagnon  Jacques  23  ca  Bell   Marois  Sherly   20  us   Bell   Beaumont  Michel   24  fr   Bell   Dery    Paul            19  ca  ‐‐‐‐   Fournier   Nadine     22  ca     DMR 

                                                                               Match :  dateM*  lieu*  score  nomG  nomP   12‐jan‐1998   Qc  12‐7    Beaumont       Gagnon   5‐sept‐1995   Mtl  3‐5     Marois         Fournier   23‐mai‐1996   Qc    12‐3    Fournier     Gagnon   3‐jan‐1998   Qc   8‐6      Tremblay      Dery   22‐oct‐1999   Qc      2‐5   Beaumont       Gagnon   18‐nov‐1999  Paris   7‐4     Tremblay         Gagnon  

Commanditaire :  societe*  montant  duree   Bombardier  4000  2   CGI  2000  5   LGS  3000  2   DMR  6000  3   Bell  5000  2   Caisse Populaire  5000  5 

          1.1  Formuler  la  clause  SQL  pour  afficher  les  noms  des  joueurs  n’ayant  perdu  aucun match joué à Qc. Vous ne savez pas à priori si un joueur a joué ou pas un match, mais il doit en avoir joué un pour être dans la réponse escomptée.  Réponse  : Il y a plusieurs formulations possibles pour obtenir une bonne réponse dans l’hypothèse de tables cohérentes. 1ère : Les joueurs de match qui ont joué un match à Québec sans perdre leur match.  

(SELECT [distinct] nomG FROM Match WHERE lieu = 'Qc') MINUS (SELECT [distinct] nomP FROM Match

Page 109: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

109

WHERE lieu = 'Qc');  2ème SELECT nom  

FROM Joueur J, Match M WHERE J.nom = M.nomG and M.lieu =’Qc’ and NOT IN (SELECT nomP FROM Match WHERE lieu = 'Qc');

3ème SELECT nom

FROM Joueur J, Match M WHERE J.nom = M.nomG or J.nom = M.nomP and M.lieu =’Qc’ and not exists ( SELECT * FROM Match M WHERE J.nom = M.nomP and lieu = 'Qc');

4ème  SELECT nomG FROM Match WHERE lieu = 'Qc' and nomG not in (SELECT nomP FROM Match WHERE lieu = 'Qc');

 2‐ Formuler la clause SQL pour lister le nom de joueur, le montant de la commandite et la  société  qui  commandite  un  joueur  en  incluant  dans  la  réponse  les  sociétés  qui  ne commanditent pas encore un joueur.  Réponse :  La jointure externe droite en SQL sʹexprime avec le (+) du côté de la relation qui reçoit les valeurs nulles  ajoutées dans le calcul de la réponse. Cette jointure peut être aussi exprimée par un LEFT OUTER JOIN de SQL‐92 :    

SELECT nom, montant, C.societe FROM Joueur J, Commanditaire C WHERE J.societe(+) = C.societe;

N.B.  Si  les  clés  primaire  et  étrangère  étaient  composées  de  plusieurs  attributs,  la condition de jointure serait un prédicat conjonctif de plusieurs égalités et avec autant de signes (+) pour formuler la jointure externe.   

nom  montant  societe Gagnon  5000  Bell Marois  5000  Bell Beaumont  5000  Bell   4000  Bombardier Tremblay  2000  CGI   5000  Caisse‐Pop Fournier  6000  DMR   3000  LGS 

 

Page 110: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

110

3‐  Formuler  la  clause  SQL  pour  lister  le  nom  du  perdant  et  du  gagnant  du  premier match, i.e. le plus ancien match inscrit dans la base de données.  Réponse :  

SELECT nomP, nomG FROM Match WHERE dateM in (SELECT MIN(dateM)FROM Match);

 Les dates sont ordonnées selon lʹordre chronologique. La fonction min() retourne la plus petite, soit la plus ancienne.       nomP  nomG     Gagnon  Beaumont                                            La clause suivante fournit aussi la bonne réponse : 

SELECT nomP, nomG FROM Match WHERE dateM < ALL (SELECT dateM FROM Match);

 4‐ Voici  une  requête  SQL  dont  la  réponse  est  calculée  sur  la  base  de  données ALU‐NORD.                                   

SELECT ville, sexe, Count(nas) [as] nb-de-Personnes FROM Ouvrier O, Usine U WHERE ville = 'Quebec' -- une seule ville retenue GROUP BY ville, sexe; -- pour québec ==> 2 sexes

 Combien de lignes et de colonnes seront présentes dans la réponse ?                             Réponse :  Le GROUP BY est  calculé sur l’attribut sexe de la table temporaire ne contenant que les ouvriers de la seule ville Québec. Les valeurs possibles pour lʹattribut sexe sont ʹMʹ et ʹFʹ.  Donc la réponse comportera 2 lignes et 3 colonnes.                  

réponse :  ville  sexe  nb‐de‐Personnes   Québec  F  67000     M  66560 

           

Sommaire Les implémentations complètes de la norme SQL‐92  sont encore rares. Quelques SGBD de bon niveau ont une implémentation de niveau 2 de la norme. Les manufacturiers de SGBD semblent toujours avoir la volonté de faire un peu moins que la norme et dʹajouter des clauses qui particularisent leurs produits.  Le SQL est un langage de données utilisé 

Page 111: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

111

par  les  SGBD  en  sus  parfois  de  leur  langage  de  données  propriétaire.  Il  permet dʹexprimer  facilement  les  requêtes  jusquʹau  niveau  intermédiaire.  Les  requêtes complexes présentent cependant quelques difficultés  lorsque  lʹon veut  les exprimer en SQL. Les divisions relationnelles sont parfois plus difficiles à exprimer. En dépit de leur complexité,  les  requêtes  utilisant  la division  relationnelle  sont  plus  courantes dans  le contexte  de  l’exploitation  dʹun  entrepôt  de  données.  Finalement,  les  opérations  de jointures externes gauche et droite sont de plus en plus utilisées dans les applications de bon  niveau  permettant  ainsi  de  faire  en  une  seule  opération  ce  qui  en  demanderait plusieurs.  Exercices du chapitre 7    Le  calcul  de  la  réponse  aux  questions  ci‐dessous  est  effectué  en  faisant  référence  à lʹextension de la base de BD3. Formuler une clause SQL (conformément à la version SQL qui  est disponible)  et donner  lʹexpression  algébrique  équivalente  et  cela, pour  chaque question. Lorsque dans  lʹénoncé on  fait référence au seul nom   de  la relation  (table),  il sʹagit alors de  fournir  tous  les attributs de cette relation, soit en  les énumérant, soit en utilisant lʹastérisque.   Attention  :  toutes  les  fonctions  et  types  étudiés  dans  ce  chapitre  ne  sont  pas nécessairement disponibles dans  la version du SGBD qui vous  sera  rendue disponible pour faire les exercices ci‐dessous.                                                      1. Afficher le nom et le numéro des employés dont le nom renferme la chaîne du prénom (et dont le taux horaire est plus grand que 13.00$.  2.  Afficher,  sans  redondance,  le  numéro  des  employés  qui  sont  inscrits  comme travaillant le soir ou le jour.                      3.  Afficher,  par  ordre  alphabétique  décroissant,  le  nom  des  employés  dont  le  taux horaire est compris entre 13.00 et  26.25 $.  4. Afficher le numéro des employés inscrits comme ne travaillant pas le jour.  5. Le  taux horaire pour un employé qui  travaille plus de 40 heures par semaine est  le double de son taux horaire normal. Quel est le nom des employés qui touchent plus de 750.00 $ par semaine lorsquʹils travaillent 10 heures en temps supplémentaire ?  6. Quels sont les numéros de poste occupés par les titulaires inscrits comme travaillant le jour ou le soir, mais pas la  nuit ?  7. Lister le numéro des employés qui n’ont pas de quart de travail. 

Page 112: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

112

 8.  Lister  le  numéro  des  employés  dont  la  date  dʹembauche  (début)  est  inconnue  ou antérieure au 24‐sep‐1994.  9. Lister le nom, le numéro de poste, la description du poste et la date dʹembauche des employés dont le taux horaire est supérieur à 12.50$.  10. Lister le nom des employés dont le métier est ʹmécano1ʹ et dont la date dʹembauche est postérieure au 31 décembre 93 (31‐DEC‐1989).  11. Donner la valeur de vérité des conditions ** SQL‐92 ci‐dessous :   

(1, 2, 3) is NULL   (1, 2, null) is null not (1, 2, 3) is null  not (null, null)  is null (null, null) is NOT NULL   (1, null, 3) is NOT NULL 

** Ces expressions ne sont pas nécessairement  implémentées ou disponibles dans  tous  les SGBD courants.     12. Formuler  le schéma dʹune  table Fournisseur dʹarticles et  trouver deux à deux, ceux qui  offrent  exactement  les mêmes  articles.  Pour  formuler  la  solution,  il  faut  pouvoir exprimer en SQL que deux ensembles sont égaux (exercice non trivial).  13*** (Problème avec une certaine difficulté) Une base de données est constituée de deux tables Cours(noCours*,  inscriptions) et Salle(noSalle*, capacite). Le problème générique dʹallocation  formulé  par  E.  F.Codd  et  dont  la  solution  nʹest  pas  triviale  consiste  à  formuler une requête SQL avec ou sans vue relationnelle permettant dʹallouer les salles à des cours  en respectant la contrainte suivante : (inscriptions) <= (capacité) .  En dʹautres mots, lʹallocation doit se faire de manière à ce que chaque personne inscrite ait un siège dans la salle sans limiter ou préciser le nombre de sièges à conserver libres pour  les  inscriptions  tardives.  Voici  les  deux  extensions  à  utiliser  pour  lʹénoncé  ci‐dessus.  

Cours :  noCours*  inscriptions  Salle :  noSalle*  capacite   c6  40    s10  30   c5  50    s4  45   c4  55    s6  50   c3  65    s14  55   c2  70    s12  65   c1  80    s2  70         s8  85 

                     La réponse attendue est la suivante :         

Page 113: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

113

réponse :  noCours*  noSalle  inscriptions  capacite   c6  s4  40  45   c5  s6  50  50   c4  s14  55  55   c3  s12  65  65   c2  s2  70  70   c1  s8  80  85 

                  La première étape pourrait être celle de  faire une opération pour  trier au préalable  les tuples des deux extensions en ordre descendant selon  la capacité de  la salle et ensuite, selon  les  inscriptions  à  chaque  cours. Une  autre  façon  serait    de  créer  une  vue  pour calculer une jointure avec la condition inscriptions <= capacité.   14 *** ‐ Refaire le problème no 3  en faisant lʹhypothèse que dans chaque cours il doit y avoir au moins une place vide pour une  inscription  tardive. Dans  ce  cas,  la  condition sera la suivante : (inscriptions) < (capacite). Est‐ce que les solutions précédentes sont valables ? Comment est‐il possible d’obtenir la meilleure solution avec les tables fournies ?                                           

Projet ALU-NORD

 Une base de données relationnelle composée des  tables qui correspondent au MCD ci‐dessous  doit  être  implantée  et  chargée  avec  un  état  initial  correspondant  à  celui  des extensions fournies.                 Modèle conceptuel    La  société  ALU‐NORD  fabrique  plusieurs  pièces  moulées  en  aluminium  dans différentes usines spécialisées réparties dans le monde.  Les usines implantées obligatoirement dans différentes villes produisent diverses pièces sur  commande;  ces  dernières  sont  le  plus  souvent  stockées  sur  place  et  livrées entièrement  à  la  fin  de  la  production.  Le  matériau  en  vrac  est  livré  en  volume prédéterminé  par  le  fournisseur  sur  commande  de  chaque  usine.  Les  fonctions  de gestion  des  ressources  humaines  se  limitent  à  gérer  un  dossier  sur  chaque  ouvrier. L’implantation  de  cette  base  doit  se  faire  en  ne  validant  que  les  contraintes  de participation et de cardinalité et cela sans développer de  triggers. Pour y arriver, vous disposez  du  mécanisme  de  contrainte  référentielle  et  des  actions  référentielles disponibles dans le SGBD utilisé pour réaliser ce projet.       

Page 114: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

114

                                            Voici, à titre dʹinformation seulement, quelques règles plus complexes sous‐tendues par le MCD  et  qui  ne  seront  pas  au  départ  validées  dans  la  base  de  données,  car  cela exigerait  l’utilisation de  triggers et de packages qui seront étudiés brièvement dans un chapitre ultérieur.   ‐ La suppression dʹun métier entraîne celle de sa participation à lʹassociation Titularise et du même coup, la suppression des ouvriers compétents dans ce métier. Il est possible de supprimer  une  entité  dans VracMat  si  et  seulement  si  sa  participation  à  lʹassociation Utilise est aussi supprimée.   ‐ La  suppression dʹune usine  entraîne  aussi  celle de  ses productions, mais pas de  ses ouvriers, ni des matériaux en vrac qu’elle utilise.   Un métier n’est inscrit dans la base que si un ouvrier est qualifié pour le pratiquer dans son  travail.  Un  client  n’est  représenté  que  s’il  a  effectué  au  moins  l’achat  d’une production  complétée  par  une  usine. Globalement,  il  ne  peut  pas  y  avoir  plus de  10 métiers différents dans tout  le réseau des usines. De même,  le même matériau ne peut pas être fourni par plus de quatre fournisseurs.  Ces contraintes seront  formulées  dans 

Production noPiece*  lot*  qte dateDebut delai 

Realise(1,1) Client 

noClient*  ville credit  Achete  (1,n) (0,1)

Ouvrier nas*  nom prenom sexe dNaiss 

b h

Metier noMetier*  classeMetier taux 

Titularise  (1,n) 

Usine noUsine*  ville  capacStock  surfaceUsine 

VracMat noMat*  noFourn* volL cat

Travaille  (0,1)

(0,n)

(0,n) (0,m)Vol

(0,n)

(1,1) 

Commande 

Page 115: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

115

le  schéma dans  la mesure où  le SGBD utilisé pour  lʹexploitation  le permet. Le modèle ALU‐NORD est un graphe acyclique.  

Sémantique de quelques attributs : 

dNaiss  Date de naissance de lʹouvrier comprenant le jour, le mois et lʹannée. embauche :   Date du premier contrat de travail exprimée avec le jour, le mois et lʹannée. classeMetier:  Classes de compétence pour un métier identifiées par un entier de 1 à 5. capacStock :  Nombre de pièces pouvant être conservées à lʹusine dans une enceinte dont  la 

surface représente obligatoirement 10% de celle de lʹusine. lot :   Unité de production dʹune sorte de pièces correspondant à une commande. delai :   Nombre prévu de jours pour  la fin de la production dʹun lot de pièces. volL :   Quantité minimale dʹun matériau en vrac pouvant être livré à une usine. noMetier  :  Identifiant pour un métier exercé par plusieurs ouvriers. cat :  Qualité du matériau en vrac fourni ou livré par un fournisseur. qte  Quantité de pièces produites dans un lot de production VolC :  Volume de matériau en vrac commandé par une usine. surfaceUsine :  Surface totale de lʹusine dont 10% est consacrée à lʹentreposage. nas :  Numéro  assurance  sociale  sous  forme dʹune  chaîne  composée uniquement de 

chiffres     Modèle relationnel  Le MCD ci‐dessus est transposé en modèle logique relationnel (MRD) en appliquant les règles de  transposition appropriées. Certaines des contraintes seront  implémentées par les  clés  référentielles,  tandis  que  dʹautres  le  seront  par  des  contraintes  dʹattribut  et finalement certaines par des triggers.   VracMat(noMat*, noFourn*, volL, cat) Usine(noUsine*, ville, capacStock, surfaceUsine) Metier(noMetier*, classeMetier, taux) Production(noPiece*, lot*, qte, dateDebut, delai, noUsine, noClient) Ouvrier (nas*, nom, prenom, sexe, dNaiss, embauche, noUsine, noMetier) Commande(noUsine*, noMat*, noFourn*, volC) Client (noClient*, ville, credit)  N.B . Lʹastérisque  (*)  indique  un  attribut  primaire,  i.e.  un  attribut  qui  compose  la  clé primaire. Pour une meilleure lisibilité du MRD, le trait dʹunion est utilisé dans le libellé dʹun attribut à  la place du  souligné qui demeure  cependant  le  caractère dʹespacement admissible par  le  langage SQL‐DDL. Par  exemple,  lʹattribut  classe‐Metier  sera  spécifié dans  le  schéma avec  le  libellé  ʹclasseMetierʹ. Les autres caractères de ponctuation  sont exclus  du  libellé  du  schéma.  Les  caractères  $  et  #  sont  admissibles, mais  à  toute  fin pratique inutilisés.                                

Page 116: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

116

Domaines de quelques attributs Certains  attributs  ont  un  domaine  sémantique  particulier  défini  dans  le  tableau  ci‐dessous.  Par  définition,  l’indicateur  null  est  hors  domaine.  Toutefois,  elle  peut  être utilisée  pour  valuer  certains  attributs.  Le  domaine  des  autres  attributs  est  considéré comme étant implicite et dérivé des extensions des tables ci‐dessous. Les attributs dont le domaine n’est pas imposé auront un domaine syntaxique qui repose sur le type et que vous pouvez définir en vous référant aux contenus des tables.   cat: { ʹAʹ, ʹBʹ, ʹC, ʹD’}  capacStock: ]10...9999]  volL ]0... 1000]  sexe : {ʹFʹ, ʹMʹ} classeMetier : { 1...5}  taux:  ]10.00 ...  32.75]  lot : [ʹb10ʹ.... ʹb99ʹ]  credit:[1000....10000] noMetier  :  [‘j1’... ‘j99’] 

surfaceUsine:]100...5000] 

 nas  :  chaîne  de  9 car.  

 noUsine : [ʹu10’...’u99’] 

 N.B. Un  crochet  ouvert   par  la gauche  ou par  la droite  indique une  borne  exclue du domaine. Un crochet fermé par la gauche ou par la droite indique lʹinclusion de la borne dans  le domaine. La  valeur  nulle  nʹest pas une  valeur du domaine, mais  correspond quand même  à  une  réalité  pour  quelques  attributs,  notamment  les  attributs  délai  et noUsine.  Les  attributs  dont  le  domaine  n’est  pas  défini  explicitement  doivent  être spécifiés selon les données fournies par les tables. 

Remarques 1‐ De  par  la  contrainte  sur  la  capacité  de  stockage,  toute  production  inférieure  à  11 unités  doit  quitter  lʹusine  immédiatement  et  donc  être  livrée  au  client.  Cette  petite production  exceptionnelle  nʹest  donc  pas  inscrite  dans  la  base  de  données,  ce  qui explique la définition du domaine sémantique pour cet attribut. 2‐ La sémantique de plusieurs attributs peut être dérivée du contexte de la relation. 3‐ Les  signes orthographiques ne  sont pas  autorisés pour  le nom dʹattribut,  sauf  si  le système  utilisé  implémente  le  Unicode.  Seulement  les  dernières  versions  des  SGBD assurent  la représentation des caractères sur 16 bits ou plus. Les données peuvent être cependant stockées avec les signes orthographiques.                                             4‐ La connaissance des données a aussi permis de formuler quelques règles de validation syntaxiques  qui  viennent  en  restreindre  le  domaine  et  qui  seront  renforcées  dans  le schéma  de  la  base  ALU‐NORD.  Ces  règles  ne  sont  pas  complètes, mais  il  vous  est demandé d’implémenter que celles‐ci et cela pour ne pas surcharger la description de la base de données.  

Page 117: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

117

Attribut  Validation syntaxique nas  chaîne de 9 caractères représentant des chiffres seulement   noFourn  1 ère lettre est un ʹfʹ  noMetier  1 ère lettre est le caractère ʹjʹ et sa longueur max. est 3 noUsine  1ère  lettre est  le caractère  ʹuʹ,  les autres étant des chiffres. La 

longueur max. est 3 noClient   1ère lettre est le caractère ʹcʹ noMat  Chaîne dont la 1ère lettre est le caractère ʹm ʹ nom  Chaîne de lettres en majuscules. prenom  1ère  lettre  est  un  haut  de  case.  Les  autres  lettres  sont  des 

caractères éventuellement mixtes. noPiece  1ère lettre est un ʹpʹ et la dernière un caractère chiffre. lot  1ère lettre est un ʹbʹ . 

 5‐ Les clauses SQL étudiées dans les chapitres précédents sont extraites soit de la norme SQL‐89, soit de celle du SQL‐92. Le SGBD utilisé pour réaliser votre mini projet nʹa pas nécessairement  implémenté  le  niveau  3,  voire même  le  2  de  la  norme  SQL‐92.  Par conséquent, certaines commandes ou options du DDL   peuvent ne pas être disponibles pour  la  réalisation du projet  (par  exemple  : ON DELETE  SET NULL  est  absent dans Oracle).        

Instance de la base de données à la création N.B. Au moment de  lʹexploitation,  lʹétat de  la base de données peut  être différent de lʹinstance ci‐dessous qui doit cependant être incluse. La valeur nulle est représentée par le NULL ou par des espaces. Lʹinstance de la base de données doit vérifier les contraintes dʹintégrité définies. Lʹabsence dʹune valeur nulle pour un attribut dʹune table signifie que cet attribut doit avoir obligatoirement une valeur dans lʹextension.    

Production :  noPiece*  lot*  qte  dateDebut  delai  noUsine  noClient   p1000  b70  1200  17‐dec‐1998  20  u12  c35   p2000  b80  900  23‐nov‐1998  15  u24  null   p1500  b75  1150  5‐nov‐1998  null  u12  c50   p1000  b35  700  28‐nov‐1998  12  u18  c25   p2300  b42  2375  10‐dec‐1998  7  u14  c35   p1000  b74  130  18‐nov‐1995  5  u10  c45 

                          Metier :  noMetier*  classeMetier  taux   j27  1  32.75   j41  2  28.53   j75  5  27.68   j19  4  18.40   j40  3  22.90   j44  3  19.29 

 

Page 118: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

118

Client :  noClient*  ville  credit   c35  Québec  7500.00   c45  Paris  3000.00   c25  New‐York  2000.00   c50  Toronto  10 000.00 

 Ouvrier : 

nas*  nom  prenom  sexe dNaiss  embauche  noUsine  noMetier196573432  BOIVIN  Louise  F  10‐1‐1965  20‐oct‐1995  u12  j27 198029823  DION  Paul  M  17‐5‐1980  17‐nov‐1998  u12  j41 199549525  BOUCHARD  Félix  M  null  8‐jan‐1995  u14  j75 197479013  GENEST  Christian  M  4‐2‐1974  27‐jan‐1994  u12  j27 196871002  GAUTHIER  Fabrice  M  25‐4‐1968  19‐sep‐1995  u14  j19 197287815  DUSSAULT  Luce  F  11‐10‐1972  12‐mar‐1995  u18  j40 195545260  TREMBLAY  Jacques  M  9‐11‐1955  1‐mar‐1991  u22  j19 196236649  SOUCY  Sybelle  F  2‐12‐1962  23‐jan‐1998  u32  j41 195265972  DRECJACKSEN  Jack  M  8‐5‐1952  10‐jan‐1995  u10  j75 195023961  SMITH  Marie  F  27‐11‐1950  26‐jan‐1996  null  j44                             

Commande :  noUsine*  noMat*  noFourn*  volC   u12  m27  f510  15   u14  m27  f320  25   u22  m75  f420  30   u32  m41  f650  80   u18  m41  f100  40   u14  m75  f520  45   u10  m27  f320  60   u18  m27  f100  90   u18  m75  f100  50 

                                               

Usine :  noUsine*  ville  capacStock  surfaceUsine   u10  Chicoutimi  1000  300   u12  Québec  2000  1700   u14  Montréal  3000  1250   u18  Boston  1000  1550   u20  Rimouski  1275  1100   u22  Toulouse  1400  500   u24  Paris  3000  450   u26  Zurich  2300  1200   u28  Atlanta  2000  1700   u30  Toronto  1250  420   u32  Vancouver  970  600 

                             

Page 119: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

119

VracMat :  noMat*  noFourn*  volL  cat   m35  f270  20  B   m75  f520  15  A   m35  f300  15  C   m27  f100  25  A   m27  f510  25  C   m75  f100  30  B   m41  f650  40  A   m75  f420  50  A   m41  f100  20  D   m27  f320  15  B 

 Chargement initial de la base de données    Le  schéma des  relations  (tables) doit  être  créé de  sorte quʹune  table  (parent)  soit déjà créée  avant  quʹelle  soit  référencée  par  une  autre  table  (type  enfant).  Lors  de  la suppression des tables, lʹordre inverse sʹimpose! Le  chargement  de  la  base  de  données  peut  être  fait  par  lʹexécution  dʹun  script  de l’annexe B et lancé de préférence avec la commande START A:\ALU_data.txt (pour un  volume  plus  important    de  données,  il  y  a  le  chargeur  SQL*LOADER    dont  les fonctions  sont  décrites  en  annexe).  Le  script  de  chargement  est  aussi  disponible  au moyen du lien hypertexte disponible sur le site Web.

Exploitation de la base de données Lorsque lʹénoncé de la question fait référence seulement au nom de la table, ce sont les valeurs de  tous  les  attributs  qui  sont demandées,  sauf  si  les  attributs  sont demandés explicitement.  Exemple,  lister  lʹusine  de Québec  signifie  afficher  la  valeur  de  chaque attribut de lʹusine de Québec.   La  rubrique de chaque  section de questions est  indicative. Normalement,  la  réponse à une question de cette section fait appel aux opérateurs mentionnés dans la rubrique de cette section et, au besoin, aux autres des sections précédentes. Toutefois,  il nʹy a   pas quʹune seule façon de formuler la réponse à une question. Dans tous les cas,  privilégier la clause SQL la clause la plus simple pour répondre à la question. Il serait utile de lire ou  relire  immédiatement  la  section  sur  les  commandes  de  lʹéditeur  de  SQL*Plus  de manière à  formater correctement  le  reportage de vos  réponses et cela, dès  le début de votre travail.   Lorsque la réponse consiste à formuler une commande SQL, placez cette dernière dans un fichier sur disquette A; ou sur le disque de votre station ou ordinateur de travail.  Son exécution  peut  ensuite  être  lancée  à  partir  du  fichier  :  @A:\fb3.sql  ou  START A:\fb3.sql. Le  nom du  fichier  est  formé  par  la  lettre  et  le  numéro  de  la  question, exemple: b3.  N.B. Si exceptionnellement lʹimplémentation SQL du système qui vous est demandé d’utiliser ne permet pas de répondre à une question, formulez  la requête sur papier en SQL‐92.                                     

Page 120: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

120

Contenu du rapport du mini projet Dans  le  rapport,  il  faut  identifier  chaque  question,  reprendre  le  texte  de  la  question demandée  et  fournir  la  clause  SQL  permettant  de  calculer  la  réponse. Une  trace  de lʹexécution correcte permet de vérifier la  justesse de la réponse obtenue. Pour quelques questions, notamment  les opérations de mise à  jour  et de  suppression,  certains autres éléments  doivent  être  présentés  afin  de  démontrer  que  lʹopération  demandée  a  été exécutée avec succès. Par exemple, si lʹon demande dʹajouter des tuples dans une table, il faudra donc afficher la table avant et après pour démontrer que les ajouts demandés ont été réalisés correctement. Le schéma de la base de données sera vérifié et reconnu correct s’il passe avec succès le test appelé test_alu.rtf. Bien que ce test ne soit pas complet, il sera présumé  suffisant  pour  valider  votre  schéma.  Il  faudra  donc  dans  votre  rapport présenter une trace imprimée qui illustre que le test a été passé avec succès.                                           

Questions à formuler en SQL Attention  : Les  questions  ne  sont pas  nécessairement  en  ordre  croissant de difficulté. Elles ont été mises dans un ordre quasi aléatoire de manière à  ce que,  s’il y a  lieu,  la répartition  des  questions  dans  une  équipe  fournisse  des  ensembles  de  complexité similaire.  

A‐ Création et  chargement de la base de données À partir du MCD, commenter les transpositions nécessaires pour obtenir le MRD  donné dans  lʹénoncé  du  projet.  Ensuite,  spécifier  le  schéma  dans  lequel  sont  formulées  les contraintes dʹintégrité de domaine et syntaxiques formulées explicitement de même que celles inhérentes au modèle relationnel ALU‐NORD qui peuvent être implémentées sans avoir recours à un trigger.  N.B.  Attention au type de chaîne de caractères : un attribut dont la valeur apparaît être de longueur variable dans les instances de table doit être spécifié VARCHAR2(), sinon le type CHAR() peut être utilisé. L’instance des tables présentée dans l’exercice doit aussi servir d’indication pour identifier les attributs pouvant avoir une valeur nulle. Effectuer la création de  la base de données pour ensuite  la charger avec  les tuples fournis par  le fichier  Aludata.txt.  La  création  des  tables  parents  doit  précéder  celle  des  tables enfants.  Pour  la  suppression  des  tables,  cʹest  lʹordre  inverse  quʹil  faut  respecter.  Pourquoi doit‐il en être ainsi? Validité du schéma.                                     De plus, vous pouvez vérifier  la validité de votre schéma en exécutant  le Test‐Alu que vous trouverez sur le site web ou éventuellement sur le disque CD d’accompagnement.  

B‐ Création de tuples avec un fichier de commandes 1‐ Représenter dans la base de données chaque membre de lʹéquipe (lorsque le projet est réalisé en équipe) comme un ouvrier qui travaille dans une usine existante (en excluant l’usine  ʹu50ʹ)  de  votre  choix  et  qui  titularise  un métier  déjà  exercé  par  un  ouvrier. Comme valeur du nas, utiliser votre numéro de dossier étudiant auquel vous ajoutez un 0 devant, mais avec un nom fictif. Ensuite, inscrire  la date du jour comme étant celle de 

Page 121: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

121

votre embauche dans une usine du groupe ALU‐NORD. Tous les attributs doivent avoir une valeur, valide dans le domaine associé. Lorsque le travail est fait en équipe, avec un seul ordre DML  les membres de  lʹéquipe  sont ajoutés dans  la base,  sauf un. Lorsquʹil sʹagit dʹune modification  ou dʹun  ajout dʹun  tuple,  afficher  la  table  avant  et  après  les opérations.  2‐ Ajouter 2 nouvelles usines qui nʹont pas encore utilisé de matériau en vrac.  3‐  Pour  un membre  de  lʹéquipe,  formuler  un  ordre  SQL  pour modifier    la  date  de lʹembauche en lʹaugmentant de 15 jours.  4‐  Pour  la  même  personne  de  lʹéquipe  dont  la  date  dʹembauche  a  été  modifiée précédemment,  changer  lʹusine  où  elle  travaille pour  quʹelle  soit  ʹu50ʹ. Commenter  le résultat de lʹopération. 5‐ Supprimer une usine que vous avez  ajoutée précédemment.  

C‐ Sélection simple  1‐  Rechercher  et  afficher  le  tuple  que  vous  avez  ajouté  dans  la  base  de  données  (le membre de votre équipe encore représenté). 2‐ Lister  toute  lʹinformation  concernant  seulement  les deux premiers métiers présents dans la table Metier. Les libellés de la table doivent être affichés intégralement. Utiliser le pseudo‐attribut ROWNUM présent  implicitement dans toutes les tables pour ne retenir que les tuples dont le rang dans la table réponse est inférieur à ROWNUM. 3‐ Lister les différents métiers titularisés par les ouvriers en bonifiant  leur taux horaire de 15%. 4‐ En présumant que lʹâge de la retraite légale soit 65 ans, lister le nom, le nas et la date exacte prévue pour  la retraite des ouvriers masculins  inscrits dans  la base de données. La  retraite  commence  au  65e  anniversaire  dʹun  ouvrier.  Utiliser  la  fonction ADD_MONTHS() pour le calcul de l’âge de la retraite. 5‐ Lister le nom, le prénom et le nas des ouvriers dont le prénom est inclus dans le nom.  6‐ Lister le numéro des usines situées à Montréal ou à Boston qui ont une superficie de plus de 1500 mètres carrés.   7‐  Lister  la  ville  et  le  numéro  des  usines  dont  40%  de  la  capacité  de  stockage  est supérieure 1100 pièces.   8‐ Lister  le nom et  le prénom des ouvriers encore  sans affectation de  travail dans une usine. 9‐  Simuler  ce  quʹaurait  été  la date de  fin des  productions  en  augmentant  le délai de livraison de 10% arrondi à lʹentier supérieur. La réponse est fournie avec les no‐pièce, le lot et la date de fin de production avec lʹintitulé  ʺFin de production + 10%ʺ.  N.B. : il y a une différence entre une chaîne encadrée par des  ʹ        ʹ, qui correspond à une constante littérale et une autre encadrée par des  ʺ     ʺ, qui correspond à un alias ou à un intitulé de colonne  dans  lequel  il  peut  y  avoir  des  espaces. Noter  aussi  le  résultat  obtenu  avec lʹaddition dʹune valeur nulle, i.e. lorsque le délai nʹest pas spécifié. 10‐ Lister les nas, nom et prénom des ouvriers embauchés entre le 1 janvier 1995 et le 31 décembre 1998. 

Page 122: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

122

D‐ Sélection avec les fonctions SQL 1‐ Lister les ouvriers qui ont été embauchés en 1995. 2‐ Combien y a‐t‐il de productions dont le client est inconnu?  3‐ Lister la plus grande surface dʹentreposage disponible peu importe lʹusine. 4‐ Quel  est  lʹâge moyen  des  ouvriers  embauchés  au  cours  des  6  premiers mois,  peu importe lʹannée? 5‐ Quel est le taux horaire moyen payé pour tous les métiers confondus? 6‐ Lister  le  nom,  lʹâge  et  le  numéro dʹusine  où  travaillent  les  ouvriers  nés  après  le  1 janvier 1950. Lorsquʹun ouvrier nʹa pas dʹaffectation, le libellé ʺSANS USINEʺ est affiché tel quel. Utiliser la fonction NVL(). 7‐ Afficher le nombre total dʹouvrières inscrites présentement dans la base de données. 8‐ Quel est le plus grand volume de matériau en vrac utilisé par une usine? 9‐ Quel est  le délai  le plus  court  imposé aux productions  réalisées par  l’ensemble des usines ʹu12ʹ et ʹu18ʹ ?  10‐ Lister le nom et le prénom de chaque ouvrier en le précédent du libellé M. ou Mme selon le cas. Le nom est affiché en majuscules suivi de la première lettre du prénom. 11‐ Modifier  votre  nom  dʹouvrier  (éventuellement  pour  chaque membre  de  lʹéquipe) dans la base de données pour quʹil apparaisse en lettres minuscules sauf pour la 1e lettre qui reste une majuscule. Souvenez‐vous que vous êtes encore  inscrit(s) dans  la base de données ! 12‐ Quelle est la quantité totale de pièces produites jusquʹici par lʹensemble des usines? 13‐ Quelle est la date de livraison des pièces dont la production a débuté en novembre, peu importe lʹannée? 14‐ Quel est le nombre de voyelles dans le nom des ouvriers occupant un métier et dont le  nom  commence  par  une  des  lettres  suivantes  :  {ʹBʹ,  ʹDʹ,  ʹSʹ}. Afficher  le  nom  et  le nombre de voyelles quʹil contient. 15‐ Combien dʹouvriers sont des hommes (peu importe lʹusine) dont les quatre premiers chiffres du nas  forment un nombre supérieur à 0971? Afficher uniquement    le nombre dʹouvriers obtenu. 16‐ Quel est l’âge des ouvriers au moment de leur embauche ?  17‐ Quelle est la quantité totale des productions dont le délai est inférieur à 10 jours ? 18‐ Quel est le taux horaire moyen payé pour les métiers de classe 3 ?  19‐ Quel est le nombre d’ouvriers masculins travaillant dans l’usine ‘u12’ ? 20‐ Lister les numéros des usines qui stockent plus de 3 pièces au mètre carré ?                                

E‐ Jointures (interne et externe), union et différence 1‐ Lister le nom, le nas des ouvriers et la ville des usines où ils travaillent présentement.  2‐ Lister le numéro des pièces et les quantités produites par les usines de Montréal. 3‐ Lister le no et la classe des métiers titularisés par un homme né en mai peu  importe lʹannée.  4‐ Lister le no dʹusine, le no de matériau et la catégorie du VracMat utilisé par les usines.  Inclure aussi le numéro des usines nʹutilisant pas présentement un VracMat.  5‐Lister le numéro des lots de pièces et la ville où ils sont réalisés.  

Page 123: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

123

 

F‐ Fonctions de groupement, union, différence et tri 1‐ Donner, pour  chaque matériau,  le nombre de  fournisseurs qui  approvisionnent  les usines. Afficher  le  numéro  du matériau  et  le  nombre  de  fournisseurs  avec  le  libellé   ʹNb_fournisseursʹ.  2‐ Lister  le numéro de pièce,  le  lot,  la date du début et  le numéro de  lʹusine pour  les productions. La liste est présentée par ordre croissant des numéros de lot. 3‐ Compter  le nombre dʹusines pour chaque métier. Afficher  le numéro du métier et  le nombre dʹusines avec le libellé  ʹNombre_usinesʹ. 4‐ Afficher les numéros de métiers et leur taux horaire, pour les métiers exercés par au moins deux ouvriers. 5‐ Lister en ordre descendant,  le numéro des usines qui nʹont pas encore dʹouvriers. 6‐  Lister  pour  chaque  no  de matériau,  le  volume  total  de  vrac  livré  aux  usines,  peu importe le fournisseur. 7‐ Lister le numéro de matériau qui peut être livré par plus de deux fournisseurs. 8‐  Lister  par  mois  d’anniversaire  le  nas  et  le  nom  des  ouvriers  de  métier  qui  ne travaillent pas encore dans une usine.  9‐ Lister en ordre croissant de nom, le nas et le nom des ouvriers qui travaillent dans des usines qui ont  commandé leur matériau en vrac. 10‐  Lister  le  numéro  et  la  ville  des  clients  ainsi  que  le  numéro  de  leur  lot  pour  les productions terminées.     

G‐ Division relationnelle 1‐ Quels  sont  les numéros des usines qui ont des ouvriers de  tous  les métiers dont  le taux horaire est supérieur à 28.00 $?  2‐ Quelles sont les usines de Boston ou de Montréal qui ont acheté tous les matériaux de catégorie ‘D’ en vrac? 3‐  Est‐ce  quʹil    y  a    un matériau  commandé  par  toutes  les  usines  présentement  en opération  et dont  la  capacité de  stockage  est  égale ou  supérieure à 3000 pièces  ? Une usine est en opération lorsquʹelle a commandé un VracMat pour assurer sa production. C’est bien une division, malgré des apparences qui peuvent être trompeuses! 4‐ Quels  sont  les  clients  (noClient  seulement)  qui  n’ont  pas  acheté  toutes  les  pièces produites, peu importe l’usine ?                     

H‐ Requête  imbriquée 1‐ Afficher  le  numéro,  la  ville  et  la  surface  des  usines  ayant  la  plus  grande  surface dʹentreposage?  N.B.  Dans  lʹinterprétation  du  modèle,  chaque  usine  consacre obligatoirement 10% de sa surface à lʹentreposage. 2‐ Quel est le nom et le nas des ouvriers nés la même année (peu importe le mois et le jour) que celle du plus jeune des ouvriers ? 3‐  Lister  le  numéro  des  pièces  produites  en  quantité  supérieure  à  la  moyenne  des productions inscrites  jusquʹici, peu importe le lot. 

Page 124: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 7 Langage SQL 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

124

4‐ Lister le numéro et la surface dʹentreposage des usines dont la capacité de stockage est plus grande que 2    fois  la  capacité de  stockage de  lʹusine ayant  la plus petite  surface dʹentreposage.  5‐ Lister les numéros des clients dont le crédit est supérieur à la moyenne du crédit des clients inscrits dans la base.  

I‐ Vue  relationnelle    1‐ Créer une vue nommée v1 pour obtenir  le nombre  total dʹouvriers qui  travaillent à chaque usine. N.B. Il  est toujours possible de définir un libellé particulier pour désigner le résultat dʹune fonction, et ce libellé peut être utilisé par la suite comme un alias de la colonne. Dans la vue demandée, le nombre total des ouvriers est libellé nbTotalOuvriers. 2‐ Créer une autre vue v2   qui permet dʹobtenir  le nombre  total dʹouvriers qui ne sont pas au  travail, peu  importe  le métier. Notez quʹil est possible dʹutiliser un  libellé pour représenter le résultat dʹune fonction. Ce libellé peut être par la suite utilisé comme un alias ou attribut de la table intermédiaire. 3‐ En utilisant  les vues précédentes,  formuler une  clause SQL pour obtenir  le nombre total dʹassignations de travail encore possibles pour les ouvriers.  4‐ Créer une vue  relationnelle  fournissant  le numéro de matériau  la quantité  totale de chaque matériau livré suite à une commande et cela, peu importe le fournisseur.    

J‐ Trigger (déclencheur) Pour  répondre  à  ces  deux  questions,  il  faudra  avoir  terminer  le  chapitre  suivant  qui décrit le langage des triggers. 1‐  Implémenter  la contrainte qui  limite à 10  le nombre  total de métiers différents dans tout  le  réseau.  Tester  la  contrainte  en  augmentant  le  nombre  de métiers  de  façon  à dépasser cette limite. 2‐  Implémenter  une  contrainte  qui  limiterait  à  quatre  le  nombre  de  fournisseurs  du même matériau. Tester cette contrainte avec un trigger d’énoncé BEFORE  INSERT. 

 

Page 125: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

125

Chapitre   8   Indexation , vue relationnelle, droits d’accès et base de données réactive 

 8.1 Indexation Il y a plusieurs  types dʹindex allant du simple séquentiel,  indexé avec un ou plusieurs niveaux, au plus complexe représenté par la famille des index organisés avec la structure d’un arbre. Dans tous les cas, lʹindex utilisé par le moteur de la BD est en quelque sorte un  mécanisme  dʹaccès  rapide  aux  données,  qui  vient  bonifier  lʹaccès  séquentiel (balayage)  de  base  toujours  disponible  par  défaut.  Sous  cet  angle  d’accès  rapide,  la famille des  index  inclut  aussi  celui par Hashing qui  implémente un  accès  rapide  aux tuples par lʹentremise dʹune fonction de calcul d’adresse.   Les index les plus utilisés par les SGBD sont ceux de la famille des B‐arbres, notamment le B*‐arbre. Rappelons quʹun B‐arbre organise les valeurs sous la forme dʹun arbre n‐aire de façon à permettre par exemple une recherche dans un lot de 2 millions de tuples en moins  de  5  lectures  sur  disque.  Le  B*‐arbre  se  distingue  par  le  fait  que  les  nœuds internes ne pointent que sur dʹautres nœuds internes, sauf pour les feuilles qui pointent sur les données regroupées dans les feuilles. De plus, la gestion et lʹéquilibrage de lʹarbre sont faits pour maintenir une hauteur moyenne quasi fixe et un remplissage moyen des cellules appelé facteur dʹoccupation (fill factor) qui peut varier de 0.25 (Oracle 8) à 0.66. 

8.2 B*‐arbre Comme nous  lʹavons vu dans un chapitre précédent,  le B*‐arbre est une hiérarchie de cellules dʹordre p,  ce qui  signifie quʹil y  a p pointeurs  et p‐1 valeurs dans  les nœuds internes. Par exemple, lʹindexation du matricule employé, dont le domaine varie de 1 à 100, présente la structure suivante à un moment particulier de lʹexploitation de la BD.            B*‐arbre dʹordre 3 (pointeurs et au plus 2 valeurs de clé) 

Figure 8.1  

20

 35   15   17    18   20

  25  17 

  23   25

tuple  tuple tuple tuple tuple tuple  tuple

Page 126: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

126

Chaque cellule  interne est un nœud et  les cellules du dernier niveau  sont des  feuilles. Chaque  feuille  a une même  structure qui peut varier  selon  le  type d’arbre. Voici une structure typique de la cellule interne (nœud)            

Structure d’un nœud Figure 8.1a 

 Le  pointeur  à  la  gauche  dʹune  valeur  conduit  à  un  sous‐arbre  dont  les  valeurs  sont inférieures ou égales à la valeur  vi, tandis que le pointeur de droite conduit à un sous‐arbre dont  les valeurs sont supérieures à vi. La sémantique des pointeurs est  la même pour  tous  les  nœuds  internes.  La  structure  dʹune  feuille  est  toutefois  légèrement différente puisque le pointeur fournit l’adresse du tuple sous la forme de rid (row  id ou adresse de tuple). 

Caractéristiques dʹun B*‐arbre Lʹintérêt du B*‐arbre ou de lʹune de ses variantes comme le B+‐arbre, réside dans le fait quʹil nʹest  jamais largement déséquilibré et que sa hauteur est quasi constante quel que soit  le  chemin  parcouru  pour  aboutir  à  une  feuille.  A  tout moment,  cette  structure arborescente (similaire aux arbres AVL) présente les propriétés suivantes :  1‐ Chaque valeur indexée présente dans les nœuds (internes) est aussi présente dans les feuilles. Les valeurs de chaque  bloc d’index sont en ordre lexicographique.  2‐  Seulement quelques valeurs de  clé  sont utilisées par  les nœuds  internes de  lʹarbre. C’est un index non dense sur les blocs stockant les tuples d’une même table.  3‐ Chaque valeur indexée et présente dans un nœud interne apparaît aussi comme étant la valeur  la plus à droite dans  le sous‐arbre pointé par  le pointeur gauche de  la valeur indexée.  4‐ A lʹajout dʹune nouvelle valeur, si la feuille (cellule terminale) devient saturée (i.e. le facteur de saturation est atteint), elle est divisée en deux feuilles de même niveau et  la valeur centrale de la feuille dʹorigine devenue saturée (celle avant division) est déplacée vers le nœud de niveau supérieur. Si, ce faisant, ce nœud devient saturé, la division des 

Pointeur  sur  le  sous‐arbre droit  dont  les  clés  sont supérieures  à vi+1. 

    vi       vi+1       

Pointeur  sur  le  sous‐arbre  droit dont les clés sont supérieures à vi ou égales à vi+1

Pointeur  sur  le  sous‐arbre gauche  dont  les  clés  sont inférieures (et égales) à vi . 

Page 127: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

127

valeurs  est  à  nouveau  effectuée  avec  insertion‐déplacement  de  la  valeur  centrale  du nœud saturé vers un autre de niveau supérieur suivant.  5‐ Lorsqu’on supprime une valeur, elle est en premier supprimée dans  la feuille. Il   en est  de même  si  elle  apparaît  aussi  dans  un  nœud  interne  de  l’index. Dans  ce  cas,  la valeur à gauche dans la feuille remplace la valeur supprimée qui apparaît dans le nœud interne. Si la suppression dʹune valeur dans une feuille amène le niveau dʹoccupation  en dessous dʹun  seuil minimal,  les  valeurs  sont  redistribuées  entre  la  feuille dʹorigine  et celle  immédiatement  à  sa  gauche  au  même  niveau.  Sinon,  les  deux  cellules  sont fusionnées et la disparition dʹune feuille est propagée au niveau supérieur.  

Création et ajout dans un B*‐arbre La  création  dʹun  B*‐arbre  dʹordre  3  sous‐tend  celle  dʹun  en‐tête  sans  aucun  nœud  ni feuille. Lʹajout de la valeur 20 déclenche la création dʹun premier nœud dans le B*‐arbre, cʹest‐à‐dire que cette structure a au maximum 2 clés et 3 pointeurs par nœud interne. Le facteur de saturation est de 2.  Ajout de 20 : la cellule contient alors un pointeur sur le tuple identifié par la valeur 20.      Ajout de 40 : idem      Ajout de 25 : cet ajout dans la cellule provoque la saturation et donc la division en deux feuilles, suivie de la création dʹun nœud.         La valeur la plus à droite dans le sous‐arbre gauche est celle qui apparaît dans le nœud qui pointe sur ce sous‐arbre (lien gauche).  Ajout de 15  : ajout de  la valeur dans une  feuille avec division de  la  feuille et  insertion dʹune valeur dans un nœud interne parent.  

20       40

tuple tuple

  25    

tuple

40    20       25   

tuple tuple

20

tuplenull 

Page 128: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

128

  

           Ajout de la clé 17 :             Lʹajout de 17 dans une feuille a provoqué sa division et la création dʹune nouvelle feuille, mais  aussi  la  réplication  de  la  valeur  centrale  vers  un  nœud. Ce  dernier  est  devenu saturé (>2) et sʹest divisé provoquant la création dʹun autre nœud de même niveau et du déplacement  dʹune  copie  de  la  valeur  centrale  vers  ce  nouveau  nœud  supérieur.  Le processus se  répète  jusquʹà ce que  lʹinsertion de  la valeur dans un nœud ne provoque plus de division.  Ajout de 14 :               Ajout dans une feuille d’un index dʹordre 3 

Figure 8.2 

  20        25

tuple 

25    15       20  

tuple tuple

40   

Blocs de tuples 

tuple    tuple tuple tuple tuple 

20

  40   15   17    20

  25  17 

  25

null 

  14   15 

20

  40  20

  25  15       17

  25

tuple  tuple tuple tuple  tuple 

  17 

tuple 

null 

Page 129: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

129

 Lʹajout  sature une  feuille.  Il y a donc  création dʹune nouvelle  feuille pour y  ranger  la valeur 17. La valeur centrale 15 est répliquée dans  le nœud supérieur quʹelle ne sature pas. Le  rôle de  la valeur qui est déplacée dans une cellule de niveau  supérieur est de servir de  séparateur  entre  les deux  sous‐arbres inférieurs  :  le  gauche  et  le droit.  Si  le système avait placé une autre valeur comme séparateur, disons  le 16 qui n’est pas une valeur indexée, la mécanique de l’indexation aurait tout aussi bien fonctionné, à la seule condition que cette valeur ait un bit pour indiquer que c’est un séparateur étranger aux valeurs.  Dans  un  arbre  indexant  des  chaînes  de  caractères,  il  devient  alors  possible d’économiser de  l’espace en utilisant des séparateurs formés de chaînes beaucoup plus courtes,  ce  qui permet d’augmenter  sensiblement  le nombre d’entrées dans une page d’index.   La  croissance  d’un  B*‐arbre  est  symétrique  parce  que  le  rééquilibrage  est  effectué généralement  après  chaque  lot  dʹinsertions  (cette  opération  est  dépendante  de lʹimplémentation). A  lʹétat  stable,  la  longueur du chemin qui  sépare  la  racine de  toute feuille est approximativement  la même. Par exemple, avec des clés de 100 octets et des pointeurs de 4 octets, un arbre dʹordre 50 avec une cellule de  la  taille dʹune page peut avoir au cinquième niveau, plus de 2, 500,000 nœuds, chacun contenant près de 50 clés. En dʹautres mots, la recherche dʹune clé parmi les 3 millions de tuples nécessitera dans le pire des cas 6 accès au disque.  

Facteurs de croissance d’un  B*‐arbre La hauteur dʹun B*‐arbre dépend de plusieurs  facteurs dont principalement  le nombre de  tuples dans  la  table  indexée. Avec un  nombre  important de  tuples,  la  hauteur de lʹarbre  augmente  bin  sûr, mais  très  lentement.  Il  est  courant  dʹavoir maintenant  des tables  contenant  des milliards  de  tuples  et  dʹobtenir  des  hauteurs  dʹenviron  7  (sept) niveaux.   Un autre  facteur  important est celui de  la  longueur de  la clé ou de  la valeur indexée. Par exemple, plus une chaîne de caractères indexée est grande, moins il y aura dʹentrées dans une même cellule ou page (ordre plus petit de l’arbre) et, partant, plus la hauteur de  lʹarbre sera grande pour  indexer  le même nombre de tuples. La hauteur de l’arbre  peut  cependant  être  raccourcie  par  l’utilisation  de  séparateurs  de  sous‐arbres formés en tronquant la chaîne de la première clé du sous‐arbre droit.             

  23  ,  34  , 

42  ,  19  , 

Jean‐Etienne  Lazure  du  Portail, rid16 

34 , 

(90 entrées par page) (1000 entrées par page) 

page j  page j

Page 130: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

130

Finalement, lorsque lʹattribut indexé est très sélectif, comme c’est le cas pour une clé, la hauteur de  lʹarbre sera plus grande que dans  le cas dʹun attribut moins sélectif comme lʹattribut  ville.  En  générale,  lʹordre  de  la  cellule  est  choisi  pour  y  ranger  un  grand nombre de valeurs (exemple: cellule = page) de sorte que les suppressions et les ajouts ne génèrent pas à chaque opération un réajustement du B*‐arbre. Ceci évite un travail qui peut  exiger  une  ou  plusieurs  lectures  de  nouvelles  pages  sur  le  disque  et  affecter  la performance du SGBD.    

Suppression dans un B*‐arbre La suppression dʹune valeur dans une feuille se répercute aussi au niveau des nœuds où lʹon observe non plus une saturation, mais une sous‐saturation. A chaque suppression, la valeur est physiquement supprimée dans la feuille et si cette valeur apparaît aussi dans un nœud, elle doit être aussi enlevée et remplacée par la clé qui se trouve dans la feuille à la gauche de la valeur supprimée.   Lʹoccurrence dʹune feuille sous saturée suite à une suppression dʹune valeur déclenche, sʹil y a  lieu,  la  fusion avec une  feuille adjacente  (gauche ou droite) qui est aussi  sous‐saturée,  suivie dʹune  répartition des valeurs, de  telle  sorte que  les deux  feuilles  soient remplies à moins de  la moitié de  la valeur de saturation. Sinon,  il y a  fusion des deux feuilles pour obtenir une  seule qui nʹest pas  saturée. Cette création ou disparition des feuilles a aussi une  répercussion au niveau des nœuds. Après plusieurs  suppressions, lʹarbre peut alors décroître en hauteur.  

Index avec des valeurs dupliquées Les valeurs dupliquées peuvent être aussi  indexées par  le B*‐arbre. Le seul ajout est  le chaînage  des  feuilles  dont  la  valeur  est  identique, mais  avec  des  adresses  de  tuple différentes. Au niveau des nœuds, une seule valeur est utilisée pour lʹindexation.                  

Index avec valeurs dupliquées Figure 8.3 

 

20

  40   14   15  20

  25  15       17

  25

tuple  tuple tuple tuple tuple 

  17      17 Cellule  de  débordement  pour les valeurs identiques. tuple 

17

Page 131: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

131

La recherche des tuples vérifiant le critère dʹune plage de valeurs est possible avec le B*‐arbre  par  lʹentremise  des  pointeurs  latéraux  qui  enchaînent  les  cellules  d’un  même niveau. La cellule de débordement qui nʹest pas pointée par un nœud  interne est dite déconnectée par rapport aux nœuds  (ex. Système SGBD SYSBASE) de  lʹarbre. De plus, les entrées de lʹindex peuvent être simples ou complexes. Dans ce dernier cas, lʹentrée est traitée comme une composition ordonnée (juxtaposition) des valeurs dʹattributs qui font lʹobjet de lʹindexation de la table. Par la suite, la recherche avec une clé concaténée sera très sensible au respect de lʹorthographe de la chaîne. Dʹun autre côté la recherche avec une valeur partielle (préfixe) nʹest pas très efficace. Elle est cependant hors de question avec un suffixe, car  la  fouille du B*‐arbre avec une clé partielle  tronquée du début est impossible.              Recherche dans une table avec un attribut primaire La  recherche  dans  une  seule  table  lancée  par  une  clause  de  sélection  est  rapidement effectuée si le prédicat est conjonctif  et si les attributs du prédicat sont indexés.  Exemple :   

Employe (nas*, nom, age, salaire, ville) Select *  From Employe  Where age = 24; 

 L’indexation de  l’âge dans  la  table Employe permet d’obtenir  rapidement  les  rid des tuples  des  employés  de  24  ans.  Ensuite  il  suffit  de  lire  ces  tuples  en  utilisant  à  bon escient les rid obtenus.   Si la clause de sélection est une disjonctive, le calcul de la réponse ne bénificie pas autant de l’indexation d’un seul des attributs. Puisque le deuxième attribut exigera le balayage séquentiel de la table, autant alors ne pas utiliser l’indexer et effectuer la vérification du prédicat disjonctif  à  chaque  accès  à  un  tuple de  la  table. En  revanche,  si  les  tous  les attributs de la clause de sélection sont indexés, alors les index seront pleinement utilisés pour obtenir les adresses des tuples de la réponse (rid). Dans la dernière étape, chaque rid  de  cet  ensemble  d’adresses  de  tuple  permet  d’obtenir  directement  le  tuple correspondant et d’effectuer en ligne la projection de sortie.    Exemple :  Les attributs salaire et ville sont indexés. 

Select *  From Employe  Where Salaire = 25000.00 And ville = ‘Québec’; 

 L’index sur salaire fournit les rid des employés ayant le salaire de 25000.00. Ces adresses sont regroupées dans un ensemble temporaire T1. Ensuite l’index sur la ville permet de former  l’ensemble T2 avec  les  rid des employés de Québec. L’intersection de T1 et T2 fournit les rid des tuples qui constituent la réponse. 

Page 132: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

132

 Ce  type  de  calcul  est  efficace  avec  les  attributs  indexés  sélectifs  c’est‐à‐dire  dont  le facteur de sélectivité est près de 1. Par contre, si  le  facteur de sélectivité est  inférieur à 0.6,  l’ensemble des rid constitué au moyen de  l’index contiendra beaucoup  trop de rid que  le SGBD devra   gérer éventuellement  sur disque entraînant par  le  fait même une augmentation des  lectures et écritures. Dans un tel cas,  le SGBD pourrait préférer faire un balayage séquentiel de la table.                                                       Recherche avec un prédicat d’intervalle Une  telle  recherche peut  être  aussi  effectuée  avec  le B*‐arbre. L’intervalle  est  formulé avec le prédicat suivant :   

Select *  From Employe  Where Salaire = 25000.00 And salaire <= 50000.00; 

                               En premier, il y a une recherche dans l’index avec la borne inférieure de l’intervalle. Au terme de cette opération les rid des tuples indexés avec 25000.00 sont regroupés dans un ensemble T1. Ensuite les entrées de ce nœud d’index sont parcourues séquentiellement et en suivant le pointeur horizontal jusqu’à l’atteinte du premier salaire plus grand que la borne supérieure. Durant cette opération les rid sont ajoutés à T1. Il ne reste qu’à lire les tuples au moyen de ces adresses. C’est cette opération qui alourdit souvent le calcul. En effet, les rid peuvent à la limite demander autant de lectures de blocs lorsque tous les tuples sont dispersés avec le ratio de un par bloc.  8.3 Fonction de Hashing Cette  fonction  H()  permet  de  stocker  et  de  retrouver  une  ou  plusieurs  valeurs  par lʹentremise dʹune  adresse  qui  est dérivée de  la  valeur même.  Par  exemple,  si  le  nom dʹune  société  est  lʹobjet dʹune  indexation par  la  fonction H,  la  recherche de  la  société ʹViticole‐de‐Gersʹ  débutera  par  un  accès  à  un  tuple  dont  lʹadresse  est  calculée  par  la fonction H(ʹViticole‐de‐Gersʹ). La valeur obtenue est utilisée  comme  rid de  sorte quʹen allant  à  cette  adresse  on  trouvera  le  tuple  ou  le début dʹune  chaîne de  tuples, parmi lesquels se trouvera celui recherché.   La fonction H ne génère pas un ordre interne à l’image de l’ordre des valeurs externes, de  sorte  quʹil  nʹy  a  plus  de  relation  d’ordre  parmi  les  valeurs  calculées  et  celle  des adresses  de  Haching.  Ainsi,  le  stockage  des  noms  de  personnes  ordonnés  en  ordre lexicographique  sera  effectué  à  des  adresses  qui  ne  respectent  pas  la même  relation dʹordre. Finalement, la fonction de Hashing (H) permet la gestion dense des valeurs et la gestion  des  collisions  par  le  chaînage  dans  une  zone  de  débordement.  Ainsi,  si  les matricules à stocker sont largement discontinus, la fonction H peut les transformer pour les  stocker avec un plus petit nombre dʹadresses  contiguës,  facilitant ainsi  le parcours séquentiel sur un plus petit nombre de pages. Toutefois, il y aura des collisions et celles‐ci devront être gérées par le logiciel.  

Page 133: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

133

 En mode recherche, la fonction de Hashing (H) est théoriquement très rapide. Elle exige dʹavoir une orthographe exacte du critère de recherche. Ainsi, une valeur en minuscules donnera  un mauvais  accès  si  la  valeur  utilisée  initialement  avec  la  fonction H  était composée dʹun mélange de lettres minuscules et majuscules. Il en est de même pour les recherches approximatives,  comme  cʹest  le  cas avec des valeurs partielles ou voisines. Par  exemple,  les  recherches  des  articles  fabriqués  respectivement  par  ʹDeschênesʹ  ou ʹDeschainesʹ ne donneront pas les mêmes résultats, malgré le fait que le nom désigne la même  personne,  sauf  si  la  fonction  Soundex  est  utilisée  lors  d’une  recherche  dite approximative. 

8.4 Densité de lʹindex et le placement regroupé des tuples Un index dont les pointeurs des feuilles conduisent directement à un tuple est dit dense, tandis que s’ils pointent sur une page de tuples (lot), il est qualifié de non dense.                              

Figure 8.4  Densité dʹun index pour accéder aux tuples  Dans  ce  dernier  cas,  la  recherche  dʹune  valeur  particulière  exigera  un  balayage séquentiel de  la page. Cela  suppose aussi que  les  tuples  soient ordonnés  sur  l’attribut indexé et que valeurs identiques soient rangées dans la même page (clustered).   Un index non dense pointe sur la page qui contient un tuple dont la valeur d’attribut a été  trouvée  dans  l’index.  Lʹavantage  d’un  tel  index  consiste  en  une  utilisation  plus optimale  de  lʹespace  des  pages  dʹindex  lorsque  lʹattribut  indexé  a  un  facteur  de sélectivité  faible.  En  effet,  les  tuples  partageant  la  même  valeur  sont  rangés (éventuellement) dans la même page et une seule entrée est nécessaire dans lʹindex avec fournissant un seul rid   pour faire référence à cette page. Par contre, certaines requêtes de comptage exigent un accès physique aux  tuples pour obtenir une réponse. Ainsi,  la requête pour  calculer  le  total des  salaires payés aux employés âgés de plus de 25 ans exige normalement un accès aux pages de données.   

référence à une page (non dense)

  page j+1 

  page j 

référence à un tuple (dense)

Page 134: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

134

Avec  un    index  dense  certaines  requêtes  peuvent  être  calculées  sans  avoir  accès  aux tuples. Par exemple,  le comptage des ouvriers qui ont 25 ans est  fait sans accéder aux pages,  puisque  chaque  rid  de  lʹindex  sur  âge  identifie  indirectement  un  ouvrier  qui satisfait le critère de recherche. Le comptage peut donc se faire au niveau de lʹindex sans accès aux pages de données.  

Index regroupé Un  index  regroupant  (clustering  index)  est un  index dans  lequel deux  entrées voisines pointent sur des tuples qui sont aussi voisins dans lʹespace de stockage des tuples de la BD, c’est‐à‐dire dans la même page de données ou dans des pages voisines.                                                Index avec regroupement des tuples dans la page 

Figure 8.5 Ce type dʹindex est créé lors de lʹindexation d’une structure de table appelée cluster dans laquelle  cohabitent  des  tuples  de  plusieurs  tables  qui  sont  présumés  être  lʹobjet  de jointures  fréquentes.    La  création  dʹun  cluster  doit  être  suivie  de  celle  dʹun  index  de regroupement pour que le premier puisse être exploité par le SGBD.  Exemples :  CREATE INDEX cluster_idx ON CLUSTER Lieu_travail;   [Oracle] 

‐‐ le cluster Lieu_travail est présumé déjà créé                                                        CREATE NONCLUSTERED INDEX article_idx on Ventes(article); [SYSBASE] 

8.5 Index à clés transformées Lorsque les ajouts sont effectués dans un ordre croissant de la valeur dʹun attribut et que des  suppressions  régulières  sont aussi  faites dans un ordre quelconque, cela engendre un déséquilibre du B‐arbre, suivi du déclenchement du processus de réajustement. Pour éviter ce phénomène épisodique, certains SGBD, dont Oracle8, offrent  la possibilité de transformer chaque valeur indexée en inversant systématiquement lʹordre de ses octets, ce  qui  entraîne  une  randomisation  des  entrées  de  lʹindex.  En  ce  faisant,  les  espaces libérés par les entrées supprimées ont une plus grande chance dʹêtre réutilisés en cours des  ajouts,  avant  même  lʹamorce  du  travail  de  réorganisation.  Bien  entendu,  cette répartition  est  faite  au  détriment  de  la  recherche  par  plage  de  valeurs  (index  scan), 

                    35                     47 

35 47

Index sur  âge 

Page 135: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

135

puisque  trois  valeurs  initialement  ordonnées  lors de  leur  insertion dans  l’index  ne  le seront plus suite à lʹinversion des octets de ces mêmes valeurs. 

8.6 Index inversé Un  index  inversé  (inverted  index)  sur  un  attribut  est  un  index  construit  avec  les différentes valeurs de l’attribut dont chacune est associé à une liste de rids de tuples.  Par exemple, pour sélectionner les soudeurs dans la table Ouvrier, le SGBD accède à un index inversé et dans une seule opération obtient la liste des rids des tuples représentant un employé‐soudeur. De même, pour obtenir les soudeurs et/ou les fraiseurs, il suffit de faire  la concaténation des deux  listes et ensuite de  référer aux  tuples  identifiés par  les adresses de tuple.     

specialite         soudeur  r23  r34  r44  <‐‐liste de rids fraiseur  r89  r56     sableur  r123  r78  r22   

Index inversé sur la spécialité (vision logique) Figure 8.6 

 Lʹattribut qui est inversé peut être organisé selon un B*‐arbre avec, dans les feuilles, les rid qui conduisent aux tuples utilisant cette valeur. Ce type dʹindex permet lʹindexation des  attributs,  peu  importe  leur  sélectivité,  et  le  calcul  des  requêtes  comportant  un prédicat complexe formé avec les opérateurs OU et  ET  logiques. Il est particulièrement utile dans  les  grandes  bases  ou  les  entrepôts de données  comportant des millions de tuples. 

8.7 Index bitmap Ce  type dʹindex est particulièrement utile pour  indexer  les attributs à  faible  sélectivité pour lesquels le B*‐arbre n’a pas de performance exceptionnelle. Il sera particulièrement exploité  avec  un  star  schema de  lʹentrepôt de données  (data wharehouse).  Par  exemple, indexer une  table des  employés avec  lʹattribut  sexe dont  le  facteur de  sélectivité pour une répartition uniforme est 0.5, nʹajoute pas à lʹefficacité de la recherche des employés féminins! En effet, il est fort probable que le calcul soit fait par un balayage séquentiel de la table.   Une recherche classique dans un B*‐arbre aboutit à une feuille où le système trouve un rid  permettant dʹaccéder, selon le cas, à la page de données ou au tuple. Dans le cas de lʹindex bitmap,  la  structure de B*‐arbre est  toujours utilisée pour organiser  les valeurs (de  préférence  peu  nombreuses)  de  lʹattribut  indexé.  Cependant,  les  feuilles  ne contiennent pas les rids, mais un vecteur de bits dans lequel chaque position représente un  tuple de  la  table ouvrier  identifié par  son adresse. La  longueur du vecteur de bits correspond  au  nombre  de  tuples  dans  lʹextension  de  la  table.  Par  exemple,  un  index bitmap sur la spécialité de la table Ouvrier permet dʹavoir accès à des vecteurs de 4 bits, 

Page 136: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

136

soit  un  bit  par  spécialité  du  domaine.  Pour  chaque  valeur  de  l’attribut    specialite,  le vecteur correspond à la colonne de la table ci‐dessous.  

Ouvrier (nas*, nom, salaire, specialite, noUs)  Lʹextension est la suivante :  ROWID (rid)  soudeur  fraiseur  sableur  tourneur  <‐index sur specialite 00055:000:0023  0  1  0  0  <‐liste des specialités 00234:020:8922  1  0  0  0   19000:328:6200  0  0  0  1   21088:120:1002  0  0  1  0   

Figure 8.7 Index bitmap sur lʹattribut specialite Ce  type dʹindex  accélère  sensiblement  les  requêtes  avec  comptage,  opération  souvent utilisée  dans  une  requête  de  type  OLAP  (On  Line  Analysis  Processing).  Ainsi,  pour connaître  le  nombre  de  soudeurs,  cela  nʹexige  pas  un  accès  aux  tuples  de  la  table Ouvrier.  Seul  lʹaccès  à  lʹindex  bitmap  de  lʹattribut  specialite  suffit  pour  calculer  la réponse.  Le  B*‐arbre  sera  réduit  à  sa  plus  simple  expression,  et  dans  le  cas  de  cet exemple, à une seule page de données.   CREATE INDEX BITMAP ON Ouvrier(spec)  

TABLESPACE spec_espace STORAGE (INITIAL 2M PCTINCREASE 10);  Un  autre  index  bitmap  peut  être  aussi  créé  sur  lʹattribut  salaire. Ce  deuxième  index permettra de calculer rapidement la réponse à une question du genre suivant :  Quels sont les employés soudeurs qui gagnent 30 000.00$?   

ROWID  20000  30000  40000  <‐‐bitmap sur salaire 00055:000:0023  1  0  0   00234:020:8922  0  1  0   19000:328:6200  0  0  0   21088:120:1002  0  0  1   

 En  effet,  avec  un  index  sur  l’attribut  salaire,  il  suffit  de  faire  lʹintersection  des  deux colonnes,  salaire  de  30  000.00  avec  celle  de  soudeur.  Les  tuples  du  résultat  sont accessibles via la clé de la table Ouvrier.    

ROWID  soudeur  30000  réponse 00055:000:0023  0  0  0 00234:020:8922  1  1  <‐‐‐‐1 19000:328:6200  0  0  0 21088:120:1002  0  0  0 

Calcul dʹune réponse à une requête conjonctive Figure 8.8 

Page 137: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

137

 Lʹouvrier décrit par le tuple 00234:020:8922 est un soudeur gagnant 30 000 $ par année. Cʹest le seul tuple de la réponse.                                      

8.8 Index partitionné Avec le SGBD Oracle 8, les index peuvent être aussi partitionnés comme cʹest le cas avec les  tables.  En  ce  faisant,  chaque  partition  peut  avoir  ses  caractéristiques  de  stockage, notamment un fichier exclusif utilisé pour le stockage des seules données de la partition. L’utilité de ce mécanisme reste cependant à démontrer. 

Création des  index simple et composé Un  index  (B*‐arbre)  est  avant  tout  un mécanisme  qui  privilégie  un  chemin  d’accès particulier et rapide pour accéder aux tuples. Si cette valeur est unique, i.e. associée à un seul  tuple, cela permet de vérifier  l’unicité de valeur dans une colonne dʹattributs sans faire un accès physique aux tuples de la table.   Un  message  d’erreur  est  émis  si  une  deuxième  valeur  identique  est  ajoutée.  La spécification  d’une  clé  primaire  active  dans  le  schéma  d’une  table  génère automatiquement  un  index  interne  géré  par  le  système. Cela  n’est  pas  le  cas  avec  la spécification de  la clé étrangère qui peut être  indexé par  la création  subséquente d’un index. Un  index peut donc être créé, au besoin par  le DBA, afin dʹaccélérer  lʹaccès aux tuples.                          

CREATE [unique] index <nom_index> on <nom_relation> (col1, col2, ...)  La commande de création d’un index peut avoir des arguments concernant le stockage : tablespace, PCTused, PCTfree, initrans, etc. L’index est lui‐même une table qui peut être consultée  comme n’importe  quelle  autre  table de  base de  la BD. Toutefois,    en  cours d’exploitation, la table d’index est parcourue avec une structure de B‐arbre ou une de ses variantes.                     

CREATE INDEX  nom de lʹINDEX 

schéma.

ON  table (‐‐‐‐‐‐‐‐‐‐‐‐‐  colonne  ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐schéma. 

ASC DESC 

CLUSTER  nom_cluster schéma.

Page 138: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

138

                                                                            Figure 8.9                  

Caractéristiques des index Un index est stocké sous la forme de tuples dans une table comportant une colonne pour lʹentrée  de  lʹindex  et  une  autre  pour  le  rid  du  tuple  indexé.  Si  un  index  est  unique, chaque valeur dʹindex est appariée à une  seule valeur de  rid, donc à un  seul  tuple de données.  Les propriétés d’un  index  sont parfois explicitement  spécifiées ou  sous‐tendues par  la procédure de création des index du SGBD.   a)  L’index  est  créé  automatiquement  lorsqu’une  clé  primaire  est  spécifiée  dans  un schéma.   Il est alors du  type système en ce sens quʹil ne peut pas être supprimé par  le DBA  autrement  que  par  redéfinition  du  schéma.  L’index  de  la  clé  primaire  peut cependant  être  désactivé  temporairement  par  le DBA  au moyen  de  la  clause ALTER TABLE. Lʹindex peut être supprimé avant une mise à jour importante et être refait par la suite en une seule opération (facilite le chargement en lot).  b) Les tuples d’index peuvent cohabiter avec les tuples de données dans le même espace de données, mais dans des segments (donc des pages) différents;  ils peuvent aussi être avec profit regroupés dans un tablespace spécialisé réservé exclusivement au stockage des index.   c) Les entrées sont mises automatiquement à jour au cours de l’exploitation de la base, ce qui peut entraîner un ralentissement lors dʹune mise à jour intensive. Ce ralentissement vaut aussi pour une entrée composée de plusieurs attributs de la même table.  d) Les  index sont utilisés  implicitement par  l’optimiseur de requêtes.  Il est possible de bloquer l’usage d’un index dans la phase d’optimisation par la formulation du prédicat ou  en  fournissant  directement  une  directive  à  lʹoptimiseur  (hint).  La  recherche  des données dans une table est accélérée par un index, mais l’ajout est ralenti par la mise à jour sous‐jacente de l’index en question. Le parcours complet d’une table (full table scan) n’est pas nécessairement accéléré par un index. Ce parcours exhaustif est une opération qui demeure lente et que lʹon doit de préférence éviter dans les applications.  e)  Les  index  utilisent  lʹespace  de  la  ZMP    (Zone  de Mémoire  Partagée  gérée  par  le moteur SGBD) qui autrement serait utilisé par les pages de données; un index ne devrait être utilisé que pour les tables dont la cardinalité est de lʹordre de 1 000 tuples et plus.  

extension TABLESPACE nom_tablespace NOSORT 

Page 139: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

139

f) Un index peut‐être dense ou non selon que les entrées pointent sur un tuple ou sur un lot de tuples (i.e. une page). En outre, il peut induire un placement (clustering) des tuples associé à lʹordre des entrées de lʹindex. 

Usage des index par lʹoptimiseur En  règle générale,  les  index  sont utilisés pour  le  calcul d’une  réponse,  car  ils  sont  en principe  capables  d’en  accélérer  l’obtention.  Il  est  cependant  possible  dʹen  bloquer lʹexploitation  par  une  formulation  syntaxique  particulière  des  clauses  SQL  ou  par  le recours aux ʺhintsʺ de l’optimiseur du SGBD. Lʹoptimisation est bloquée dans  le  cas des  requêtes  suivantes qui  comportent une des caractéristiques suivantes : a) Un attribut indexé est modifié par une fonction ou une expression arithmétique; b) Un attribut indexé est modifié par un NOT  ou un !=  ou est testé pour un NOT NULL; c) Lʹabsence de la clause WHERE ; d) Un attribut indexé associé à une recherche de caractères par lʹopérateur de chaîne % placé en début de chaîne. Les  mécanismes  détaillés  mis  en  œuvre  dans  l’optimiseur  seront  étudiés  dans  un prochain chapitre.  

Exemples de création dʹindex : a) Créer un index avec le nom de l’article en inventaire (clé candidate) : 

 CREATE UNIQUE INDEX idx_article_Inventaire on Inventaire (article); 

 Le  nom  de  lʹindex  est  choisi  par  le DBA  et  peut  être  normalisé  en  le  préfixant  par exemple par idx_, suivi du nom de lʹattribut indexé et finalement terminé par le nom de la table.  b) Créer un  index unique  et  composé dont  les  entrées  sont  formées  avec  les  attributs (description  et  proprio)  de  la  relation  Pieces.  Cette  paire  d’attributs  étant  une  clé candidate, un index unique peut être créé.  

Pieces (nop*, description, km, ville_p, proprio)  Create UNIQUE index idx_desc_propr_Pieces on Pieces (description, proprio); 

 Cet  index  composé  peut  accélérer  de  façon  significative  le  calcul  de  la  réponse  aux requêtes  qui  utilisent  les  deux  attributs  dans  un  prédicat  conjonctif  de  sélection.  La recherche est réalisée par la consultation de lʹindex composé pour obtenir l’ensemble des rids de la réponse.   

SELECT * FROM Pieces WHERE description =‘porte’ And proprio ='f1';

Page 140: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

140

 Si la requête est exécutée fréquemment, le gain de performance sera alors d’autant plus important. Lorsqu’une  requête  conjonctive ne  concerne  qu’une  seule  table,  l’existence d’un index sur lʹun des attributs permet normalement d’accélérer le calcul de la réponse. L’optimisation  en  tient  compte  pour  établir  le  plan  d’exécution  de  la  requête.  En revanche, une  requête disjonctive ne gagne pas nécessairement  en  temps de  calcul  en utilisant un seul    index. En effet,  il  faudra  faire un balayage complet de  la même  table pour  vérifier  la deuxième partie du prédicat disjonctif. Autant  alors  éviter  l’appel de l’index et vérifier  le prédicat  lors d’un seul balayage séquentiel. Si tous  les attributs du prédicat  sont  indexés, alors  les  index peuvent être utiles. Le balayage d’une  table  (full table  scan)  est une opération  longue qu’il  faut  autant que possible  éviter  en  raison du transfert  d’un  nombre  important  de  pages  entre  les  disques  et  la  zone  de mémoire partagée (ZMP ou SGA‐Oracle).   Avec une requête concernant plusieurs tables, l’absence de tout index pour les attributs non primaires utilisés dans  le prédicat  sous‐tend un balayage obligatoire  complet des deux tables. Avec un seul index, l’optimiseur choisira entre plusieurs plans d’exécution en  estimant  lequel  sera  le  plus  rapide  pour  calculer  la  réponse.  C’est  la  base  de  la stratégie qui repose sur le coût de calcul. 

Suppression d’un index L’index  est  un  objet  de  la  BD  comme  lʹest  une  table  de  données.  Il  peut  donc  être supprimé par la  commande DROP INDEX :  Drop index <nom de l’index> L’index est alors supprimé et sa définition est enlevée du dictionnaire de données.                                 Exemple : Supprimer l’index nommé idx_piece_inventaire: 

Drop index idx_piece_inventaire                      L’espace utilisé par l’index est libéré sans entraîner automatiquement une réorganisation de  l’espace disque  impliqué dans  la suppression des pages de  l’index. Cet espace sera cependant éventuellement réutilisé par le SGBD. 

8.9 Guide dʹutilisation des index en cours dʹexploitation de la BD Plusieurs  règles  de  pratique  sont  proposées  par  les  sociétés  qui  commercialisent  les systèmes haut de gamme sur lʹusage des index dans l’exploitation de la BD. Il faut tenir compte des facteurs suivants :  a) Les index utiles sont ceux nécessaires à l’exploitation courante des données (évitez les traitements  hypothétiques  ou  prévus  mais  non  confirmés  par  des  applications  en production) en fonction du profil d’utilisation des données. Il est utile dʹavoir recours à un  fichier  de  commandes  pour  créer  les  index,  afin  de  spécifier  plus  facilement  les paramètres  concernant  l’espace  de  données  (tablespace)  nécessaire  à  la  création  du segment d’index. Il devient alors tout aussi facile de les supprimer que de les créer. 

Page 141: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

141

 b) Il faut supprimer les index lorsquʹil sʹagit de traiter un flux important de transactions du  type mise à  jour  sur une  table. Les  index  sont d’abord  supprimés, puis  recréés au besoin après les mises à jour. Cette opération est indiquée lors des traitements en lot ou du chargement d’une table avec un fichier de données validées.  c) Durant une session intensive de création de rapports et de calcul de requêtes, le DBA verra à  créer  les  index nécessaires  en  tenant  compte des  tables qui  seront utilisées au cours de la préparation du rapport et du calcul des réponses.    d) L’index de  clé  (en version  système)  est aussi utilisé pour assurer  l’unicité de  la  clé monoattribut, i.e. pour renforcer la contrainte de clé spécifiée dans le modèle relationnel. Au besoin, la clé primaire peut être désactivée par un DISABLE pour bloquer la mise à jour de l’index système sous‐jacent, mais l’index sur la clé primaire n’est pas détruit. La réactivation  de  la  clé  primaire  lance  cependant  la mise  à  jour  rétroactive  de  lʹindex système correspondant.  e) Une accélération de la  jointure est possible par la création des index : les attributs de jointure  qui  sont  indexés  permettent  un  accès  plus  direct  aux  tuples  vérifiant  la condition de jointure.  Exemple : 

SELECT Empl.nom, Y.dnoDep,Y.nomDep FROM  Empl E, Dep Y  WHERE Empl.noDep = Y.noDep ; 

                Dans ce cas, l’index sur la clé primaire est automatiquement utilisé en conjonction avec celui créé par le DBA sur la clé étrangère.                                  Index simple et composé de Oracle  Deux sortes dʹindex sont disponibles avec le SGBD Oracle : simple et composé. Dans les deux cas, ils sont de type dense, i.e. que les entrées pointent sur des tuples et non sur des pages. Lʹindex simple est construit avec  les valeurs d’un attribut d’une seule  table. On doit  éviter  de  créer  un  tel  index  pour  les  attributs  peu  sélectifs  dont  le  facteur  de sélection est supérieur à .35, par exemple le sexe d’une personne ou le nom. Il convient dʹutiliser l’index simple déclaré UNIQUE pour valider l’unicité des valeurs d’un attribut, car la vérification est alors effectuée sans faire un accès aux tuples de la table.  

CREATE UNIQUE INDEX idx_assig_empl ON Assignations(noEmpl);  L’index  composé  est  défini  avec  plusieurs  attributs  dʹune  même  table.  Il  y  a  alors accélération du calcul pour les requêtes dont le prédicat se réfère à tous les attributs de l’index composé.     

Page 142: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

142

CREATE INDEX idx_no_poste_no_mpl_assignations  ON        Assignations (noPoste, noEmpl); 

 Lʹindex composé est construit avec  les entrées  formées de plusieurs attributs ordonnés dʹune même relation. Une entrée peut avoir jusquʹà 16 attributs dont lʹordre est figé dès la création de  lʹindex. Si  le prédicat d’une clause SQL fait référence au premier attribut de  l’index  composé,  celui‐ci  sera  employé  pour  accélérer  le  calcul.  Si  seulement  le deuxième est référencé, l’index ne peut pas être utilisé. Dans ce cas, s’il existe un index simple  sur un des  attributs de  l’entrée de  l’index  composé,  il  sera mis  à  contribution  pour le calcul de la réponse.                                  Voici un exemple avec création d’un index supplémentaire monoattribut pour la relation Assignations, en sus d’un  index composé existant sur  les attributs  (no‐poste, no‐empl). La  requête  suivante  utilise  une  jointure  qui  fait  seulement  référence  au  deuxième attribut de l’index composé, soit le noEmpl.   

Select E.noEmpl, E.nom From  Empl as E, Assignations as A Where E.noEmpl = A.noEmpl ;  

 Le calcul de  la  réponse en  lʹabsence dʹun  index  simple  sur  la clé étrangère ne  tire pas profit de  l’index composé qui  inclut  la clé étrangère.  Il y aura un balayage complet et séquentiel de  la  table Assignations,  puisque  cette  jointure  fait  référence  au deuxième attribut  de  lʹindex  composé. Une meilleure  performance  sera  obtenue  par  la  création avec l’attribut noEmpl   d’un index simple sur la clé étrangère.                                      

CREATE INDEX idx_noEmpl_Assignations ON  Assignations(noEmpl) ; 

                               Ainsi,  le  calcul  de  la  réponse  précédente  est  accéléré,  car  l’index  simple idx_noEmpl_Assignations est disponible et l’optimiseur en tirera profit dans le calcul de la jointure.  

Optimiseur et index composé Les  index  sont  utilisés  par  l’optimiseur,  notamment  si  certaines  informations  sont présentes dans  le prédicat  (WHERE) des requêtes. Nous allons  faire un bref survol de quelques choix d’optimisation que ce dernier peut faire en cours de traitement : a) Tous  les attributs d’un  index composé doivent être présents dans  la clause WHERE, peu importe leur ordre dans la clause, pour que l’optimiseur en tire profit.  b)  Si  le  premier  attribut  de  l’index  composé  idx_noPoste_noEmpl_Assignations    est présent  dans  le WHERE,  l’index  composé  est  utilisé.  S’il  est  absent,  l’index  composé devient inutile. 

Page 143: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

143

     

     

segment 2Page d’index 

Page d’index 

Page  de données 

Page  de données 

segment 1 

  SELECT *  FROM  Assignations A, Empl E WHERE A.noEmpl = E.noEmpl and article =ʹa1ʹ;  

L’absence de l’attribut  noPoste rend l’index composé inutilisable.  c) La négation dans une condition bloque  l’usage des  index composés par  lʹoptimiseur puisque les valeurs hors domaine ne sont pas indexées.    

SELECT *  FROM  Ventes WHERE nom != ʹChristineʹ and Ventes.article  = ʹa1ʹ; 

Quand faut‐il créer un index composé ? Lorsque certains attributs sont fréquemment utilisés ensemble dans l’exploitation d’une BD,  il  peut  être  alors  avantageux  de  définir  quelques  index  composés.  La  décision dépendra du suivi de  l’exploitation  fait par  le DBA et des statistiques de performance mesurées par le noyau du SGBD.  

8.10 Indexation avec Oracle Les  relations  créées ne  sont pas  indexées  automatiquement,  sauf pour  la  clé primaire (simple  ou  composée)  qui  est  spécifiée  dans  le  schéma  d’une  table  par  la  clause PRIMARY KEY. Cette  clause  impose  la  création de  l’index  sur  la  clé primaire,  lequel index  est  maintenu  par  le  système  SGBD  indépendamment  du  DBA.    La  clause PRIMARY KEY  spécifie  une  contrainte  de  clé    vérifiée  par  le  SGBD  au moyen  dʹun mécanisme approprié qui peut être un index, un trigger ou une fonction de hasching.                               La clé étrangère spécifiée dans un schéma de relation ne génère pas automatiquement un  index  sur  celle‐ci.  La  contrainte  référentielle  spécifiée  dans  le  schéma  identifie simplement  les attributs qui sont  impliqués dans une contrainte référentielle et rien de plus .          

Index et données dans divers segments Figure 8.10 

Page 144: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

144

 Lʹindex  sur  la  clé  étrangère  doit  être  créé  explicitement  par  la  commande  CREATE INDEX. Les pages des  tuples d’une même  table  forment un segment,  tandis que celles d’un index sur la même table forment un autre segment distinct quant à sa structure. La lecture d’une page d’index permet de lire une  page de données de tuples grâce aux rids fournis par le B‐arbre.   Lʹespace dʹune page dʹindex est géré à peu près comme celui des données, soit avec  le paramètre  PCTFREE.  Par  exemple,  avec  un  PCTFREE  de  20 %,  de  nouvelles  entrées dʹindex pourront être ajoutées dans une page (via de nouvelles cellules) et cela, tant quʹil y a 20% dʹespace libre dans celle‐ci. Lorsque l’occupation passe la barre du PCTFREE, la page perd  son  statut de page  insérable.  Il  est  alors  impossible dʹajouter de  nouvelles entrées  tant que  lʹespace utilisé nʹest pas  revenu  à un niveau  inférieur  à  la valeur du PCTUSED. À ce moment, la page devient à nouveau insérable et est ajoutée à la liste des pages  libres  (free  list).  La  libération  dʹespace  provient,  soit  des modifications  soit  des suppressions des entrées de lʹindex. Toutefois, la mise à jour dʹun index non unique par lʹajout de ROWID  comme une  entrée  sera possible grâce  à  lʹespace disponible  (20 %) pour  le  débordement.  Puisquʹun  index  est  lʹobjet  dʹune  grande  activité  en  cours dʹexploitation,  le  PCTFREE  doit  être  assez  élevé  pour  un  index  non  unique  afin  de permettre  lʹinsertion des  adresses de  tuple dans  les  feuilles  et  cela,    pour  une  entrée existante.   

Occupation d’une page d’index Figure 8.11 

Enfin,  il y  a  avantage  à privilégier  la  consultation des pages dʹindex par des  lectures logiques (logical read), cʹest‐à‐dire des lectures dans les pages déjà présentes dans le SGA, de manière  à  éviter  les  lectures  physiques  (physical  read),  cʹest‐à‐dire  celles  toujours lentes des pages physiques  sur un disque. Les  lectures  logiques  seront probablement plus fréquentes si les adresses de tuple pour une même entrée sont dans la même page. Les pages des index sont rangées dans la ZMP et sont lʹobjet de verrouillage. Ainsi, un tuple  de données, qui sera trouvé par un index et dont la valeur de lʹattribut indexé sera modifiée, forcera le système à verrouiller lʹentrée de lʹindex (le tuple correspondant à son entrée) en plus de poser un verrou RX  sur  la  table à modifier. Le double verrouillage 

20% pour le PCTFREE       70%  pour  le PCTUSED

Page 145: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

145

peut  ralentir  la  concurrence de  lʹaccès  aux données, notamment  lorsque  la  localité de référence aux données est relativement grande lors de l’exploitation de la base.  La mise  à  jour des  index  suit  toute modification  et  toute  insertion de  tuples dans  les relations et est assurée automatiquement par le SGBD. Plus les attributs dʹune table sont indexés, plus le temps global de mise à jour est important. En effet, le SGBD doit faire la modification dans  le  tuple, mais aussi dans  tous  les  index  faisant  référence aux  tuples modifiés.   Un index peut être simple ou composé selon que son entrée comprend un ou plusieurs attributs.    

CREATE INDEX [schéma.]<nom_idx> ON [schéma.]<table>  (attribut [asc|desc], ...) INITRANS <entier>  MAXTRANS <entier> TABLESPACE <tablespace>  STORAGE <initial , next  , MINEXTENTS  ,... >  PCTFREE <entier> [NOSORT] ;   

 La suppression dʹun index est réalisée par la commande DROP INDEX.   

DROP INDEX [schéma.]<nom_index> ;                                                 Exemple : CREATE INDEX idx_proprio_pieces on Pieces (proprio) ASC  

INITRANS 3 MAXTRANS 6  Tablespace espace1  storage 5M initial 10K next 10K minextents 2  maxextents 20  PCTINCREASE 20 PCTUSED 40 PCTFREE 40; 

 Lors  de  la  création  de  lʹindex  idx_proprio_pieces,  le  segment  est  créé  avec  deux extensions de 10K octets. Au besoin, une 3e extension est créée de 10Ko, et par la suite les extensions sont créées avec une augmentation de 20%. 

Quelques facteurs de performance avec le SGBD  Oracle Le  calcul  des  réponses  est  accéléré  avec  les  index  et  les  groupements  des  données (clusters)  et  sous‐tend  une  gestion  performante  de  la mémoire  physique14.  Le  noyau d’Oracle  aura  accès plus  rapidement  aux  tuples  avec un mécanisme d’indexation. De plus, un accès plus direct aux  tuples  favorisera  la  réduction de  l’activité de  I/O  sur  le canal  du  disque.  En  revanche,  les  index  ralentissent  la mise  à  jour  parce  que  toute modification de la valeur d’un attribut dans une relation de base doit être, si l’attribut est indexé,  répercutée  dans  l’index.  La  séparation  des  pages  d’index  et  des  pages  de données  dans  leurs  tablespaces  respectifs  favorisera  la  performance  en minimisant  les échanges de pages, sous réserve d’une ZMP suffisamment grande pour contenir à la fois les  pages  de  données  et  celles  des  index.  La  présence  de  plusieurs  disques  avec  des 

Page 146: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

146

contrôleurs différents est aussi un facteur de performance pour autant que  les  index et les données des tables soient rangées sur des disques différents.     

8.11 Indexation de la clé primaire et de la clé étrangère Une  clé  primaire  simple  ou  composée,  spécifiée  dans  le  schéma  dʹune  relation,  est implémentée  par  la  création  automatique  dʹun  index  système  qui  est  rendu immédiatement,  actif,  sauf  si  la  clause DISABLE  est  spécifiée. Les valeurs nulles  sont exclues  implicitement de  la  clé  et n’apparaissent donc pas dans un  tel  index  système. Toutefois, la clé primaire pouvant être désactivée, les attributs qui la composent doivent être déclarés NOT NULL, car autrement lʹinsertion de tuples avec des attributs primaires nuls serait tolérée jusquʹà la prochaine réactivation de lʹindex de la clé primaire. C’est à ce  moment  que  la  contrainte  de  clé  sera  vérifiée.  Normalement,  l’index  sur  la  clé primaire  est  actif  à  la  création de  la  base de données  et  le demeure  au  cours de  son exploitation transactionnelle.    Voici un exemple pour illustrer la désactivation de la clé primaire de la table Empl. 

ALTER TABLE Empl primary key DISABLE;

Ajout de tuples dans une table enfant En l’absence d’un index sur la clé étrangère, la contrainte référentielle est vérifiée par un trigger ou une procédure  interne qui sous‐tend  le balayage complet des données de  la table.                                  

Figure 8.11a Dans ce cas, pour éviter un verrou bloquant sur  la  table et  favoriser  la performance,  il suffira  de  créer  un  index  avec  la  clé  étrangère,  index  qui,  ajouté  à  celui  de  la  clé principale  de  la  table  parent,  permettra  de  vérifier  la  présence  dʹune  valeur  de  clé primaire  (ajout  dans  la  table  enfant)  ou  de  clé  étrangère  (suppression  dans  la  table 

Suite à l’ajout dans la table enfant, un trigger balaie la table parent pour déterminer si  l’usine  référencée dans  le nouveau  tuple  est  bien présente dans  la  table Usine. Pour faire ceci, tout ajout est temporairement bloqué dans la table Usine. 

 

Ajout d’un atelier  

Table Atelier 

Les tuples de Usine sont verrouillés pour  assurer  la  consistance  de lecture 

Table Usine 

noUsine Déclenchement du  trigger 

T2 : Delete    u1 ??

T1 : (a2, …. u1) 

Page 147: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

147

parent) sans verrouiller ni accéder aux  tuples de  la  table parent. Une contrainte de clé étrangère est automatiquement renforcée en lʹabsence de la clause DISABLE pour la clé primaire de  la  table parent. Cependant,  cette  contrainte  référentielle ne  se  traduit pas nécessairement par la création automatique dʹun index avec la clé étrangère.        

Figure 8.12  Elle est implémentée par un mécanisme interne qui fait référence à la clé primaire de la table parent ou par un  trigger qui sous‐tend  le verrouillage complet de  la  table parent suivi de son balayage en entier (full table scan).  Au début de la transaction T1 qui ajoute un tuple dans  la table Atelier, si  lʹusine référencée par ce nouveau tuple est absente,  le trigger enclenché doit aboutir à un échec.  La présence d’un index sur la table parent, permet au système de vérifier la présence de l’usine référencée et de placer un verrou partagé (Shared lock) sur l’entrée de l’index de la clé  primaire,  qui  bloque  de  facto  la  suppression  de  ce  tuple  parent  par  toute  autre transaction. Le verrou est maintenu  jusqu’à  la  fin de  la  transaction T1.   Lʹeffet net sera une plus grande concurrence aux données au profit des autres transactions.                           De même, la suppression d’un tuple dans la table parent par T1 exige la vérification de la référence éventuelle de ce tuple par ceux de la table enfant. Pour éviter de bloquer la table  enfant  aux  autres  transactions,  un  index  créé  avec  la  clé  étrangère  permet  de vérifier rapidement une référence à  la clé primaire, de poser un verrou  temporaire sur l’entrée correspondante dans l’index de la clé étrangère, bloquant momentanément toute suppression aux  tuples enfants et cela, par  le moyen d’un verrou partagé appliqué sur l’entrée de  l’index pour  la durée de T1. Ainsi,  toute  autre  transaction T2  est  interdite d’ajout d’un tuple dont la clé étrangère aurait la valeur de l’entrée de l’index verrouillée par T1.  

Pertinence de lʹindexation Il nʹest pas toujours approprié dʹindexer les attributs dʹune relation sans tenir compte de lʹexploitation  réelle  des  tables.  Ce  nʹest  que  par  un  suivi  approprié  et  rigoureux  de lʹexploitation des données et un bon travail de coordination avec les concepteurs, quʹun DBA  peut  mettre  au  point  et  adapter  les  accès  à  la  BD  par  des  index  qui  sont essentiellement un mécanisme dʹaccès  rapide  aux  tuples. Lʹindexation doit  être  revue périodiquement  pour  tenir  compte  des  changements  dans  le  profil  dʹexploitation  des données. Un index fort utilisé pendant une période peut devenir nuisible par la suite si le taux dʹaccès à la table indexée chute radicalement.  

noUsine,   noUsineIdx

                            noUsine Ajout  d’un atelier

Verrou sur l’entrée

25 

25Table enfant Atelier 

Table parent Usine 

Page 148: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

148

Observations pratiques pour lʹindexation 1. La spécification de la clé primaire engendre la création d’un index système unique et actif, sauf sʹil est désactivé par le mot clé DISABLE. 2. Si  la clé est utilisée  fréquemment dans une  jointure  impliquant  la clé étrangère, une meilleure  performance  pourra  être  obtenue  avec  un  index  actif  défini  sur  la  clé étrangère.  La  contrainte  référentielle  doit  cependant  rester  active.  Par  contre,  un  tel index peut ralentir les mises à  jour sur la clé étrangère (DELETE CASCADE) parce que celles‐ci doivent  être  répercutées  sur  l’index.  Il  faut donc  éviter dans  ce  cas de  figure lʹindexation de la clé étrangère.  3. Si la cardinalité dʹune relation est supérieure à 1000 tuples et que cette table est utilisée fréquemment dans une  jointure,  la  création dʹun  index  avec  les  attributs de  jointures accélère généralement le calcul de la réponse. 4. Un  index composé est utile si  les attributs  indexés sont souvent utilisés comme une suite  conjonctive  de  valeurs. Un  tel  index  composé  est moins  utile  avec  les  requêtes disjonctives. 5. Un  index nʹest pas nécessaire pour des exploitations séquentielles du type  ʺfull scanʺ comme la préparation de listes exhaustives des tables qui utilisent toutes les valeurs des attributs dʹune relation. Un  index est guère utile avec un attribut dont  la sélectivité est inférieure à 0,35. 7. Les attributs de la clause WHERE seront l’objet d’une indexation. Avec une condition dʹégalité,  le  calcul  est  accéléré  avec  une  fonction  de  Hashing,  tandis  qu’avec  une condition impliquant une plage de valeurs, le calcul est plus rapide avec un index en B‐arbre. 8. Généralement, un  index sur une relation peut être de  type cluster pour accélérer  les requêtes de jointure assorties d’un intervalle (plage), sauf si lʹévaluation n’est faite quʹau niveau de lʹindex. Dans ce dernier cas,  le clustering nʹest pas nécessaire.  Durant  la  phase  dʹanalyse,  le DBA  doit  en  premier  répertorier  les  applications  et  les attributs  utilisés  par  celles‐ci  pour  accéder  aux  données.  Si  certains  attributs  sont fréquemment utilisés par les applications, ce sont des attributs candidats à lʹindexation. Il faut aussi considérer les applications déjà planifiées pour s’attarder particulièrement à celles qui font de très nombreuses lectures. En contrepartie, si les applications ont aussi une charge de mise à jour très importante, il faut prendre en compte le fait que les index sont plutôt lourds à mettre à jour. Quelle que soit la décision, le DBA doit surveiller de près  l’évolution des performances du système et prendre  les mesures qui sʹimposeront pour les améliorer, notamment la création ou la suppression d’index. 

8.12 Placement des tuples par le cluster Le  clustering  ou  le  regroupement  des  tuples  dʹune  ou  de  plusieurs  tables  est  un mécanisme  de  placement  des  tuples  partageant  une même  valeur  pour  les  attributs définis comme attributs du regroupement. Il y a donc création dʹune nouvelle structure de  page  caractérisée  par  deux  en‐têtes.  Normalement  les  tuples  de  deux  tables différentes  sont  rangés  dans  des  pages  différentes  respectivement  allouées  aux  deux tables.  Il  en  est  autrement  avec  le  cluster.  Il  sʹagit  pour  le  système  SGBD  de  placer 

Page 149: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

149

physiquement  les  tuples  qui  interviennent  dans  le  calcul  des  jointures  le  plus  près possible  les  uns  des  autres,  de  préférence  dans  la même  page.  Il  y  a  deux  types  de placement  indexé  :  le  cluster  indexé  et  le  cluster  avec Hashing.  Le  premier  implique deux  ou plusieurs  tables,  tandis que  le deuxième  sous‐tend une même  table dont  les tuples sont placés dans des pages dont  lʹadresse est dérivée de  la valeur dʹun attribut. Ces clusters sont spécifiés et créés au besoin par le DBA. Prenons lʹexemple de la BD de Dotation des  ressources humaines, BD3 dans  laquelle  le  taux horaire est multiplié par 100.    

postes : noPoste*  description   j12  gérant   j34  peintre   j98  null   j21  mécano1   j55  contrôleur   j75  mecano2 

                                 empl :   noEmpl*  nom  prenom  tauxH  (x100) 

  P346  Audy  rudy  1300   P456  Gagnon  andré  1715   P345  Audy  michel  1250   P651  Tremblay  robert  1250   P762  Dussault  marc  1325   P337  Bérube  null  1250   P450  Dion  fabrice  1325   P535  Joncas  sylvie  1450 

 assignations :  noPoste*  noEmpl*  debut  quart   j12  P456  21‐jan‐1992  soir   j34  P651  22‐mar‐1991  jour   j21  P762  23‐dec‐1990  nuit   j34  P345  24‐sep‐1994  jour   j75  P346  12‐oct‐1997  null   j55  P456  25‐jan‐1994  jour   j34  P337  21‐jan‐1992  nuit   j75  P450  27‐jan‐1994  null 

                        Pour connaître la description du poste occupé par un ou plusieurs employés, il faut faire une  jointure entre  les tables Assignations et Postes, en utilisant  lʹattribut noPoste. Pour accélérer  le  calcul,  le  système peut placer, de préférence,  les  tuples de ces deux  tables dans la même page en se basant sur la valeur de noPoste. Ainsi, les tuples de ces deux tuples  qui  concernent  les  employés  occupant  la  fonction  ‘j75’    seront  placés  dans  la même page pour en faciliter les accès et les comparaisons. Les attributs spécifiés avec le critère de placement sont appelés la clé du regroupement (ou du clustering). Dans notre exemple, le noPoste est lʹattribut de clustering.  

Page 150: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

150

                                                                      Le placement par  clustering ne  se  limite pas au  seul  calcul dʹune  jointure.  Il peut  être utilisé  pour  gérer  le  placement  des  tuples  de  diverses  tables  dʹune  BD  que  les applications rapprochent par leur traitement.                      Par  exemple,  si  une  application  en  L3G  doit  faire  la  liste  des  transporteurs  dans  la colonne  gauche  dʹun  rapport  et  ensuite  celle  des  pièces  dans  la  colonne  droite,  elle exploite  simultanément  les deux  tables Transporteurs  et Pièces  sans  faire de  jointure. Dans ce cas, on aura avantage à placer les tuples des deux tables dans les mêmes pages en déclarant  les deux  clés, primaire  et  étrangère, de  ces  tables  comme un  attribut de clustering  (cʹest‐à‐dire  placement  regroupé).  Les  tuples  ayant  la  même  valeur  pour noPoste sont rangés dans les mêmes pages ce qui accélère le calcul de la jointure.   

8.12.1 Placement par Hashing (Hash clustering) Dans  ce  cas,  le  placement  concerne    les  tuples  dʹune  ou  de  plusieurs  tables  dont  le rangement dans la BD est calculé par une fonction de Hashing, soit la fonction H fournie par le SGBD, soit selon la valeur fournie explicitement par un attribut.   Lʹespace des clés du cluster est défini comme la plage des valeurs possibles définie par les bornes inférieure  et  supérieure. En pratique,  toutes  les valeurs de  la  clé du  cluster ne  sont par utilisées par la clé. Lʹintervalle de ces valeurs est donc condensé en premier à une plage plus petite au moyen d’une fonction T appelée par l’application et dont les valeurs sont par la suite traitées par un Hashing pour donner les adresses de pages. Par exemple, le taux horaire (x100) payé à un employé varie de 1250 à 1450 dans la table et seulement 5 % de ces valeurs sont réellement utilisés,  soit environ 50 numéros.            

(j34, peintre)  (j34, P651, 22‐mars‐1991, jour)  (j34, P337, 21‐jan‐1992, nuit) (j34, P345, 24‐sep‐1994, jour) 

(j21, mécano1) (j21, P762, 23‐dec‐1990, nuit) 

Page de cluster (structure logique) Page de cluster(structure logique) 

Page 151: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

151

         

Figure 8.14  La fonction de transformation T consistera donc à calculer pour chaque taux une valeur entre  0  et  50  par  une  transformation  appropriée  souvent  basée  sur  un modulo.  En supposant la taille dʹun tuple à 1Ko et que 200 valeurs sont théoriquement possibles, il faudra prévoir un maximum de 4 tuples ayant les mêmes valeurs de Hashing regroupés dans  une même  page  de  4 Ko.  Lʹespace  à  prévoir  pour  le  stockage  des  tuples  et  les collisions sera donc de 4 *1Ko/t = 4Ko, soit la taille d’une page.   Pour créer un cluster de Hashing, il faut spécifier les attributs de clustering et le nombre de valeurs de H possibles, ainsi quʹun estimé du nombre de tuples ayant la même valeur pour la fonction H. Dans lʹexemple ci‐dessus, il peut y avoir jusquʹà cinquante valeurs de Hashing différentes (mod50). On estime que 4 tuples, qui ont la même valeur et dont la taille est près de 1Ko, nécessitent un espace de rangement  de 4K  (SIZE). Il y aura donc jusquʹà 4 tuples par page (de 4K). Le SGBD fournit par défaut sa fonction de Hashing .                          CREATE CLUSTER TAUX_CLUST (c_taux number(4)) 

SIZE 4K ‐‐espace du cluster pour ranger les tuples de même H ; taille max = 1 page)  HASHKEYS 50;  ‐‐ nombre possible de clés de Hashing  

 Après  la création du cluster,  il  faut créer  la ou  les  tables  (pour en  ranger  la définition dans  le  dictionnaire)  en  spécifiant  que  les  tuples  seront  rangés  dans  le  cluster TAUX_CLUST, qui est en fait un espace de table un peu spécial quant à la stratégie de rangement des tuples de la ou des tables associées au cluster. 

CREATE TABLE Empl ( noEmpl char(4) not null, nom varchar2(30)) prenom varchar2(30), tauxH number(4), CLUSTER TAUX_CLUST(taux);

                                               Le  lien entre  lʹattribut de cluster c_taux et  l’attribut de  la table tauxH est fait  lors de  la création de la table et de son association au cluster. Lorsquʹune requête fait référence à la table rangée dans un cluster, le SGBD utilise la valeur de lʹattribut de cluster (fournie par 

Valeurs de l’attribut      ( x 100)  1300 : mod(50) = 0 1752: mod(50) = 2 1249 : mod(50) = 49 1325: mod(50) = 25 1431 : mod(50) = 31 

Page 0

Page 1

Page  49 

Page 2

T

Page 152: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

152

lʹattribut de la table correspondant) pour calculer une clé de Hashing et lire la page qui contient le ou les tuples demandés. 

SELECT * FROM Empl WHERE tauxH = 1250 ;

 Lʹattribut taux est inscrit dans le dictionnaire avec un indicateur signalant quʹil est utilisé dans la spécification dʹun cluster. Le SGBD effectue le calcul de la clé de Hashing à partir de la valeur  1250 pour ainsi connaître directement lʹadresse de la page à transférer dans la ZMP : MOD(1250, 50) = 0. Lʹaccès est plus  rapide par  rapport à celui  réalisé par un index qui dans ce cas peut nécessiter le transfert de plusieurs pages avant dʹidentifier le rid du tuple. 

Cluster avec Hashing explicite   Il  est  aussi  possible  de  fournir  la  fonction  de Hashing  (H)  en  remplacement  de  celle fournie par le SGBD. Par exemple, la fonction pour générer le no‐poste peut être définie comme un nombre généré par la séquence poste‐ID‐seq :    CREATE CLUSTER POSTEID_CLUST(poste_ID_SEQ  NUMBER(3)) 

SIZE 4K   ‐‐espace pour ranger les tuples de même valeur H HASH IS (no_poste) mod(25) /* no généré par la séquence*/  HASHKEYS 31; ‐‐ arrondi au premier nombre premier suivant 25 

 Dans ce cas,  le placement des  tuples est dirigé par  le modulo 25 de  lʹattribut no_poste dont la valeur, dans cet exemple, est générée automatiquement par une séquence.  

8.12.2 Cluster indexé    Un cluster  indexé  regroupe dans  la même page  les  tuples ayant  la même valeur pour lʹattribut  de  cluster.  Un  tel  cluster  doit  être  indexé  pour  permettre  dʹexploiter  la cohabitation des tuples dans la même page. Dans ce type de placement, il faut créer un objet cluster et ensuite créer obligatoirement un index. Il est aussi possible dʹutiliser un cluster  indexé avec une  seule  table pour  regrouper  les  tuples ayant une même valeur dʹattribut. Considérons un modèle pour représenter les comptes bancaires et les clients.  CREATE CLUSTER  clust_comptes_bancaires (c_no_compte number(3)); CREATE INDEX ind_clust_comptes_bancaires  ON CLUSTER  clust_comptes_bancaires;  CREATE TABLE Comptes ( 

noCompte number (3) primary key, ville varchar2(35)) CLUSTER clust_comptes_bancaires (no_compte); 

CREATE TABLE Client ( nas char(8) primary key, 

Page 153: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

153

nom varchar2(45),  . . . noCompteClient number (3) Foreign key References  Comptes(no_compte) ) CLUSTER clust_comptes_bancaires (noCompte); 

 Une page dʹun cluster (indexé ou pas) regroupe donc des tuples des deux tables sur  la base de leur valeur commune pour lʹattribut du cluster.                   

Figure 8.15  Les pages du placement ne sont pas prédéterminées par le moteur du SGBD, mais bien par la valeur de la clé du cluster. Les deux tuples de lʹexemple ont une taille différente, mais  sont  associés  au même  attribut  de  cluster.  Donc  les  trois  tuples  concernant  le compte c35 se trouveront dans la même page.  Un  cluster, de par  sa  structure mixte,  freine  lʹaccès  séquentiel  à  tous  les  tuples dʹune même table. En effet, ces mêmes tuples sont rangés dans plus de pages que nécessaire et cela  constitue  une  charge  supplémentaire  pour  la  lecture  séquentielle  des  pages  sur disque. 

noCompte

En‐tête de la page 4

nas7, Tremblay, c35 

nas56, Gagnon c35

nas78, Poulin, c38 

C20 C35 C38

1 2 3 4 5Répertoire du cluster  Chaînage des pages pour  les entrées de même valeur 

Index du cluster 

C35, Québec

tuple client

tuple comptetuple client

tuple client

Page 154: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

154

Pages regroupées (clustered) La jointure est faite via lʹindex et avec la condition suivante :  

Client.noCompte = Compte.noCompte   Le calcul dʹune  telle  jointure est  très rapide, car  les  tuples sont déjà regroupés dans  la même page.    

Index de regroupement (cluster) et ses propriétés : 1‐ Une clé entièrement nulle a une entrée dans  le répertoire. Ce  type d’index est donc différent de celui en B‐arbre qui n’indexe pas les valeurs nulles. 2‐ L’index de cluster est obligatoire pour accéder aux données. Une entrée pointe sur la 1ere page pour une valeur donnée de la clé du cluster.   Autre exemple :  

CREATE CLUSTER Lieu_travail (no_usine number) SIZE 4K, -- espace pour ranger les tuples ayant la même --valeur pour l'attribut du cluster TABLESPACE espace_table1; CREATE TABLE Ouvrier( ... noUsine number ) CLUSTER Lieu_travail(noUsine); CREATE INDEX cluster_idx ON CLUSTER Lieu_travail; [Oracle]

 

8.13 Création et suppression de vues Au  chapitre  sur  le  modèle  relationnel,  la  mise  à  jour  par  lʹentremise  de  la  vue relationnelle  a  été présentée  comme  étant possible dans  certaines  conditions précises, lesquelles  ne  peuvent  pas  être  généralisées.  Avec    les  implémentations  SQL commerciales, la mise à jour à travers une vue est limitée davantage.   CREATE OR REPLACE VIEW VentesImportantes (nom, article, qteTot) AS   

SELECT *  FROM   Ventes WHERE qteTot > 5;                                      Une vue  relationnelle ne peut pas  être  supprimée, ni  être utilisée pour  la mise à  jour d’une relation de base s’il y a violation des contraintes relationnelles actives et renforcées par le SGBD (view dependency).  Une  vue  est  conservée  sous  forme  d’une  définition  SQL  et  ne  correspond  pas généralement  à  une  sous‐table  réelle  et  persistante.  La  vue  n’a  donc  pas  d’extension permanente et nʹest pas un  instantané  (snapshot). Une vue composée d’une  jointure de deux  relations  de  base  pourrait  être  autorisée  à  faire  une  mise  à  jour  seulement  à certaines conditions très particulières qui exigeraient une certaine intelligence de la part 

Page 155: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

155

du SGBD, en plus d’une consultation fréquente du dictionnaire. Cependant, en pratique les systèmes n’autorisent pas  la mise à  jour à  travers une vue définie par une  jointure. Finalement,  une  vue  peut  être  reprise  par  une  requête  SQL  (à  titre  de  relation intermédiaire)  en  remplaçant  ainsi  la  variable du  type  table  qui  n’existe pas  en  SQL. Ainsi, on aura : 

SELECT V.article FROM VenteImportante V ; -- VenteImportante est une vue

 L’extension  d’une  vue  peut  être  affichée  par  une  consultation  de  la  vue  et  sans spécification du prédicat WHERE. La vue  est  aussi dynamique, puisque  toute mise  à jour sera reflétée dans la vue aussitôt quʹelle est recalculée. La notion de table temporaire de la norme SQL‐92 est différente de la vue, puisquʹil sʹagit dʹune véritable table inscrite dynamiquement  dans  le  schéma  et  qui  nʹest  pas  actualisée  par  les  mises  à  jours subséquentes. Elle est donc ainsi différente de la notion de snapshot qui est un instantané des tables et qui peut être mis à jour.  Pour créer une vue, lʹutilisateur doit normalement avoir les droits de lecture et de mise à jour sur la ou les tables de base référencées dans la vue et avoir le privilège système de créer des vues dans son schéma. Toutefois, un utilisateur autorisé à créer des vues peut le  faire même  sʹil  nʹa  pas  les droits dʹaccès  sur  les  tables de  base dont  il  nʹest pas  le propriétaire. Cette opération est possible avec la clause CREATE FORCE  VIEW.  

CREATE FORCE VIEW Ventes_Tres_Importantes (nom, article) as SELECT nom, article FROM Ventes V WHERE qteTot> 10;

 La table Ventes peut ne pas être encore créée au moment de la formulation de cette vue. 

Fonction dʹagrégation dans une vue relationnelle Une vue définie avec une  fonction dʹagrégation  (ex. SUM()) doit aussi définir un alias essentiel pour référer à la valeur agrégée. Une telle vue ne permet pas la mise à jour.    

CREATE VIEW ventePop as  SELECT article, SUM(qte) AS total  FROM Ventes  WHERE qte > 4;   

 

Variable de table Il en est autrement avec  la variable du  type  table que certains  langages  implémentent. Lʹexemple ci‐dessous, illustre le stockage du résultat d’une recherche dans une variable de table et sa réutilisation dans une autre expression du langage :  

Page 156: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

156

(vue relationnelle) G_transactions = (SELECT Ventes.article FROM  Ventes);  Select G.article FROM G_transactions G ;

 L’inconvénient majeur de cette approche est le caractère statique de la variable de table. Une  application  qui  utiliserait  cette  variable  n’a  pas  l’assurance  d’avoir  accès  aux dernières mises à jour faites sur la BD. En effet, seules les relations de base sont mises à jour  et  les  modifications  ne  sont  pas  propagées  aux  variables  de  table.  La  vue  est similaire à une variable de table, à la différence que la table correspondant à la vue a une vie  éphémère  et  est  recalculée à  chaque  fois que  celle‐ci  est  référencée par une  clause SQL. L’instantané sera aussi similaire à une variable de table. L’instantané matérialisé et synchronisé  pour  la mise  à  jour  correspond  à  à  une  variable  de  table mais  dont  le contenu est fidèle à la base de données. 

8.14 Droits dʹaccès et contrainte pour le calcul dʹune vue Lʹexpression de  la vue par une  sous‐requête permet de  refléter  lʹétat  réel de  la BD au moment  de  son  exécution.  La  vue  étant  un  objet  du  schéma  de  la  BD,  elle  a  des privilèges dʹaccès, dʹinsertion, de suppression et de modification comme pour toute table de la base.  

CREATE VIEW VentesRecentes as SELECT * FROM Ventes WHERE date > To_Date('01-jan-1995',‘DD-MON-YYYY’);

 Ainsi, un usager Paul qui nʹest pas  le propriétaire de  la vue peut  cependant  lʹutiliser pour  avoir  accès  aux  ventes  enregistrées  après  le  1  janvier  1995.  Il  doit  auparavant obtenir du propriétaire de la table le droit de sélection que ce dernier formulera ainsi : 

 GRANT SELECT ON VentesRecentes TO Paul;     

Lʹusager Paul peut dorénavant utiliser la vue Ventes_Recentes pour effectuer seulement des sélections.   Peut‐il faire une insertion concernant une vente de 1996? Il ne peut  le faire que sʹil a le privilège dʹajout (insert) sur  la vue Ventes_Recentes. Ce privilège  lui est accordé par  la clause Grant.    

GRANT INSERT ON VentesRecentes TO Paul;                                                  Peut‐il alors aussi ajouter un tuple pour enregistrer une transaction de 1994 même si la vue ne référence que les tuples de 1995? Oui, car le prédicat dʹune vue qualifie les tuples qui peuvent être sélectionnés et ne contraint pas les tuples qui peuvent être ajoutés, sauf si lʹoption CHECK OPTION est explicitement insérée dans lʹexpression de la vue. Dans 

Page 157: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

157

ce cas, lʹopération résultant sur les tables de base n’est effectuée que si le prédicat de la vue nʹest pas infirmé par celle‐ci.   Pour accepter que  les  transactions ajoutées par Paul  se  limitent à  l’année 1995,  il  faut modifier lʹexpression de la vue : 

CREATE view VentesRecentes_ajout as SELECT * FROM Ventes WHERE date >'01-jan-95' WITH CHECK OPTION;

 Cette  dernière  option  va  lancer  une  vérification  du  prédicat  de  la  vue  et  cela,    pour chaque tuple ajouté par Paul. En cas dʹéchec, le tuple sera refusé par le système.  Comme la vue est exprimée par une requête ou une expression SQL,  il est possible dʹexploiter toute fonction SQL disponible afin de formuler un prédicat complexe. Par exemple, pour bloquer  toute  transaction  inférieure à 5.00 $ effectuée avant  la date du  jour,  il suffit de formuler la vue ainsi :  

CREATE view VentesCourantes as SELECT * FROM Ventes WHERE date = SYSDATE and prix > 5.00 WITH CHECK OPTION;

                             Ensuite, il faut accorder les droits de sélection et dʹinsertion à Paul :  

  GRANT SELECT, INSERT on Ventes_courantes to Paul.   Si le DBA désire limiter lʹusage de cette vue au lundi, il formulera alors la vue ainsi :  

CREATE view VentesCourantes as SELECT * FROM Ventes WHERE date = LOWER(TO_CHAR(SYSDATE,'DAY')) = 'monday' and prix > 5.00 WITH CHECK OPTION;

 Lʹajout dʹun tuple par Paul ne sera donc autorisé que si lʹopération est faite un lundi. Il faut  souligner que ces vérifications  sont  faites en  ligne et que  la contrainte de vue est généralement gardée dans la ZMP. 

Suppression de la vue en SQL‐92 Pour supprimer une vue, il faut en être le propriétaire: 

DROP VIEW <nom_vue> {RESTRICT | CASCADE};  Lʹoption RESTRICT échoue  si  la vue est aussi utilisée par une autre vue ou une autre contrainte.  Il y  a  alors une dépendance de vue qui bloque  la  suppression  tant quʹelle subsiste dans  la base de données. Quant à  lʹoption CASCADE, elle supprime  la vue et toute autre vue ou contrainte la référençant.  Lʹeffet de cascade se propage dans la chaîne de dépendances de la vue.  

Page 158: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

158

Suppression des privilèges sur la vue. Il  est  aussi  possible  de  supprimer  les  privilèges  liés  à  une  vue  sans  pour  autant supprimer la vue elle‐même.         

Figure 8.16               Patricia ne peut pas transmettre son privilège de sélection à dʹautres usagers puisquʹelle nʹa pas lʹautorisation de le faire (sans GRANT OPTION). Si lʹon supprime le privilège de Patricia, aucun autre usager nʹest touché par cette action : 

REVOKE SELECT FROM Patricia;  Par contre, Sylvain a le privilège de propager ses propres privilèges à dʹautres usagers. La suppression de son privilège dʹinsertion est automatiquement propagé aux usagers dont le même privilège dépend de celui de Sylvain :   

REVOKE SELECT FROM Sylvain;  La suppression du privilège prend effet seulement lors de la prochaine ouverture de la base  de  données  par  lʹusager  visé.  Sʹil  est  en  ligne  au moment  de  la  suppression  du privilège, il ne perd pas illico lʹaccès aux objets!  

8.15 Modification de la BD à travers une vue SQL  Supposons  les  relations  de  base  définies  par  les  schémas  de  relation  Employe  et Departement.  La  clé  étrangère,  noDep,  permet  de  relier  les  deux  tables  et  donc d’effectuer des  jointures. Par exemple, il est possible de connaître tous les employés du département d2.              

Employe :  nas*  nom  noDep  salaire    Dep :  noDep*  site   27  audrey  d1  15k$      d1  Québec   20  benoit  d2  20k$      d2  Montréal   21  christine  d2  19k$      d3  Trois‐Riv   22  audrey  d2  18k$      d4  Québec   23  audrey  d4  15k$         

 Vue3 :          Vue2 :        Vue1 : nas*  nom  site    nom*  site*    nas*  salaire 27  audrey  Québec    audrey  québec    27  15K 20  benoît  Montréal    benoît  Montréal    20  20K 21  christine  Montréal    christine   Montréal    21  19K 

Marie‐Claude (Select + Update)

Patricia (Select) 

Sylvain  (Select  +  Insert  +  Update    Grant 

Jacques  (Select  +  Insert) 

Vue Ventes‐99 

Page 159: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

159

22  audrey  Montréal    audrey  Montréal    22  18K 23  audrey  Québec    audrey*  Québec    23  15K 

Figure 8.17  Ce  tuple  est  invisible  et  redondant dans Vue2 malgré  son association à une personne différente. La Vue3 est simple et correspond à une projection de  la  table Employe. Les vues Vue2 et Vue3 sont plus complexes et correspondent à des jointures de tables.  Les  deux  relations  suivantes  ont  les  attributs  suivants  comme  clé  primaire :  nas  et noDep. Les vues sont définies par des expressions algébriques qui correspondent à des tables virtuelles calculées à chaque fois quʹune application fait référence à la vue. La vue reflète donc lʹétat de la BD au moment de son calcul ou de sa matérialisation.                                   

Expression algébrique des vues La  vue  relationnelle  est  exprimée  par  une  expression  algébrique  qui  est  évaluée seulement au moment de lʹexécution. Avec un langage de données de plus haut niveau comme le SQL, la vue sera formulée par une clause SQL stockée dans le dictionnaire des métadonnées qui sera aussi évaluée seulement  lors de  lʹexécution. Ainsi,  lʹextension de la vue reflète toujours lʹétat actuel de lʹinstance de la BD, qui a peut‐être été mise à jour depuis la dernière matérialisation de la vue.    Vue1 : Πnas,salaire (employe) <‐‐ projection, relation de base Vue2 : Πnas,nom,site((Πnas,nom, noDep(employe)|x|departement) Vue3 : Πnom, site ((Πnom,noDep(employe))|x|departement)  Examinons en premier la vue la plus simple, soit la vue Vue1. Elle correspond à un sous‐ensemble d’une seule relation de base. Les vues Vue2 et Vue3 ont chacune un schéma composé d’attributs provenant de plusieurs relations de base. Supposons que les droits d’accès pour  la  lecture et pour  la mise à  jour  soient accordés aux propriétaires de  ces vues pour effectuer  les opérations ci‐dessous. Rappelons aussi que  lʹinsertion se fait au moyen dʹun seul ordre DML dʹinsertion.  

Usager 1 Par lʹentremise de la vue Vue1, modifier le salaire de l’employé dont le nas est 21 pour que  son  salaire  soit maintenant 20 K$. La mise à  jour peut être effectuée parce que  le SGBD peut  identifier  (procédure unique pour  le  trouver) dans une  relation de base et sans  ambiguïté  le  tuple  à mettre  à  jour. On dit  alors que  cette vue  est modifiable  ou ʹupdatableʹ. Dans l’application  lʹordre DML est le suivant :  

Update vue1 set salaire = 20 K$ WHERE nas = 21;  (avec la vue)  Le SGBD peut transposer cette opération de mise à jour par lʹentremise de la vue en une procédure  interne  sur  les  relations  de  base,  laquelle  peut  effectuer  sans  ambiguïté  la 

Page 160: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

160

modification demandée. Cette procédure  interne doit être composée dʹordres DML de même nature que celui de la procédure externe (i.e. le DML  utilisé sur la vue). Ordre interne exécuté par le SGBD : 

Update Employe set salaire = 20 K$ WHERE nas = 21;     (avec une table de base)   Un  seul  tuple  sera mis  à  jour  conformément  à  l’intention  de  l’application,  soit  celui identifié par le nas 21 dans la relation de base Employe. La mise à jour à travers cette vue sera donc possible.                                    

Usager 3 Par lʹentremise de la vue Vue3, faire lʹajout du tuple : (28, ‘denis’, ‘Hull’). 

Insert INTO Vue3 VALUES  (28, ʹdenisʹ, ʹHullʹ);   Pour l’application, un seul tuple doit être mis à jour et la modification de l’extension doit pouvoir se refléter dans les relations de base.   

Employe  nas*  nom  noDep  salaire    Dep :  noDep*  site   27  Audrey  d1  15k$      d1  Québec   20  Benoit  d2  20k$      d2  Montréal   21  Christine  d2  19k$      d3  Trois‐Riv   22  Audrey  d2  18k$      d4  Québec   23  Audrey  d4  15k$        ‐‐>  ‐‐  Hull          ‐‐‐>  28  Denis  ‐‐  ‐‐         

Figure 8.19 En effet, un affichage de lʹextension de la vue révèle quʹaprès cette insertion il y a un seul tuple représentant Denis dont le nas est 28. Son lieu de travail est absent de la base, car le tuple véhiculant cette information nʹa pas pu être inséré dans la relation Departement puisque la clé est absente. Lʹintention de lʹutilisateur est claire, mais il y a une ambiguïté au niveau du SGBD. Quel est lʹeffet au niveau de la BD?   La procédure interne exécutée par le noyau du SGBD serait la suivante :    

Insert INTO Employe VALUES  (28, ʹDenisʹ, null, null);  Insert INTO Departement VALUES  (null, ʹHullʹ); 

 Cet ajout viole cependant une contrainte  fondamentale du modèle relationnel, à savoir que la clé de la table Departement ne peut être nulle. Pour éviter ce problème, le système devra  interdire  cette mise  à  jour. La Vue1  correspond  à une  jointure des  relations de base, mais  elle  n’inclut  pas  les  clés  primaires  des  deux  relations  intervenant  dans  la jointure. Cʹest une condition suffisante, mais non nécessaire pour exclure ce type de mise à jour par lʹentremise dʹune vue.  Usager 2 

Page 161: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

161

Avec la Vue2, effectuer une modification pour refléter le fait que lʹemployée audrey de Québec  travaille  maintenant  à  Montréal.  Selon  la  vue  Vue2,  il  y  nʹa  qu’une  seule personne nommée Audrey qui devrait faire l’objet de la mise à jour, soit un seul  tuple :  UPDATE Vue2  set site = ʹMontréalʹ  WHERE  nom = ʹAudreyʹ and site = ʹQuébecʹ;           Lʹintention de  lʹapplication  est  claire, mais  le SGBD ne peut  la  comprendre,  car  il y a plusieurs  tuples  candidats  à  cette  modification.  Sans  autre  connaissance  externe,  le SGBD traduit cette procédure en une autre qui utilise seulement les relations de base et les constantes fournies par lʹapplication :    

UPDATE Employe set noDep =  (SELECT noDep FROM Departement WHERE site = ʹMontréalʹ)      WHERE nom = ʹAudreyʹ and noDep in      (SELECT noDep FROM Departement  WHERE site = ʹQuébecʹ); 

 La procédure  interne est composée dʹun  seul ordre DML du même  type constitué des constantes de  lʹexpression  fournies par  lʹapplication. L’effet net modifiera deux  tuples dans  la  table de base! Ainsi,  lʹapplication  anticipe une  seule mise  à  jour  et deux  sont réalisées dans les tables de base par le SGBD! Qu’en est‐il maintenant si le tuple de mise à  jour  spécifie  que  Audrey  du  département  d1  (Québec)  travaillera  maintenant  à Montréal? Dans ce cas particulier, la relation de base pourra être mise à jour seulement si Vue2  est  enrichie  du  numéro  de  département  de  la  relation  Departement.  Il  nʹest cependant pas possible de généraliser ce cas.   

Traitement dʹune requête SQL référant à une vue relationnelle     Une requête SQL avec une référence à une vue peut être traitée soit par substitution, soit par  matérialisation.  La  vue  est  définie  par  son  expression  SQL  stockée  dans  le dictionnaire de données sous forme dʹune chaîne de caractères. 

8.16 Matérialisation dʹune vue Dans certains cas, l’exécution d’une requête avec une vue est impossible par substitution et cela, pour des raisons syntaxiques, mais elle le devient avec la matérialisation. Voici la BD FPF composée des trois relations suivantes :  

 Fourn(noF*, nomF, cote, ville) Piece(noP*, nomP, couleur, poids, ville) FournPiece(noF*, noP*, qte    

où   nof   le numéro du fournisseur   noP  le numéro de la pièce  

Page 162: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

162

La vue SQL :  CREATE view P_QTE as  SELECT  SUM(FP.qte) as qteTot <‐‐ alias FROM FournPiece as FP GROUP BY FP.noP; 

 Le schéma de la vue P_QTE est le suivant : P_QTE (qteTot).   Soit la requête sur la vue P_QTE : 

SELECT AVG(qteTot) as mqp FROM P_QTE; 

 La réponse attendue a un schéma composé du seul attribut‐alias mqp qui représente une moyenne  numérique.  Si  le  SGBD  procède  uniquement  par  substitution,  la  requête obtenue  sera  refusée  par  plusieurs  SGBD,  en  raison  de  l’imbrication  des  fonctions d’agrégation :    

SELECT #p, AVG(SUM(FP.qte)) as mqp <‐  imbrication au niv.1 FROM FP GROUP BY FP.noP ; 

 Toutefois, la même requête sera acceptée si le SGBD utilise une matérialisation de la vue. Le calcul de la vue donne une relation intermédiaire temp1 :  

temp1 :   noP  SUM(FP.qte)   1  44   3  33   2  22 

Figure 8.20 La  relation  temp1  est  l’objet  d’une  projection  pour  obtenir  la  valeur  de  SUM(FP.qte) lequel peut être renommé Somme‐quantité. C’est sur  cette table temporaire que la requête SQL  est  exécutée pour donner  la moyenne  escomptée. Certains  logiciels  commencent par utiliser  la  substitution et, en cas d’échec,  font appel à  la matérialisation  (voir DB2 dʹIBM). Cette matérialisation  est aussi  employée pour  le  traitement des  sous‐requêtes, c’est‐à‐dire les clauses SQL de niveau supérieur à 1.  

Matérialisation de la vue en Oracle Les versions récentes dy système Oracle autorisent la matérialisation de la vue au moyen d’une  commande DDL particulière. Ce mécanisme  est  similaire à  l’instantané avec ou sans    mise  à  jour.  Pour  créer  une  vue,  il  faut  avoir  les  privilèges  CREATE MAERIALIZED VIEW, CREATE DIMENSION et QUERY REWRITE.                             

Page 163: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

163

Create MATERIALIZED view SalaresMoy  never refresh – ou refresh (mises à jour exclues) enable query rewrite  ‐‐ autorise l’optimisation as Select nom 

From Empl Where salaire > 30000 and salaire < 60000; 

 A  la  première  référence  à  cette  vue,  elle  sera  matérialisée  de  sorte  que  l’extension correspondante soit disponible lors des traitements subséquents. Cette vue existe au delà du COMMIT de  la  transaction qui  a  lancé  sa  création. Une vue matérialisée  est  aussi appelée Snapshot.             

Droit dʹaccès aux tuples de la vue relationnelle Pour traiter les données à travers une vue, il faut que lʹapplication ait des droits dʹaccès aux tables et que les manipulations ne violent pas les contraintes dʹintégrité définies sur les tables de base : a)  En  lecture,  l’opération  est  réalisée  si  l’usager  a  les  droits  de  lecture  sur  toutes  les relations de base fournissant des attributs à la vue.                      b)  En mise  à  jour,  l’usager  doit  avoir  les  droits  de  lecture  et  de  suppression  sur  les relations de base fournissant les attributs à la vue; la mise à jour étant traitée comme une suite atomique d’une suppression et d’un ajout. c) En mise à  jour,  les contraintes d’intégrité actives quant à  la BD ne peuvent pas être violées dans les relations de base après l’opération de mise à jour.  d)  Si  la  vue  est définie  sur une  seule  relation de  base  et qu’elle  inclut  la  clé de  cette première sans autre fonction, alors il est possible d’ajouter, de supprimer et de modifier un tuple de la vue sans créer d’ambiguïté.  Cette  condition  est  difficile  à  faire  vérifier  par  le  SGBD  autrement  quʹen  lui  faisant valider systématiquement les vues dans le dictionnaire. Si un utilisateur a le privilège de créer des vues, il peut le faire librement avec les relations auxquelles il a accès. Le DBA devrait‐il autoriser les vues au préalable et interdire les modifications subséquentes non contrôlées ?  Si une  telle  approche  était  adoptée,  serait‐elle perçue  comme un  obstacle dans les opérations que peut effectuer un utilisateur sur les données.                     

Mise à jour à travers une vue incluant une fonction Si  la  vue  comprend  une  fonction  de  groupement,  d’agrégation,  arithmétique  ou  de chaîne, la mise à jour est interdite. En effet, toute modification de l’information obtenue par  la  fonction ne peut pas  être  transposée de  façon  appropriée dans  les  relations de base. Il est cependant possible d’interroger à volonté cette vue (read only  view).  La  lecture par  lʹentremise dʹune vue ne pose pas de problème, si ce n’est généralement celui de  l’interprétation des tuples affichés, en particulier en ce qui concerne le résultat 

Page 164: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

164

obtenu  avec  les  fonctions  arithmétiques,  d’agrégation  et  de  groupement.  Pour contourner la difficulté, les langages de données permettent à lʹutilisateur de remplacer les  en‐têtes  de  colonne  par  des  expressions  plus  significatives.  Un  autre  cas  très particulier à éviter est celui de la lecture d’une relation obtenue par la  jointure de vues interdites par une dépendance de  jointure. Cette anomalie est possible lorsquʹil y a une dépendance de jointures dans le schéma de la BD et que le schéma nʹest pas en 5FN.  Sur  le plan  théorique, certaines vues peuvent être utilisées pour  la mise à  jour,  tandis que d’autres sont à proscrire15. Il y a donc certaines vues qui sont indésirables en ce qui concerne  la  mise  à  jour  et  que  l’administrateur  de  la  BD  devrait  repérer  par  une validation des vues proposées et au besoin enrichir de manière à ce que  les opérations demandées par  les usagers puissent  être  exécutées  correctement. Cʹest  cependant une solution  au  cas  par  cas  qui  nʹest  pas  acceptable  dans  un  contexte  dʹexploitation  le moindrement dynamique. 

Création des vues avec SQL (ordre DDL de SQL) La  création  d’une  vue  consiste  à  définir  l’expression  SQL  correspondante  qui  dans certains cas tient lieu de pseudo‐variable de table.   Exemples : Vue 1  : Les nas, nom et site des employés qui travaillent dans un département. �nas, nom, site ((�nas, nom, noDep (Employe)) |x| Departement):       

CREATE [REPLACE] VIEW vue1 AS SELECT nas, nom, site FROM Employe [as] E, Département [as] D WHERE E.noDep = D.noDep;

 Vue 2 : Le nom et le site des employés qui travaillent dans un département. 

�nom, site ((∏nom, noDep(Employe)) |x| Departement)  CREATE [REPLACE] view vue2 as SELECT nom, site FROM Employe[as] E, Departement [as] D WHERE E.noDep = D.noDep;

 Vue 3 :  Le nas et le salaire des employés. 

�nas, salaire (Employe) :  <‐‐ relation de base CREATE [REPLACE] view vue3 as SELECT nas,salaire FROM Employe;

 Ces expressions de vue relationnelle sont stockées dans le dictionnaire de données de la base.  Voici  une  base   composée  de  deux  taables  qui  décrit  le  lieu  de  travail  des personnes qui sont en ménage. 

Page 165: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

165

Menage (conjoint, conjointe) LieuTrav(nas, nom, ville, salaire)  Chaque attribut de Ménage partage le même domaine sémantique, soit le nas de chaque personne. Le domaine des autres attributs est  suggéré par leur libellé respectif.  Les domaines sont donc les suivants :      conjoint  d‐nas     conjointe  d‐nas     nas  d‐nas     salaire  d‐entier     nom  STRING (varchar(40))  domaine syntaxique  

Menage :  conjoint  conjointe   345  456   923  786   387  384   629  310   319  231   127  612 

                   

Figure 8.21  Vue 4  :  Le nom et le salaire des conjointes dont le salaire est supérieur à 25 000 $ . 

CREATE view vue4 (nom_conjointe, salaire) as SELECT nom, salaire FROM Menage [as] M, Lieu_travail [as] L WHERE M.conjointe = L.nas and L.salaire > 25 000;

 Vue 5  : Le nom des conjoints qui ont un salaire égal à celui de leur conjointe.  

Lieu_Travail :  nas  nom  ville  salaire     345  Jacques  Québec  20K$     231  Danielle  Trois‐Rivières  19K$     456  Sylvie  Québec  28K$     127  Nahn  Nice  32K$     612  Josée  Chicoutimi  26K$     387  Pierre  Québec  25K$     384  Clotilde  Ste‐Foy  22K$     923  Rachid  Québec  25K$     319  Arthur  Québec  22K$     187  Gerry  Montréal  25K$     310  Patricia  Québec  25K$     452  Estelle  Montréal  23K$     629  André  Montréal  25K$     876  Denise  Québec  27K$   

Page 166: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

166

Comme  il  n’est  pas  possible  de  définir  des  relations  temporaires  en  SQL,  les  vues serviront à cette fin, car elles peuvent être  interrogées comme si elles étaient des tables de base. La vue  ci‐dessous permet de  trouver  l’information  ayant  trait  aux  conjoints : conjointe, son salaire et la ville de son domicile.     

CREATE view vue5.1 as SELECT conjoint, conjointe, salaire, nom FROM Menage [as] M, Lieu_travail [as] L WHERE M. conjointe = L.nas;

 De même pour la conjointe : 

CREATE view vue5.2 as SELECT conjoint, conjointe, salaire, nom FROM Menage [as] M, Lieu_travail [as] L WHERE M. conjoint = L.nas;

 CREATE view reponse as SELECT conjoint FROM vue5.1 X, vue5.2 Y WHERE X.conjointe = Y.conjointe and X.conjoint = Y.conjoint and X.salaire = Y.salaire;

 SELECT conjoint [as] nas-conjoint /*renommage attribut*/ FROM reponse;

 ou plus directement : 

SELECT conjoint[as] nas-conjoint FROM vue5.1 [as] X, vue5.2 [as] Y WHERE X.conjointe = Y.conjointe and X.conjoint = Y.conjoint and X.salaire = Y.salaire;

 Vue 6  : Les conjointes et le lieu de leur travail pour celles qui travaillent dans la même ville que leur conjoint.  

CREATE OR REPLACE view vue6.1 as SELECT conjoint, conjointe, nom, ville FROM Menage [as] M, LieuTravail [as] L WHERE M.conjointe = L.nas;    CREATE view vue6.2 as SELECT conjoint, conjointe, nom, ville FROM Menage [as] M, LieuTravail [as] L WHERE M.conjoint = L.nas; CREATE view reponse as

Page 167: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

167

SELECT conjointe FROM vue6.1 [as] X, vue6.2 [as] Y WHERE X.conjoint = Y.conjoint and X.conjointe = Y.conjointe and X.ville = Y.ville; SELECT conjointe [as] nas-conjointe FROM reponse;

 ou plus directement : 

SELECT conjointe [as] nas_conjointe FROM vue6.1 [as] X, vue6.2 [as] Y WHERE X.conjoint = Y.conjoint and X.conjointe = Y.conjointe and X.ville = Y.ville;  

Vue 7 :  La ville et la moyenne des salaires, le plus petit et la somme des salaires.    

CREATE view vue7 (ville, moy_sal, min_sal, som_sal) AS SELECT ville, Avg(salaire), Min(salaire), Sum(salaire) FROM LieuTrav GROUP BY ville; SELECT ville, moy_sal /*interrogation possible*/ FROM vue7;

Restrictions associées à la vue relationnelle La  vue  relationnelle  est  définie  par  une  expression  algébrique.  Elle  permet  un renommage des attributs (alias),  mais interdit les opérations suivantes :  a) Le changement de type pour les attributs spécifiés dans les relations de base.  b) La modification des droits d’accès aux tables de base.   Avec  SQL, une mise  à  jour  est possible par  lʹentremise dʹune  vue  si,  et  seulement  si, toutes les propositions ci‐dessous sont validées :    a)  L’expression  de  la  vue  est  une  clause  SELECT  qui  ne  contient  pas  les mots  clés suivants : JOIN, UNION, INTERSECT, EXCEPT (sauf); b) La clause SELECT ne contient pas le mot clé distinct. Chaque attribut du SELECT fait une référence simple à une colonne de la table (sans fonction); c) Il y a une seule table dans la clause FROM, donc pas de  jointure; La table référencée dans la clause FROM est une table de base ou une vue de mise à jour acceptable; d) L’expression de la vue n’inclut pas un WHERE avec une sous‐requête qui se rapporte aussi à la même table (autojointure interdite); e) L’expression de la vue n’a pas de GROUP BY; f) L’expression de la vue n’a pas de HAVING. 

Page 168: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

168

Il  est donc possible de  faire une mise à  jour  très  limitée dans une BD par  lʹentremise dʹune vue relationnelle (incluant la suppression et l’ajout).                                       8.17 Instantané 

Le  concept  de  l’instantané  ou  snapshot  est  intéressant  parce  qu’il  permet  de  garder facilement une image de la BD. Cet objet est une table qui reflète lʹétat dʹune autre table de base ou dʹune vue  relationnelle à un moment donné et, au besoin,  les mises à  jour subséquentes effectuées sur  la table de base. Ce mécanisme est utile parce quʹil permet de  conserver  localement  une  copie  dʹune  table  distante  qui  est  mise  à  jour périodiquement  et  automatiquement.  C’est  une  notion  apparentée  à  celle  de  la  vue matérialisée.  CREATE SNAPSHOT <schéma> <nom‐snapshot>  

REFRESH  [FAST  |COMPLETE  | FORCE]  START WITH  <date>   NEXT  <date> FOR UPDATE AS  <sous‐requête> ; 

 Le mode de rafraîchissement dʹun instantané détermine comment sera faite lʹacquisition des mises à  jour effectuées sur  la  table de base  (locale ou distante), sous‐tendue par  la définition de l’instantané.  Les modes possibles sont :  FAST :  la mise à jour est incrémentielle et effectuée à partir dʹun journal de table spécial créé et associé à  la  table de base à  laquelle est relié  lʹinstantané. Le  journal de  table est créé par la commande suivante : Exemple : CREATE  SNAPSHOT  LOG  <schéma.><table> ; COMPLETE  :  la  requête  du  snapshot  est  réexécutée  à  la  date  prévue  par  le rafraîchissement. FORCE : un FAST si cela est possible, sinon un COMPLETE ( cas : absence du journal de table).  Le moment de  la mise à  jour de  lʹinstantané est contrôlé par  la clause START WITH. Il est aussi possible de  lancer une procédure utilitaire pour démarrer  immédiatement  le rafraîchissement de la table.                                     

Mise à jour de l'instantané La création d’un  instantané sous‐tend  la création d’une table correspondant au schéma de la requête  et dont l’extension est formée avec les données fournies par lees tables de base.   

Page 169: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

169

CREATE SNAPSHOT Ouvrier_Exp PCTFREE 10 PCTUSED 100 TABLESPACE TS_utilisateur REFRESH FAST ON COMMIT AS SELECT * FROM T1 WHERE age > 50; 

                                 La mise à  jour d’une table de base référée par un  instantané FAST est faite au moment spécifié dans  la clause REFRESH soit à chaque commit. Cette mise à  jour est réalisée à partir d’un journal spécial associé à la table de l’instantané.          

Mise à jour de l’instantané Figure 8.21a 

Avec  les  versions  plus  récentes,  par  exemple  Iracle  9i,  la  notion  d’instantané  est remplacée par celle équivalente de vue matérialisée ou vue concrète. Exemple : La vue matérialisée sera mise à jour dans 15 jours à compter de la date de sa création.  CREATE MATERIALIZED VIEW Ouvrier_Exp  

REFRESH FAST NEXT SYSDATE + 15 AS SELECT * FROM T1 WHERE age > 50; 

 8.18 Langage procédural PL/SQL 

L’ajout  des  déclencheurs  et  des  procédures  stockés  dans  une  base  de  données relationnelle a fait apparaître la nécessité d’avoir un SQL enrichi doté des structures de contrôle communes aux langages procéduraux. La proposition de la société Oracle pour la spécification des triggers consiste à donner un caractère procédural à SQL*Plus dans le  cadre  du  langage  PL/SQL16.  Ce  langage  implémente  la  ʺprocéduralitéʺ  permettant ainsi une manipulation  très souple des  tuples des  tables de base. Ce  langage peut être utilisé à diverses fins : écriture des déclencheurs de Developer, écriture des procédures, des fonctions et des packages internes qui sont exécutés automatiquement ou sur appel par le noyau du SGBD.             

Principales caractéristiques du PL/SQL Le PL/SQL est un langage procédural qui étend la puissance de traitement du SQL. Il est portable  à  l’intérieur  de  la  gamme  de  produits  dʹOracle.  Ainsi,  un  concepteur  peut mettre  au  point  une  requête  SQL  complexe  avec  l’interpréteur  interactif  et  ensuite lʹinsérer  dans  un  déclencheur  ou  dans  une  application  en  L3G  sans  y  apporter  de changement majeur.    

26, fabella, 68 18, paul, 50 35 claude, 56 

26, fabella, 68 18, paul, 50 35 claude, 56 

35 claude, 56 

Table Ouvrier_Exp (instantané)  Table Ouvrier de base Journal de Ouvrier_Exp

321 Ajout d’un tuple

Mise à jour 

Page 170: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

170

Le  langage PL/SQL a une structure de bloc avec  les structures de contrôle habituelles  : les affectations,  les alternatives,  les  itérations et  les appels aux procédures,  fonctions et packages.  Toutes  les  clauses  SQL*Plus  peuvent  être  insérées  dans  un  bloc  PL/SQL. Chaque bloc est exécuté par le noyau comme une transaction indivisible. Les procédures SQL sont stockées dans le serveur et sont appelées par un déclencheur ou par un autre bloc. Elles peuvent aussi être exécutées en ligne avec le système SQL*Plus. 

Bloc PL/SQL Un bloc est nommé si  la clause BEGIN est étiquetée, sinon  il est dit bloc anonyme. Les clauses du langage qui sont admissibles dans un bloc sont les suivantes :  ‐ Les variables, les constantes et les curseurs sont déclarés dans une section spéciale du bloc identifiée par le mot clé DECLARE. ‐ L’affectation se fait par valeur et non par référence (par pointeur). ‐ La structure de recherche alternative est implémentée par le IF  ...    ... END IF. Chaque élément de lʹalternative peut être formé dʹun bloc PL/SQL. ‐ L’itération est implémentée par quelques structures : FOR, LOOP et WHILE. ‐ Les fonctions arithmétiques habituelles sont permises. ‐  Le  branchement  inconditionnel  autorisé  par  lʹusage  dʹune  étiquette  placée  entre guillemets français : <<label >>.    Le  traitement des exceptions est géré au moyen des exceptions déclarées explicitement dans  le  bloc  PL/SQL  ou  définies  implicitement  dans  le  langage.  Le  traitement  de lʹexception terminé, lʹexécution se poursuit avec le premier énoncé après la sortie du bloc courant. 

Structure générale dʹun programme PL/SQL Voici  la  structure générale dʹun programme PL/SQL17;  elle  comprend un ou plusieurs blocs, dont chacun est constitué de la partie DECLARE, BEGIN et EXCEPTION. Seule la partie BEGIN est obligatoire.  [DECLARE] 

Déclarations des variables, constantes, exceptions et curseurs hôtes 

BEGIN Clauses SQL et PL/SQL (lʹemboîtement des blocs est possible) 

[EXCEPTION] Traitement des exceptions  

END; Figure 8.22 

Section DECLARE du bloc PL/SQL Cette  section    contient  la déclaration des variables du  langage hôte  et des  constantes. Voici quelques types disponibles : NUMBER, CHAR, DATE, BOOLEAN et RECORD. Le type peut être spécifié par un attribut du schéma de la BD : attribut%TYPE (par exemple 

Page 171: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

171

:  Empl.nom_famille%TYPE).  L’initialisation  de  la  variable  peut  être  faite  dans  la déclaration. Une seule variable est déclarée et initialisée par énoncé. 

DECLARE salaire NUMBER (5,2); taux Empl.tarif%TYPE;      /*var. taux a le type de Empl.tarif*/ mat varchar2(10); bonus NUMBER(2) := 10; nom  VARCHAR(35); CURSOR Recherche IS     SELECT E.nom,E.tauxH     FROM Empl as E      WHERE noEmpl = ʹP762ʹ; 

 erreur5 EXCEPTION; /*déclar.label de lʹexception */ BEGIN OPEN Recherche;  ‐‐ ouverture du curseur et calcul de la clause WHILE Recherche%FOUND FETCH Recherche INTO  nom, taux; IF taux > 20  THEN RAISE erreur5; ELSE  UPDATE Empl set tauxH = tauxH * 1.05 WHERE      CURRENT of Recherche; END LOOP; CLOSE Recherche; EXEPTION  WHEN erreur5 THEN ... END; 

Figure 8.23 

Section  de traitement du bloc PL/SQL Cette  partie  de  la  procédure  contient  les  énoncés  de  traitement  selon  la  syntaxe  de PL/SQL. Les clauses PL/SQL comprennent toute clause SQL et les structures de contrôle standards  pour  l’alternative,  la  répétition  et  l’affectation.  Le  traitement manipule  des données de  la BD  et en permet  le  stockage dans une  table de base ou dans une  table temporaire existante ou créée par  la procédure. Le  langage n’a pas d’ordre d’affichage direct.  Les  données  obtenues  par  une  clause  SELECT  doivent  être  placées  dans  des variables PL/SQL. 

Affichage au terminal pour des fins de mise au point  Il  est  possible  d’utiliser  une  procédure  d’un  package  pour  un  affichage  (lecture) élémentaire au terminal/station client. Cette opération est  implémentée par  le SGBD en créant un pipe entre la procédure et le SGBD. Les données placées dans le pipe peuvent être  lues  et  affichées  au  terminal  standard  de  sortie  par  un  autre  appel  au  package DBMS_OUTPUT. 

Page 172: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

172

Pour l’affichage correct il faut activer le paramètre SERVEROUTPUT à ON.  SQL> SET SERVEROUTPUT ON  ‐‐ dans le contexte du module SQL*Plus  Les procédures sont les suivantes : 

DBMS_OUTPUT.PUT_LINE ( exp |constante | attribut) DBMS_OUTPUT.GET_LINE ( var_PL/SQL)  

Remarque sur la syntaxe des variables Toute variable d’un bloc PL/SQL qui n’est pas un attribut spécifié dans le dictionnaire de la BD,  et  qui  est  une  variable  PL/SQL de  réception de données dans  le  FETCH  et  le SELECT  INTO, doit  à  ce  titre,  être déclarée dans  le bloc PL/SQL  considéré  comme  le langage hôte. Cependant, il ne faut pas préfixer une telle variable par les deux points (:), car  le bloc PL/SQL est exécuté par  le serveur et  les variables PL/SLQ   sont déclarées et connues au moment de lʹexécution de la clause SQL. 

DECLARE  article  CHAR (3); qte Ventes.qteTot%TYPE; bonus  NUMBER :=0 ; ‐‐ initialisation  BEGIN SELECT  Ventes.article, qteTot INTO article, qte  ‐‐ curseur implicite FROM  Ventes Where nom = ʹJacquesʹ;  ‐‐ 1 seul tuple attendu bonus := 10; INSERT INTO ACHAT_JACQUES VALUES (article, qte, bonus); EXCEPTION WHEN NO_DATA_FOUND THEN    RAISE_APPLICATION_ERROR(‐20400, ʹpas de tuple trouvéʹ); END; 

 La procédure RAISE_APPLICATION_ERROR()  est  fournie par une  librairie  (Package) STANDARD du SGBD et sʹexécute sur  le serveur. Si  la même procédure est    lancée et que  lʹerreur  ‐20200  doit  être  traitée  non  pas  par  le  handler  de Oracle, mais  pour  une exception de la procédure, il faut faire appel à la directive de compilation PRAGMA : 

 EXEC SQL EXECUTE   DECLARE   ...   tauxNul  EXCEPTION; PRAGMA EXECEPTION_INIT(tauxNul, +100);‐‐ +100 ‐>no_data_found BEGIN ... EXCEPTION 

Page 173: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

173

WHEN tauxNul THEN INSERT INTO ...; END; 

Ce bloc est    transmis par  la  station‐client au  serveur et  lʹerreur  ‐20200  sera appariée à lʹexception  tauxNul  et  sera  lʹobjet  du  traitement  associé  et défini  par  l’application  en remplacement de celui prévu par Oracle pour ces exceptions utilisateurs. 

Variable hôte des langages L3G Toute  variable  utilisée  dans  une  clause  SQL  qui  n’est  pas  un  attribut  ni  un  nom  de relation est une variable hôte et doit être déclarée dans la procédure ou le bloc. Dans le cas de SQLFORMS, la variable sera préfixée par : pour identifier un champ de la forme. C’est ainsi que  l’interprète SQL est  informé qu’il s’agit d’une variable du  langage hôte, en  lʹoccurrence  le C. La  structure  itérative dʹune procédure PL/SQL  se manifeste  sous plusieurs formes : LOOP, FOR, WHILE, ... et avec une syntaxe relativement simple :  Exemple 

DECLARE compteur NUMBER(3,0) := 0; BEGIN   LOOP     INSERT INTO Temp VALUES (compteur, ʹokʹ);     compteur := compteur + 1;     IF compteur  = 100 THEN       EXIT   ‐‐ ou EXIT WHEN compteur = 100;     END IF;     END LOOP; END; 

Figure 8.24 

Boucle FOR Une boucle FOR permet de répéter lʹexécution dʹun bloc dʹénoncés un nombre déterminé de fois. 

FOR  <indice>  IN [REVERSE]  <n1> .. <n2>  LOOP   <liste dʹénoncés> END LOOP; 

 Lʹindice est une variable locale qui prend chaque valeur une seule fois, soit dans lʹordre croissant, soit dans  lʹordre  inverse. La valeur  initiale est n1,  la valeur  finale  incluse est n2. Lʹindice nʹa pas besoin dʹêtre déclaré, par défaut il est du type NUMBER. Lʹindice ne peut  pas  prendre  une  nouvelle  valeur  dans  la  boucle  par  affectation, mais  peut  être utilisé dans les expressions de la boucle.        Notez quʹil nʹy a pas de valeur dʹincrément dans la clause. Elle pourrait être simulée par la fonction MOD(nb, k) exécutée dans  le corps de  lʹitération. Par exemple, pour  insérer 

Page 174: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

174

un  tuple  dans  la  table Temp  à  chaque  5  tuples  des  50  fournis  par  lʹusager,  il  suffira dʹutiliser la division par MODULO  5.  

DECLARE nom CHAR(45); . . . FOR k in 5 ..50 LOOP nom := &nom_i; ‐‐nom à fournir interactivement  age := &age_i; ‐‐idem matricule := &matricule_i;‐‐ idem IF MOD(k, 5) = 0 THEN INSERT  INTO Temp VALUES  (matricule, nom, age); ELSE NULL;  END IF; END LOOP; END; 

Figure 8.25 Ce bloc SQL anonyme comporte des paramètres préfixés par  le & qui présuppose quʹil est exécuté dans lʹenvironnement de SQL*Plus. 

Section des exceptions du bloc PL/SQL En  PL/SQL,  le  traitement  des  erreurs  (les  exceptions)  est  géré  par  des  exceptions prédéfinies  ou  par  celles  spécifiées  par  une  application  (RAISE  erreur5  ). À  la  fin  du traitement  de  l’erreur,  le  traitement  se  poursuit  avec  l’instruction  qui  suit immédiatement  le bloc courant. L’exemple ci‐dessus  illustre  le  traitement d’une erreur nommée erreur5.                 

BEGIN   IF qte > 99 THEN RAISE erreur5;   ...     END IF;   IF ...THEN END IF; EXCEPTION   WHEN erreur5 THEN  

RAISE_APPLICATION_ERROR(‐21400, ʹERREURʹ);  ... <‐‐reprise du traitement avec le bloc situé après  celui de lʹexception libellée ‘erreur5’ ... END; 

Figure 8.26 

Page 175: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

175

Exemple dʹun bloc PL/SQL Ce bloc n’utilise pas de curseur. Il doit donc traiter un seul tuple, sinon il y aura erreur du  type  en  activant  lʹexception  TOO_MANY_ROWS. Cette  exception  est  lʹune  parmi plusieurs prédéfinies. Pour  traiter plusieurs  tuples,  il  faudrait utiliser un  curseur. Par exemple,  la  recherche  du  tuple  décrivant  la  transaction  de  vente  faite  par  le  client ʹTremblayʹ permet de  trouver  son numéro de  client  et de  la placer dans une variable num_empl du même  type que celui déclaré dans  le dictionnaire de BD pour  l’attribut noEmpl. Si plusieurs tuples sont trouvés avec le critère  ʹTremblayʹ  , il y a une erreur et celle‐ci est traitée par le segment EXCEPTION qui inscrira un indicateur spécial dans la table Temp et validera l’opération.                      

Exceptions prédéfinies Parmi  ces  exceptions  prédéfinies mentionnons  :  TOO_MANY_ROWS, NO_DATA_FOUND,  INVALID_CURSOR, etc. Voici un exemple dʹune procédure PL/SQL dʹune application dans  laquelle  il y a vérification du nombre de  tuples  retournés dans  la  réponse à une clause SELECT .   DECLARE salaire_empl   number(5,2); num_empl     Empl.noEmpl%TYPE;  ‐‐ type copié du DD erreur2      EXCEPTION; BEGIN SELECT noEmpl, salaire INTO num_empl, salaire_empl  FROM EmplWHERE nom = ʹTremblayʹ; IF salaire_empl > 100 000 THEN RAISE erreur2;   INSERT INTO Temp VALUES (num_empl,ʹnumero de tremblayʹ);   DELETE FROM Empl WHERE nom = ʹtremblayʹ; . . . EXCEPTION WHEN erreur2 THEN INSERT INTO MSG_PILE VALUES(ʹaucun Tremblay riche’); WHEN TOO_MANY_ROWS OR NO_DATA_FOUND  THEN INSERT INTO MSG_PILE VALUES (ʹaucun or trop de richesʹ); WHEN OTHERS THEN NULL; END; Figure 8.27  Lʹexception TOO_MANY_ROWS est prédéfinie dans le langage PL/SQL et nʹa donc pas à être déclarée dans le bloc PL/SQL.                                  Dʹautres erreurs prédéfinies sont aussi utiles avec le PL/SQL : 

Page 176: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

176

 CURSOR_ALREADY_OPEN  INVALIDE_CURSOR  PROGRAM_ERROR TIME_OUT_ON_RESOURCE  LOGIN_DENIED  NOT_LOGGED_IN  Ces  blocs  PL/SQL  sont  utilisés  dans  le  contexte  de  SQL*Plus.  Il  peut  être  aussi implémenté comme déclencheur de BD et de FORMS. Auquel cas, les clauses COMMIT et ROLLBACK sont  inadmissibles, de même que   dans  les procédures stockées dans  le dictionnaire du SGBD.    8.19 Base de données réactive 

La  base  de données  réactive  est  une  fonctionnalité  de  système  implémentée  dans  les nouvelles versions de SGBD (DB2‐V2, Oracle, INFORMIX).                               

Figure 8.28  Le précurseur en la matière fut le SGBD SYBASE. Avec une telle base, un événement (E) particulier se produit lorsquʹune condition (C) est vérifiée.  Il en découle immédiatement une suite dʹactions  (A) qui sont  implémentées avec  le DML du système ou un  langage procédural comme le PL/SQL.    Les règles ECA sont formulées avec un langage procédural dont le pouvoir dʹexpression peut être plus ou moins complexe selon les SGBD. Par exemple, avec le système Oracle, les  événements  sont  prédéfinis  et  les  conditions  et  les  actions  sont  spécifiées  par  le langage procédural PL/SQL utilisé pour lʹécriture des triggers. Avec DB2, le langage est le C. 

Les événements déclencheurs définis au préalable Dans une base de données, une action dʹinsertion, de suppression ou de modification est un événement qui se passe au niveau de la table ou du tuple. De même, la suppression dʹune suite de tuples qui vérifient un prédicat de sélection est un événement qui a lieu au niveau du tuple ou au niveau de la table, selon le choix effectué. Lorsque lʹévénement est  pris  en  considération  au  niveau  du  tuple,  une  action  peut  être  déclenchée 

Application :  Insert into  X… Delete  X  … where Update X .. set … 

Base de données :    Table X 

 

Trigger  

Trigger  

Trigger  

Page 177: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

177

immédiatement après ou avant chaque suppression du tuple. Par contre, si lʹévénement est déclaré  au niveau de  la  table, une  action ne  sera déclenchée  quʹà  la  toute  fin des suppressions par  lʹordre DELETE. Lorsquʹun  événement  est détecté par  le SGBD, une autre  condition  peut  être  formulée  pour  contraindre  davantage  le  déclenchement  de lʹaction (WHEN). 

Définition du déclencheur (trigger) Le trigger correspond à une logique de traitement plus ou moins complexe implémentée dans Oracle  par  une  procédure  PL/SQL  qui  est  exécutée  automatiquement  lorsquʹun événement (E) comme une insertion, une mise à jour ou une suppression se produit dans une table de la BD. Une telle procédure (A) est appelée un trigger de BD parce quʹelle est liée  à  la  BD  et  lancée  lorsque  survient  un  événement,  et  cela,  indépendamment  de lʹapplication. La procédure la plus simple est composée dʹune clause SQL, une autre plus complexe comprendra un ou plusieurs blocs PL/SQL.                                      

Propriétés du trigger Un trigger est défini une seule fois et est accessible par tous les événements de la BD; il est rangé au niveau du serveur et est normalement actif pour tous les utilisateurs de la BD. Sur le plan conceptuel, il correspond à une factorisation de procédures normalement lancées par chaque application pour assurer la cohérence de la BD. En ramenant celles‐ci à la BD, on augmente la productivité des concepteurs et on a une meilleure garantie de cohérence.   Un événement qui active un trigger est associé à une application qui utilise une relation de la BD, soit directement, soit par lʹentremise dʹune vue relationnelle. La création dʹun trigger exige que lʹutilisateur ait le privilège de créer des triggers et quʹil soit propriétaire des  tables  auxquelles  il  se  réfère. Autrement,  il  doit  avoir  le  privilège ALTER ANY TABLE.   Une même table ne peut avoir quʹun seul type de trigger, cʹest‐à‐dire quʹil est impossible de définir deux triggers AFTER‐INSERT pour une même table. Toutefois, il peut y avoir plusieurs  triggers  du  type  différent  par  table,  cʹest‐à‐dire  autant  quʹil  y  a  de combinaisons de temps et d’événements.  

(BEFORE‐INSERT), (BEFORE‐UPDATE), (BEFORE‐DELETE),  (AFTER‐INSERT), (AFTER‐UPDATE) et (AFTER‐DELETE). 

Trigger et contrainte dʹintégrité Un  trigger  est différent dʹune  contrainte dʹintégrité définie dans un  schéma parce que cette dernière est d’abord une assertion toujours vraie et satisfaite depuis lʹinstant de sa définition  dans  le  schéma.  Une  contrainte  peut  être  désactivée, mais  en  redevenant active elle validera toutes les données. Une contrainte dʹintégrité est par défaut toujours active,  sauf  si  elle  est    désactivée  par  la  clause  DISABLE.    Lorsquʹune  contrainte redevient active,  il  faut que  toutes  les données dʹune  relation satisfassent  la contrainte réactivée. Elle est, par essence, rétrospective. Le trigger est créé à lʹétat actif, mais il peut 

Page 178: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

178

être désactivé ou activé par  la suite selon  les besoins. Cʹest avec  la commande ALTER TRIGGER {Enable|Disable} que le statut du trigger est modifié. Lorsquʹil est réactivé, il ne  sʹapplique  que  sur  les  données  qui  seront  ajoutées  ou  modifiées  à  partir  de  ce moment. Le trigger ne sʹapplique donc pas rétrospectivement.         

Utilité des triggers de BD Leur usage est  multiple dans la gestion et la cohérence dʹune BD. Ils servent notamment à  calculer  les  attributs  dérivés,  à  bloquer  des  transactions  invalides,  à  renforcer  la sécurité, à propager  les mises à  jour dans une BD distribuée, à conserver un audit des accès aux relations pour  les statistiques, à  implémenter  la réplication  (ou duplication  ) synchrone des tables locales et à contrôler les effets de la dénormalisation de la BD. 

Création dʹun trigger de base de données La création dʹun  trigger de BD se  fait généralement avec  lʹéditeur de SQL*PLUS.  Ici,  il sʹagit du  trigger T5 qui est  lancé  lorsquʹil y a une mise à  jour de  lʹattribut ville dans  la table Usine et que  lʹinsertion est postérieure au 25 novembre 1994. Toute   mise à  jour dʹun autre attribut dans la table Usine ne déclenchera pas le trigger.  CREATE TRIGGER D5 AFTER INSERT OF ville ON Usine     WHEN (:new.dateEmbauche > To_Date(ʹ25‐11‐1994ʹ,ʹDD‐MM‐YYYYʹ)) DECLARE . . . BEGIN   . . . (énoncés SQL ou bloc PL/SQL) EXCEPTION .   .  .  END; .  <‐ le point termine lʹédition du bloc composé avec l’outil SQL*Plus.Lancement par la commande SQPLPlus : Run . Sinon, il faut terminer le bloc par une barre oblique droite, soit / .   Pour supprimer un trigger du dictionnaire, il suffit de faire la commande suivante :  

  DROP TRIGGER T5;  Pour réaliser cette opération, il faudra que lʹutilisateur soit le DBA ou encore quʹil ait les droits de suppression des triggers. 

Structure dʹun trigger ECA Une structure de trigger est composée de trois parties : ‐ Un événement déclencheur (E)  : une action externe sur une table ou sur un tuple qui déclenche le trigger; par exemple, lʹajout ou la suppression dʹun ou de plusieurs tuples. ‐ Une  condition  de  déclenchement  (C)  :  cʹest  une  expression  booléenne  qui  doit  être évaluée à TRUE pour que le trigger se déclenche, sinon son déclenchement est inhibé; ‐Une  action du  trigger  (A)  :  cʹest une procédure PL/SQL  (cʹest‐à‐dire un bloc PL/SQL anonyme ou pas, qui  ne contient pas un commit, rollback ou savepoint).  

CREATE OR REPLACE TRIGGER nom_trigger AFTER INSERT OR UPDATE OF attribut ON table WHEN (condition de déclenchement ) 

Page 179: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

179

DECLARE . . . BEGIN  (actions avec les données) EXCEPTION . . . END; / 

Figure 8.29 Le trigger de table ne se déclenchera quʹaprès la fin dʹun ordre SQL dʹajout ou de mise à jour dʹun ou de plusieurs tuples. Le trigger de table est caractérisé par lʹabsence de FOR EACH  ROW.  Avant  de  lancer  les  actions  du  trigger,  il  y  aura  une  vérification supplémentaire dʹune condition de déclenchement dont la formulation repose sur un ou plusieurs attributs du ou des tuples mis à jour.  

Succès ou échec dʹun trigger de BD Lorsquʹun trigger est lancé sur le serveur  et qui se termine sans traitement dʹexception, il est alors exécuté avec succès et lʹévénement qui lʹa déclenché se poursuit correctement. Sʹil sʹagissait dʹune  insertion, cela veut dire quʹelle est complétée. Dans  le cas contraire, une exception est activée et éventuellement traitée (autrement que par une action NULL) et  lʹaction  à  lʹorigine  du  déclenchement  du  trigger  est  automatiquement  défaite (équivalent  au  ROLLBACK)  par  le  SGBD.  Le  ROLLBACK  est  fait  par  la  procédure RAISE_APPLICATION_ERROR()  du  package DMS_STANDARD. À  noter  quʹil  ne  peut pas y avoir un ROLLBACK explicite dans le bloc dʹun trigger. 

Type du trigger de BD (portée du trigger) Deux types de triggers peuvent être définis en ce qui concerne la BD : Trigger dʹénoncé  (DML  statement  trigger)  :  cʹest un  trigger  lancé une  seule  fois  lors de lʹexécution de  lʹénoncé DML qui  touche une ou plusieurs  tables. Ce type de  trigger est utile  lorsque  la nature de  lʹaction à exécuter ne dépend pas dʹune valeur dʹattribut du tuple ajouté ou qui est déjà présent. Par exemple, lorsquʹil sʹagit de calculer une nouvelle moyenne sur un attribut de la table T dans laquelle il y a des ajouts effectués par un seul INSERT, il suffit de créer un trigger d’énoncé AFTER INSERT pour que lʹévénement de fin d’insertion déclenche le calcul de la nouvelle moyenne.  Trigger de  tuple  (row  trigger)  :  il  sʹagit dʹun  trigger exécuté autant de  fois quʹil y a de tuples à  insérer, à modifier ou à  supprimer dans une  table par un DML  (FOR EACH ROW). Dans ce cas, la nature de lʹaction du trigger dépend de la valeur dʹun attribut de chaque tuple inséré, modifié ou supprimé. Un tel trigger peut utiliser les variables :new et :old pour référer à  la nouvelle ou à  l’ancienne valeur. Un  trigger peut être activé au temps BEFORE ou AFTER  lʹoccurrence de  lʹévénement associé  au DML. Si un  trigger AFTER échoue et que  lʹexception nʹest pas  traitée, alors  il y a un rollback automatique pour annuler toutes les actions faites sur la table ou sur le tuple par lʹordre DML. Voici deux exemples de création dʹun trigger :    

Page 180: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

180

 CREATE TRIGGER TR2  AFTER INSERT ON Usines FOR EACH ROW     BEGIN ...    . . .  bloc PL/SQL   EXCEPTION   . . .   END;  CREATE TRIGGER TR1  BEFORE INSERT OR DELETE  ON Usines      BEGIN    ... bloc PL/SQL   END; 

Figure 8.30 

Usages des triggers événementiels Dans  le cas dʹun trigger du type BEFORE,  lʹaction de ce trigger est exécutée, soit avant lʹexécution dʹune action sur une table, soit (avant lʹaction) sur chaque tuple dʹune table. Il est utile pour calculer une (ou des) valeur à partir des tuples existants. La valeur calculée sera par la suite ajoutée dans lʹinsertion à compléter dans la table. Ce type de trigger sera aussi utilisé pour vérifier si lʹaction du DML sur la table doit être amorcée ou complétée de façon à éviter de faire un rollback après quʹune action aura été exécutée.   Exemple  : Une  transaction est  inscrite dans  la  table Contrats si  le numéro du certificat dʹautorisation correspond au montant du contrat. Le déclenchement se fera pour chaque ajout ou modification dʹun tuple dans la table Contrats :         

CREATE  TRIGGER  Verif  BEFORE  INSERT  OR  UPDATE  ON  Contrats  FOR EACH ROW  DECLARE no_certif_v  real; montant_v number (5,2); annulation EXCEPTION; confirmation EXCEPTION; BEGIN SELECT montant INTO montant_v FROM Certificats             WHERE no_certif = :new.no_certif; if montant_v != :new.montant THEN RAISE annulation;   else RAISE confirmation; end if; EXCEPTION When annulation THEN    Raise_Application_Error(‐20523,ʹautorisation inadéquateʹ); 

Page 181: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

181

When confirmation THEN  NULL;‐‐ action complétée When NO_DATA_FOUND THEN NULL; ‐‐exception prédéfinie When OTHERS THEN Raise_Application_Error(‐20600,ʹerreur non traitéeʹ); END; 

Modèle dʹexécution des triggers dʹune BD Comme une BD  a plusieurs  relations  et que  chacune peut  avoir plusieurs  triggers,  le SGBD doit avoir un protocole dʹexécution des divers triggers qui peuvent être associés au même événement et quant à la même table. Voici le modèle de traitement des triggers par Oracle :  1‐ Début exécution du trigger BEFORE de table (1er tuple à traiter); 2‐ Pour chaque tuple traité par lʹordre ci‐dessus   2.1 exécution, sʹil est présent, du trigger BEFORE de tuple; 2.2  verrouillage  de  chaque  tuple  et  vérification  des  contraintes  dʹintégrité  (verrou maintenu jusquʹà la fin de la transaction); 2.3 exécution, si présent, du trigger de tuple AFTER; 3‐ Exécution de toute contrainte dʹintégrité différée; 4‐ Exécution du trigger AFTER de table;  Si une des étapes échoue, le ROLLBACK est implicite (donc automatique) lorsquʹil sʹagit dʹun  trigger  de  BD  et  une  exception  est  communiquée  à  lʹenvironnement  du  client. Lʹexécution dʹun trigger BEFORE peut entraîner celle dʹun autre trigger AFTER qui sera déclenché lors de la référence par le trigger original BEFORE. Le dernier trigger lancé est celui  de  table AFTER  et  suit  la  vérification  des  contraintes  dʹintégrité  définies  par  le CHECK.  

Activation dʹun trigger Par  défaut  et  juste  après  sa  spécification  par  le  DBA,  un  trigger  est  actif.  Il  peut cependant être désactivé par la suite avec la commande ALTER TRIGGER DISABLE :  

ALTER TRIGGER  VERIFMODEL  DISABLE ; ALTER TRIGGER VERIFMODEL ENABLE; 

Variables de corrélation NEW et OLD Avec un  trigger de  tuples,  le dernier  tuple  touché par un énoncé DML est désigné par deux variables de tuple appelées respectivement  :NEW et :OLD. Ces variables sont dites de corrélation parce quʹelles permettent de se reporter au tuple courant dans son ancien état ou dans son nouvel état. La nouvelle valeur (new) qui affecte un attribut dʹun tuple (soit new[.attribut] et lʹancienne (soit old[.attribut]) sont référencées respectivement par :new.quantite_vendue  et :old.quantite_vendue.     

Insert INTO Transporteur (mat, nom, vol) VALUES  (‘f8’, ‘ailes du nord’, 25) ;                                   

Page 182: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

182

        

Figure 8.32  Les  deux  points  (:)  préfixe  une  variable  de  corrélation,  ils  sont  une  directive  au compilateur de PL/SQL  indiquant que  la variable tuple  :new nʹest pas déclarée dans  le bloc PL/SQL et quʹil ne faut pas chercher à la traduire puisquʹelle correspond à une des deux  variables de  tuple  gérées par  le  système.   Toutefois,  tout usage de  lʹune de  ces variables de  corrélation à  lʹintérieur dʹun bloc PL/SQL  exige  le préfixage par  les deux points (:).   CREATE OR REPLACE TRIGGER valid_qte AFTER UPDATE OF qte_V  ON   

INVENTAIRE FOR EACH ROW DECLARE ERREUR1 exception; BEGIN  IF :NEW.qte_v  > :OLD.qte_v  THEN RAISE ERREUR1; END IF; EXCEPTION  WHEN ERREUR1 THEN RAISE_APPLICATION_ERROR      (‐20001, ʹerreur: nouvelle quantité plus grande que la précédenteʹ); END ; 

                                                                     Ce trigger est exécuté autant de fois quʹil y a de tuples mis à jour dans la table Inventaire par  lʹénoncé de mise à  jour associé. Si  le  trigger échoue  , cʹest‐à‐dire   si une exception nʹest  pas  traitée  correctement  ou  si  le  bloc  lance  un  appel  à  la  procédure  stockée RAISE_APPLICATION_ERROR( ), la transaction est lʹobjet dʹun rollback automatique et le contrôle est passé à  la procédure appelée et, finalement, à  lʹenvironnement appelant, notamment SQL*PLUS ou SQLFORMS ou à une application C.  La procédure stockée RAISE_APPLICATION_ERROR() a deux arguments  : un nombre négatif entre ‐20 000 et ‐20 999 et une chaîne de caractères dont la longueur est inférieure à  512 octets. Le  rôle de  cette procédure  est de passer  à  lʹenvironnement  appelant  (ex. Developer 2000 et L3G) un numéro dʹerreur et un message de manière à les afficher pour lʹutilisateur. Ainsi,  si une  application  SQLFORMS  effectue une mise  à  jour  incorrecte, lʹaction  liée  à  la  BD  sera  défaite  par  le  trigger  valid_qte    et  le  numéro  dʹerreur  et  le message seront interceptés et traités correctement à la façon de SQLFORMS.     

:new  

‘f8’, ‘ailes du nord’, 25Table Transporteur :   ‘f8’,  ‘ailes  du  nord’, 25 

Page 183: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

183

                                     

Validation dʹun attribut de tuple en insertion Pour valider le fait que la valeur dʹun attribut doit avoir une valeur préexistante dans la BD,  il suffira de définir un  trigger BEFORE FOR EACH ROW. Par exemple,  le  tuple à insérer doit utiliser un patronyme absent dans la BD, sinon le tuple nʹest pas accepté .  

CREATE OR REPLACE  TRIGGER  TRIG_INSERT5    BEFORE  INSERT OF  nom ON Patient FOR EACH ROW DECLARE nbpat  integer; BEGIN SELECT count(*) INTO nbpat FROM Patient WHERE nom = :new.nom;     ‐‐si 0 alors nom absent IF nbpat = 0 THEN NULL else RAISE_APPLICATION_ERROR (     ‐20249, ʹpatient existant dans la BDʹ); END IF ; END ;

8.20 Problème et résolution de la mutation des tables (Oracle) Voici  une  base  de  données  simple  formée  par  deux  tables  Employe  et  Projet  entre lesquelles il y a une association matérialisée par une contrainte référentielle. Un trigger défini sur une table et qui est lancé suite à une mise à  jour ou à un INSERT  sur la dite table génère une erreur de table en mutation. La seule façon de corriger ce problème est de passer par un package et de créer une variable globale au niveau du serveur. Exemple : 

Employe(nas*, nom, classe)  Projet (noP*, site, budget, nas) 

                        Create table Employe( 

nas integer primary key, nom varchar2(40) not null, classe char(1) not null);        

 CREATE table Projet( 

noP integer primary key not null, site varchar2(40) not null, budget number(7,2) not null, nas integer, constraint fk_ProjetEmploye Foreign key (nas) References Employe(nas)); 

 SQL> SELECT * FROM  Employe; 

 nas  nom  classe 

Page 184: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

184

1  Gagné  A 2  Michaud  A 3  Landry  A 

  

noP  site  budget  nas 100  Québec  20000  1 101  Québec  40000  2 102  Montréal  5000  3 

 Il y a une contrainte de mise à jour définie sur la table projet qui limite la somme totale des budgets des projets  en  cours  au même  site  à  90  000.00$. La  seule définition d’un trigger BEFORE Update  sur  la  table Projet génère une erreur de  table  en mutation en raison de  la portée du  trigger qui doit vérifier que  les projets de Québec  et pour  cela utiliser la variable de tuples :NEW.                                  

Create or Replace trigger ProjetQcLim BEFORE Update on Projet for each row Declare total number(8,2); Begin Select Sum(budget) INTO total FROM  Projet Where site = ʹQuébecʹ; if total + :NEW.budget > 90000.00 THEN  Raise_Application_Error(‐20600,ʹBuget total dépassé pour Québecʹ); end if; end; 

Déclencheur créé.  

SQL> UPDATE Projet set budget = 20000.00 WHERE no_p= 100; ERREUR à la ligne 1 : ORA‐04091:  table AGAMACHE.PROJET  en mutation,déclencheur/fonction  ne  peut  la voir  ORA‐06512: à ʺAGAMACHE.PROJETQcLIMʺ, ligne 4 ORA‐04088:erreur lors dʹexécution du déclencheur ʹAGAMACHE.PROJETQCLIMʹ  SELECT * FROM  projet;    

noP  site  budget  nas 100  Québec  20000  1 101  Québec  40000  2 102  Montréal  5000  3 

 

Page 185: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

185

Aucune mise à jour effectuée. Pour corriger cette situation et pouvoir effectuer la mise à jour, il suffit d’utiliser une variable globale définie dans un package qui sera par la suite rangé au niveau du serveur.  /* création de la variable globale via un package */ Create package Var_globale as v_site varchar2(40); end;  /* initialisation de la variable globale */ Create or Replace trigger initSite BEFORE UPDATE on Projet for each row BEGIN var_globale.v_site := :NEW.site; Exception When NO_DATA_FOUND THEN   Raise_Application_Error(‐20500, ʹpas de projet à Qcʹ); end;                                /* vérification du dépassement de la limite pour un même site */ Create OR Replace trigger controle_budget AFTER UPDATE on Projet Declare v_total number(8,2); BEGIN Select sum(budget) INTO v_total From Projet Where site = var_globale.v_site; if v_total > 90000.00 THEN  Raise_Application_Error(‐20300, ʹpas de MAJʹ); end if; end; ‐‐ Mise à jour du budget du projet no_p = 100    

Update Projet set budget = 60000.00 WHERE no_p= 100;  

Mise à jour refusée par le trigger :  

nop  site  budget  nas 100  Québec  20000  1 101  Québec  40000  2 102  Montréal  5000  3 

 La transaction est annulée automatiquement et les modifications effectuées sont défaites par le gestionnaire de transaction. 

Page 186: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

186

8.21 Trigger INSTEAD OF Si la définition d’une vue comporte une jointure, elle ne peut pas être mise à jour par les ordres Insert, Update et Delete. Il est possible de contourner cette difficulté au moyen du trigger  Instead  Of  qui  vient  à  la  rescousse  de  la  vue  et  fournir  une  procédure  de remplacement capable de faire le travail autrement impossible. Pour ce faire, le nouveau trigger doit faire directement et précisément sur les tables de base les multiples actions sous‐tendues par l’ordre d’origine sur la vue.                   Par  exemple  l’insertion  d’un  tuple  au moyen  d’une  vue  définie  par  une  jointure  est rendue possible par le noyau en interceptant la mise à jour sur la vue et en effectuant les insertions appropriées sur les deux tables référées par la vue.   Create table Projet ( 

noP number(4) primary key, pDesc varchar2(40));  Create table Empl( mat number(4) primary key, nom varchar2(40), salaire number (7,2), noP number(4), constraint fk_Projet foreign key (no_p) references Projet (noP)) ; 

                               La vue définie avec la jointure est la suivante :    

Create View v_E_P as Select E.mat, E.nom, P.no_p, P.p_desc From Projet P, Empl E Where P.noP = E.noP; 

 Voici une insertion effectuée à travers la vue v_E_P :  Insert  INTO  v_E_P  VALUES    (50,‘Legendre’,  625,  ‘colliger  des  stats’) ;    (dml  de l’application)  À l’exécution, une erreur sera signalée pour indiquer l’impossibilité de faire directement cette insertion via la vue relationnelle. Par contre, une telle mise à jour peut être faite par le trigger Instead Of associé à la vue relationnelle v_E_P.                                Create or REPLACE    trigger  inst_emp_projet_INSERT    instead of  Insert on v_E_P  for each row   

Declare c number; 

Page 187: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

187

Begin SELECT count(*) INTO C  ‐‐ absence du tuple à ajouter ? FROM  Empl Where Empl.mat = :NEW.mat; if c = 0 THEN  Insert INTO Empl ( mat, nom) VALUES  ( :NEW.mat, :NEW.nom);  end if; Select count(*) INTO c FROM  Projet ; if c = 0 THEN  Insert INTO Projet (noP, pDesc) VALUES  (:NEW.no_p, :NEW.pDesc); end if; end; 

                                                                       SQL> Insert INTO v_E_P VALUES  ( 50, ʹLegendreʹ, 625, ʹcolliger des statsʹ)  ; 1 row created.  – 1 tuple par la vue, mais 2 tuples par le trigger.  SQL> SELECT * FROM  empl;       MAT NOM                  SALAIRE      NO_P ‐‐‐‐‐‐‐‐‐ ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ ‐‐‐‐‐‐‐‐‐       50   Legendre  SQL> SELECT * FROM  projet; 

    NOP     PDESC ‐‐‐‐‐‐‐‐‐ ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐    625     colliger des stats 

                           En résumé, le trigger Instead Of permet de contourner  la difficulté soulevée par  la vue relationnelle  définie  avec  une  jointure  et  cela,  en  fournissant  au  noyau  du  SGBD  les règles précises pour répercuter l’opération sur les tables de base.  8.22 Générateur de nombres séquentiels  

 Le déclencheur est  souvent utilisé pour générer un nombre  séquentiel qui est  souvent utile aux applications. Ce générateur monotone avec mémoire permet, par exemple, de numéroter séquentiellement des pièces, des commandes et des transactions. Le nombre est généré à partir dʹune valeur initiale et sa valeur croît à chaque émission jusquʹà une limite supérieure. Le mécanisme utilisé par Oracle pour générer un nombre séquentiel se comporte comme une fonction, avec une mémoire créée avec un nom particulier fourni par lʹapplication qui active le générateur. Elle peut être vue comme une pseudo‐table à un tuple, dotée de pseudo‐colonnes, notamment  la NEXTVAL. La pseudo‐table ne peut 

Page 188: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

188

pas  être  référencée  directement  dans  la  sous‐clause  FROM.  A  chaque  référence,  le générateur fournit la valeur suivante sans utiliser de verrou. Ce générateur est très utile dans  un  trigger  pour  générer  automatiquement  un  numéro  de  lot,  ou  de  facture  ou encore un numéro dʹordre.  La séquence est créée par la commande suivante :  CREATE SEQUENCE nbseq INCREMENT BY 1 start WITH 1 MAXVALUE 999;      Le  générateur  est  un  objet  de  la  base  qui  peut  être  partagé  pour  autant  que  le propriétaire accorde les droits dʹaccès aux autres utilisateurs.     

GRANT SELECT on nbseq to utilisateur5;   

Le générateur peut être supprimé par la commande :  DROP SEQUENCE nbseq; 

 

Exploitation concurrente du même générateur par deux applications La pseudo‐colonne CURRVAL  fournit  toujours  la dernière  valeur  générée  et  obtenue suite à la dernière requête effectuée par cette application indépendamment des autres.              Un  inconvénient  de  ce  type  de  génération  est  la  perte  éventuelle  dʹun  entier  lorsque lʹapplication qui lʹa demandé ne lʹutilise pas. En perdant ce nombre,  il y a des trous dans la suite des entiers stockés dans la BD.                                

Figure 8.33 

Application A :  Select nbseq.NEXTVAL Into nb;  Select nbseq.CURVAL Into nb;   Select nbseq.NEXTVAL Into nb;  

43

Dictionnaire Nbseq 42 

99‐ 

Dernière  valeur générée 

43

Application B :  Select nbseq.NEXTVAL Into val;

4445

1

2

3

4

Page 189: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

189

Privilège pour la création dʹun générateur La création dʹune séquence est possible si lʹutilisateur a le privilège CREATE sequence. La séquence  correspond  à une  table dont  la définition  est  rangée dans  le dictionnaire  et dont les données sont chargées dans lʹespace de table SYSTEM.                  Pour obtenir une valeur de  la séquence et  lʹaffecter à une variable maph  (matricule du patient hospitalisé),  il suffit dʹexécuter dans un trigger  lʹénoncé SQL ci‐dessous qui fait référence à un autre séquenceur nommé, par exemple, nbseq. Pour générer un nombre et le ranger dans une variable ou dans un attribut du tuple courant, on utilisera  la clause SQL suivante :  

SELECT nbseq.NEXTVAL INTO  :new.maph FROM Dual;  Lʹinsertion de  la valeur  est  faite dans  le  tuple  courant  (:new), quelle que  soit  la  table ciblée  par  lʹinsertion,  et  écrase  toute  autre  valeur  préalablement  affectée  à  lʹattribut maph.  Il  est  aussi  possible  dʹobtenir  la  valeur  courante  du  générateur  par  lʹattribut  CURRVAL.   

SELECT nbseq2.CURRVAL INTO :new.maph FROM Dual;  

Stockage des triggers dans le dictionnaire Les triggers de BD spécifiés par lʹadministrateur de la BD sont rangés dans une table du dictionnaire   (table USER_TRIGGERS) dont  le schéma est donné ci‐dessous. Un trigger peut être supprimé par son propriétaire ou par le DBA qui a le privilège DELETE ANY TRIGGER. 

Schéma de la table USER_TRIGGERS du dictionnaire  TRIGGER_NAME    NOT NULL    VARCHAR2(30) TRIGGER TYPE           VARCHAR2(16) TRIGGERING_EVENT        VARCHAR2(26) TABLE_OWNER    NOT NULL    VARCHAR2(30) TABLE_NAME    NOT NULL    VARCHAR2(30) REFERENCING_NAMES        VARCHAR2(87) WHEN_CLAUSE          VARCHAR2(2000) STATUS            VARCHAR2(8) DESCRIPTION          VARCHAR2(2000) TRIGGER_BODY          LONG 

Figure 8.34  Ainsi, pour connaître le corps du trigger tr34, son propriétaire peut interroger une table du dictionnaire de données à laquelle il a accès. 

SELECT  TRIGGER_BODY  FROM    USER_TRIGGERS    WHERE   trigger_name= ʹtr34ʹ; 

Page 190: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

190

 

Prédicats spéciaux pour les triggers de BD Lorsquʹun  trigger  est déclenché,  il  est possible de  connaître  la nature de  lʹordre DML associé de même que lʹattribut visé par lʹaction.  Prédicat  Prédicat(attribut)  Evaluation INSERTING  Inserting(nom)  IF Inserting(nom) THEN …     Vrai si le DML déclencheur est un Insert. UPDATING  Updating(Salaire)  Vrai si le salaire est modifié DELETING    Vrai si le tuple est l’objet d’une suppression dans la table.  Ces prédicats spéciaux simplifient la programmation des triggers en permettant de faire un  test  sur  la  nature de  lʹopération  en  cours.  Soit  le  trigger Trig_ajout  qui  lance  une insertion suite à un ajout fait dans la table Inscription. 

CREATE OR REPLACE TRIGGER TRIG_AJOUT   AFTER INSERT OR UPDATE OF  Statut ON Inscription FOR EACH ROW BEGIN /*  traitement dʹune  nouvelle  inscription dans  la  table du même  nom    lorsquʹil sʹagit dʹune insertion */ IF INSERTING THEN    UPDATE  TABLE_INSC   SET nbInsc = nbInsc + 1    WHERE TableIns.code = :new.code; END IF; END;  

                      À noter  que  le  trigger  est  associé  à plusieurs  ordres DML  réunis dans une  condition logique disjonctive : INSERT OR UPDATE. 

Privilèges pour la création dʹun trigger Un utilisateur peut créer un trigger dans son schéma sʹil a le privilège système approprié :  CREATE  TRIGGER.  De  plus,  il  pourrait  créer  un  trigger  dans  un  autre  schéma appartenant à un autre compte, sʹil avait le privilège système CREATE ANY TRIGGER. 

Modification de la définition dʹun trigger de BD La spécification du corps dʹun trigger ne peut pas être modifiée; elle doit être remplacée ou  supprimée  et  finalement  créée  à  nouveau.  Si  lʹon  supprime  un  trigger  par  la commande DROP TRIGGER nom_trigger , il y a aussi suppression de tous les grants ou droits accordés à ce  trigger. Par  la suite, après  la création du  trigger modifié,  il  faudra accorder à nouveau les privilèges au trigger. Pour éviter de perdre les grants du trigger à remplacer, il faut utiliser lʹoption REPLACE du CREATE ou encore utiliser CREATE OR REPLACE.                                    

CREATE  OR  REPLACE  TRIGGER  TR60  AFTER  UPDATE  OF  Qte_d  ON Production FOR EACH ROW 

Page 191: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

191

DECLARE . . . BEGIN . . .   EXCEPTION . . . END; .  <‐‐ le point pour quitter lʹéditeur de PL/SQL ou un / pour  quitter et exécuter le trigger 

 Certains  paramètres  dʹun  trigger  peuvent  être  changés  après  la  création.  Ainsi, lʹactivation ou la désactivation dʹun trigger particulier ou de tous les triggers dʹune table est possible par la commande ALTER :  

ALTER TRIGGER TR35   ENABLE; ALTER TABLE USINES   DISABLE ALL TRIGGERS; 

 Voici  un  trigger  plus  complexe  qui  vérifie  la  clé  étrangère  dʹune  relation  ATELIER chaque  fois  quʹil  y  a  ajout  ou  modification  dʹun  tuple  dans  la  table  ATELIER.  La vérification de  la clé est    faite pour valider une contrainte dʹintégrité  spécifiée dans  le schéma  de  la  relation.  Lʹusage  dʹun  curseur  dans  ce  trigger  doit  se  faire  avec  un paramètre parce que lʹexécution du SELECT ne garantit pas le retour dʹun seul tuple de la BD.   Normalement,  si  le prédicat nʹutilise pas une  clé primaire,  il y  aura plusieurs tuples  dans  la  réponse. Dans  un  tel  cas,  les  tuples  de  la  réponse  sont  logés  dans  un espace associé à un curseur Oracle créé dans  l’espace mémoire du  serveur. Les  tuples sont ramenés successivement à la station client par un ordre FETCH. En ce faisant, une ou  des  variables  locales  au  bloc  PL/SQL  sont  utilisées  pour  référer  aux  valeurs  des attributs. 

 Create  or  REPLACE  trigger  valid_clef_etrang AFTER  INSERT    or UPDATE  on ATELIER FOR EACH ROW WHEN (new.noUsine is not NULL)  /*condition supplémentaire de déclenchement du trigger */ /* avant lʹinsertion ou la modification dʹun tuple concernant un atelier, il y a une validation de sa clé étrangère, soit son noUsine dans la table parent USINES.  */ DECLARE  v_noAtel  integer; atelier_invalide exception; atelier_valide exception; erreur_piegee exception; PRAGMA EXCEPTION_INIT (erreur_piegee, ‐4091);   /*erreur interne Oracle traitée par lʹapplication  via lʹexception erreur_piegee)  dn est le paramètre du curseur*/    

Page 192: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

192

CURSOR curs_temp (dn NUMBER) IS  SELECT noAtelier FROM USINES  WHERE noAtelier = dn  FOR UPDATE; 

 BEGIN        OPEN curs_temp (:new.no_atelier);      /* du tuple qui a déclenché le trigger */    FETCH curs_temp INTO v_noAtel;    IF curs_temp%NOTFOUND THEN RAISE atelier_invalide;      ELSE RAISE atelier_valide;    END IF; EXCEPTION WHEN atelier_invalide  THEN RAISE_application_error(       ‐20010, ʹno atelier inexistantʹ); CLOSE curs_temp; WHEN atelier_valide THEN CLOSE curs_temp; WHEN erreur_piegee THEN NULL;/* erreur et rien faire */ WHEN OTHERS THEN Message(ʹautre erreurʹ); END; 

Figure 8.35 

Trigger pour la station client Oracle (Developer/2000) En sus des triggers définis au niveau de la BD, il est fort utile aussi de pouvoir spécifier certains  triggers  au  niveau  du  logiciel  client.  Dans  un  tel  cas,  le  trigger  sʹexécute immédiatement dès  lors que survient  lʹévénement déclencheur chez  le client, et non en différé comme cʹest  le cas pour certains  triggers de  la BD qui ne  se déclenchent quʹau moment  du  COMMIT  de  la  transaction  en  cours.  Pour  certaines  applications  client‐serveur, les triggers de BD peuvent faire double emploi, si un trigger identique a déjà été exécuté dans la station. Lʹassurance que le trigger du client sera toujours exécuté avec la même spécification ne relève pas normalement de la compétence du DBA.  

Signature et trigger client Il  serait  possible  de mettre  à  contribution  une  condition  de  déclenchement  préalable (clause WHEN) pour éviter dʹexécuter un trigger de BD, si une variable dʹétat représente la garantie (relative cependant) que le trigger correspondant a été exécuté par la station client. Une autre façon serait de calculer une signature (par exemple, celle de type DES ou RSA) pour chaque  trigger dʹune application et de  les stocker au niveau du serveur. Chaque fois quʹune application demande une action dʹinsertion ou de modification dans la BD, elle transmet aussi la signature que le client calcule à partir de la version actuelle du trigger de la station. Le serveur peut donc la comparer avec celle qui est stockée et, sʹil y a une différence,  le  trigger de  la BD sera exécuté. Ainsi,  toute validation  faite au niveau  de  la  station  par  un  trigger  identique  à  celui  du  serveur  ne  sera  pas  refaite 

Page 193: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

193

inutilement. Bien  entendu,  tous  les  triggers ne peuvent pas  être  implémentés de  cette façon,  car  certains  sont  propres  à  la  BD  et  devront  nécessairement  être  exécutés uniquement par le serveur.   Voici  un  autre  exemple  dʹun  trigger  de  validation  plus  simple  qui  nʹutilise  pas  un curseur, mais plutôt la variable de corrélation new.attribut   pour se référer à la nouvelle valeur de lʹattribut COULEUR dont le type est VARCHAR2 :  

CREATE TRIGGER TRIGCOUL  AFTER INSERT ON TPLAN FOR EACH ROW  DECLARE   couleur_valide exception; BEGIN  IF :new.COULEUR = ʹrougeʹ THEN RAISE couleur_valide;  ELSIF :new.COULEUR = ʹblancʹ THEN RAISE couleur_valide;   ELSE RAISE_APPLICATION_ERROR (‐20401,ʹcouleur invalideʹ); END IF; EXCEPTION WHEN couleur_valide THEN NULL ; WHEN OTHERS THEN Message(ʹautre erreurʹ); END;  

Figure 8.36  

8.23  Synonyme 

Les différents objets gérés par  le SGBD  sont  identifiés par des noms qui peuvent  être plus ou moins complexes. Par exemple, une  table pour  les  transactions de vente de  la première  campagne  de  publicité  faite  par  lʹagence  Martin  au  cours  du  deuxième trimestre 96 est nommée Ventes_pub_Martin.trim2_1996.  Il est possible dʹassocier à ce nom un synonyme plus court et peut être plus significatif pour  les utilisateurs comme par exemple Martin2_96. Avec la définition de ce synonyme rangé dans le dictionnaire, il devient possible de référer à la table source par lʹun ou lʹautre des noms.   

CREATE SYNONYM Martin2_96  FOR Ventes_pub_Martin.trim2_1996;  Ce synonyme est rendu disponible automatiquement à tout utilisateur qui entre en ligne avec le numéro de compte de la personne qui lʹa créé. Le DBA a lʹautorisation de créer de tels synonymes qui sont privés par défaut,  i.e. que  leur portée est  limitée à un schéma. Au contraire, un synonyme est créé public pour quʹil soit  accessible à tous les schémas. Un synonyme PUBLIC  est créé par la commande CREATE PUBLIC SYNONYM.  CREATE [PUBLIC] SYNONYM promotion97 FOR laval_trim3_1997;                                         

Page 194: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

194

Tout objet de la BD peut être renommé par un synonyme afin dʹen faciliter la référence, notamment  la  table,  la  vue,  le  lien  de  BD  distante,  lʹindex  et  la  procédure.  Les synonymes qualifiés de PUBLIC sont accessibles à toutes les applications.                                                           Le  mécanisme  des  synonymes  est  un  moyen  simple  et  efficace  de  rendre  des changements  dans  les métadonnées  transparents  aux  applications  et  de  simplifier  la formulation des requêtes DML pour  les utilisateurs. Ainsi,  tout changement au niveau du dictionnaire qui  consiste à  changer  le nom des  tables, des  index, des  séquences…, exigera  par  voix  de  conséquence  un  changement  du  nom  de  lʹobjet  dans  toutes  les applications opérationnelles. Par contre, si les applications utilisent des synonymes pour référer aux tables, aux index..., les changements de nom des objets de la base nʹont plus dʹimpacts sur les applications.                  8.24 Droits d’accès et compte‐utilisateur 

La  sécurité  dʹune  base  de  données  concerne  est  assurée  en  premier  par  un  contrôle rigoureux des accès aux différents objets dʹune base de données. Une base, rappelons‐le, comprend des objets que sont les tables, les espaces de données, les vues, les triggers, le schéma,  les  synonymes,  les  liens  entre  les bases,  les  rôles,  les  comptes‐utilisateurs,  les séquences,  les  procédures  et  les  packages.  Le  DBA  est  celui  qui  possède  tous  les privilèges  dès  la  création  de  la  base.  Cʹest  à  sa  guise  que  certains  privilèges  sont propagés aux utilisateurs selon  leurs besoins et que dʹautres, comme celui de créer des comptes  lui  demeurent  exclusifs.  Il  y  a  des  privilèges  de  système  et  des  privilèges dʹobjet. 

Création d’un compte‐utilisateur Le premier niveau de  sécurité est  celui de  la  création du  compte pour entrer en  ligne avec  lʹinstance  du  SGBD.  Cette  communication  doit  être  authentifiée  par  un mot  de passe fourni par lʹutilisateur et vérifié par le SGBD ou le système dʹexploitation hôte. La création des comptes est faite par le DBA soit avec lʹutilitaire SQLDBA, soit directement avec la commande CREATE.   Par exemple :    

CREATE USER  jbouchard IDENTIFIED BY qc1998fre;   Par défaut, cʹest le serveur qui vérifie la validité du mot de passe en consultant une table du dictionnaire réservée aux mots de passe. Dʹautre part,  la vérification peut être prise en charge par  le système dʹexploitation hôte qui assure quʹun numéro de compte pour utiliser  le SGBD  est aussi protégé par  le même mot de passe que  celui qui protège  le compte du système dʹexploitation :  

CREATE USER OPS$jbouchard IDENTIFIED EXTERNALLY;  

Page 195: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

195

La sécurité peut aussi être augmentée pour protéger les communications entre les clients et le serveur. Il est possible de spécifier au serveur de recevoir et de déchiffrer les mots de passe de chaque client.  

Suppression dʹun compte Le DBA ou un compte qui possède  le privilège de supprimer un compte peut enlever lʹaccès à la BD à un compte tout en conservant ou non les différents objets que ce compte a créés lors des sessions de travail antérieures.  Exemples : Cas 1 : Supprimer un utilisateur du SGBD inscrit dans le dictionnaire 

DROP USER jbouchard;   Cette  commande  inhibera  lʹaccès  à  la  BD  pour  ce  compte  si  ce  dernier  nʹa  pas  créé dʹobjets dans  la BD. Dans  le  cas  contraire,  la  commande  ne pourra pas  supprimer  le compte.  Cas 2 : Supprimer   un compte qui a déjà créé des objets comme un schéma, des tables, des triggers, ... La suppression d’un utilisateur entraîne aussi celle des ses objets créés.  

DROP USER jbouchard CASCADE;  De cette façon, tous les objets qui appartiennent au schéma de cet utilisateur sont aussi supprimés de la base de données.  Cas  3 :  Suppression  de  la  capacité  dʹun  compte  à  communiquer  avec  le  SGBD  sans détruire  les objets de son schéma. Pour ce  faire,  il suffit de  lui  retirer son privilège de création dʹune session.  

REVOKE CREATE SESSION FROM jbouchard;   Le  privilège  CREATE  SESSION  est  essentiel  à  un  compte  utilisateur  pour  entrer  en communication avec la BD. Un utilisateur pourrait avoir un mot de passe pour entrer en ligne avec le SGBD, mais ne pas pouvoir exploiter la BD parce quʹil nʹa pas le privilège de créer une session.  Un privilège de système est le droit de créer, de supprimer ou de modifier un objet qui est associé à lʹusage des ressources du système nécessaires pour le bon fonctionnement du SGBD. Parmi ces nombreux  privilèges de système, il y a notamment les suivants :  Création de tout cluster quelconque (ANY) Création dʹun lien de BD Modification de tout index      Affectation de tout privilège Suppression de toute procédure    Création de tout rôle Création de tout profil, fonction, ...    Création dʹun utilisateur 

Page 196: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

196

Création et exploitation de séquence s  Création dʹun espace de données Création de tout synonyme      Création dʹun index   Création d’une session      Création de tables       Les  privilèges  du  type  objet  concernent  les  opérations  qui  sont  autorisées  quant  aux objets du schéma. Ils sont aussi très nombreux. En général, ces privilèges sont associés aux  opérations  dʹinsertion,  dʹajout,  de  suppression  et  de modification  dʹun  objet  du schéma. Par exemple, pour que  lʹutilisateur util5 puisse  créer une  table Usines,  il doit avoir  le  privilège  de  créer  son  schéma  et  dʹy  créer  cette  table. De  plus,  si  le même utilisateur veut insérer des tuples, il devra avoir le privilège dʹinsertion et naturellement celui de suppression.   Le propriétaire dʹun objet a automatiquement tous  les droits sur cet objet. Il peut donc ajouter,  supprimer des  tuples  et  finalement  supprimer  la  table.   Pour que  lʹutilisateur util8 ait aussi les droits dʹinsérer des tuples dans la table créée par util5, il nʹa pas besoin dʹavoir le privilège INSERT ANY TABLE, mais seulement celui dʹinsertion dans la table Usines, que le propriétaire peut lui accorder par la commande GRANT.    

Ressources du système pour un utilisateur : notion de PROFILE Lorsquʹun utilisateur a  les privilèges nécessaires pour exploiter une BD,  il peut  le  faire sans limitation des ressources utilisées. Par exemple, lʹutilisateur peut rester en ligne un temps illimité ou être limité à un temps borné. Il pourra créer autant de tuples quʹil veut sans contrainte dʹespace ou être limité à un espace sur disque prédéfini.  Ces contraintes sont spécifiées dans un profil associé à un utilisateur lors de la création de son compte.   CREATE PROFILE usager_profil5 LIMIT  

CONNECT_TIME 50 IDLE_TIME  10;  CREATE USER jbouchard IDENTIFIED BY qc97fre PROFILE usager_profil5; 

 Si lʹutilisateur est déjà créé, il est possible dʹajouter le profil avec la commande ALTER. 

ALTER USER  jbouchard PROFILE usager_profil5;  Il y a un profil par défaut qui est celui du serveur et qui est associé à tout utilisateur par défaut. Ce profil nʹest pas contraignant puisquʹil spécifie la valeur UNLIMITED pour les ressources qui nʹont pas été redéfinies dans un profil dʹutilisateur.   

ALTER PROFILE usager_profil5; 

Propagation des privilèges aux utilisateurs Si  le  seul  créateur de  tables dans  le  schéma  est  le DBA,  il  est  alors  le  seul  à pouvoir accorder des privilèges aux autres utilisateurs pour leur permettre de lire, dʹaugmenter, de supprimer et de modifier lʹextension dʹune table.   

Page 197: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

197

   GRANT SELECT (no_us, ville) ON Usines TO util6, util7; GRANT DELETE ON Usines TO util7; 

                                    Dans lʹexemple qui précède, les utilisateurs util6 et util7 peuvent dorénavant accéder à la table Usines et y faire des sélections avec nʹimporte quel attribut de la table pour obtenir les  tuples.  Toutefois,  ces  utilisateurs  ne  peuvent  pas  transmettre  leur  privilège  à  un autre, sauf si le privilège quʹils ont reçu est assorti de la clause WITH GRANT OPTION.   Lorsquʹil sʹagit dʹun privilège de système,  la clause WITH ADMIN OPTION accorde  la même autorisation de transmettre :  

GRANT SELECT ON Usines TO util6, util7 WITH GRANT OPTION;  Il est aussi possible de limiter les attributs visibles pour une action liée à une table. Par exemple, supposons que lʹutilisateur util9  a les droits de lecture dʹune table Usines, mais que son droit de mise à jour est limité à celui dʹun attribut, soit la capacité.  Dans ce cas, le grant spécifie lʹattribut qui peut être ciblé par la mise à jour :   

GRANT SELECT, UPDATE(capacite) ON Usines TO util9;  Le même résultat est obtenu en définissant une vue, Vue_capacite:     

CREATE VIEW Vue_capacite AS SELECT capacite FROM Usines;  Afin de permettre,  la sélection et  la mise à  jour de  la table Usines par  lʹentremise de  la vue, il faut accorder les privilèges  SELECT et UPDATE à la vue.     

GRANT SELECT, UPDATE ON Vue_capacite WITH CHECK OPTION;  Lʹoption CHECK permet de limiter les mises à jour aux tuples qui sont visibles à travers la vue, cʹest‐à‐dire aux usines de la ville de Québec. De plus, lʹutilisateur ne pourra pas ajouter un  tuple qui ne  serait pas visible par  la  suite par  lʹentremise de  la même vue, comme  lʹajout dʹune usine  localisée à  ʺMontréalʺ. Sans  la clause CHECK OPTION, cet ajout serait possible. 

Révocation des privilèges À tout moment, le DBA ou le propriétaire du compte qui a accordé le privilège peut le supprimer par la commande REVOKE. Supposons que lʹutilisateur util5 a accordé à util9 le  privilège  système  de modifier  nʹimporte  quel  index.    Il  peut  le  lui  retirer  par  la commande suivante :  

REVOKE CREATE ANY INDEX FROM util9;  

Page 198: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

198

À noter que la suppression dʹun privilège ne se propage pas aux autres utilisateurs qui lʹauraient acquis de lʹutilisateur util9.     8.25 Rôle 

La  notion  de  rôle  est  propre  au  système  Oracle;  elle  est  cependant  une  notion  fort intéressante  pour  le  DBA.  Cela  permet  de  simplifier  la  gestion  des  privilèges  en regroupant ceux‐ci dans un rôle qui est accordé aux utilisateurs. Lʹintérêt de cette notion est  quʹelle  permet  de modifier  les  privilèges  dʹun  groupe  dʹutilisateurs  en modifiant simplement  le  rôle. Chaque  rôle a un nom et un contenu qui sont définis séparément. Par exemple, on aura :  CREATE ROLE chefUsine NOT IDENTIFIED; ‐‐aucun mot de passe pour activer le rôle  Dans  lʹexemple qui précède  le  rôle  est  créé avec  le nom  chefUsine et  ce  rôle nʹest pas protégé par un mot de passe.  Au contraire, dans lʹexemple ci‐dessous le chefUsine a une protection par un mot de passe. Par la suite, le rôle est enrichi avec les privilèges dont les utilisateurs ont besoin : 

GRANT CREATE SESSION TO chefUsine IDENTIFIED BY 34y586j; GRANT SELECT, INSERT, UPDATE ON Usines TO chefUsine; 

 Le rôle chef_usine est aussi accordé aux utilisateurs par la commande GRANT : 

GRANT chefUsine TO util2, util3, util9, util15;  Un même  utilisateur  peut  avoir  plusieurs  rôles.  En  effet,  lʹassociation  dʹun  rôle  à  un utilisateur ne  lʹactive pas  toujours  immédiatement. Cʹest par  la  commande SET ROLE quʹun rôle est activé pour un utilisateur : 

SET ROLE chefUsine;  Tous les rôles sont activés par la clause  ALL.  

SET ROLE ALL; 

Rôle par défaut Le  rôle  par défaut  est défini  à  la  création dʹun  compte dʹutilisateur.  Par  exemple,  on aura: 

CREATE USER util9 DEFAULT ROLE chefUsine;  Si lʹon procède ainsi, chaque fois que lʹutilisateur util9 démarre une session de travail, le rôle chefUsine devient automatiquement actif. 

Information sur les rôles Lʹinformation sur les rôles définis dans une BD est stockée dans deux tables que le DBA peut interroger avec une requête SQL. La table DBA_ROLES contient le nom de tous les 

Page 199: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

199

rôles  définis  dans  la  BD.  La  vue  DBA_ROLE_PRIVS  permet  de  connaître  les  rôles associés aux différents utilisateurs :    

SELECT role FROM DBA_ROLES;   ‐‐ lecture de la table du dictionnaire sur les rôles SELECT grantee, granted_role FROM DBA_ROLE_PRIVS;  

Exercices du chapitre 8 

1‐ Développer un trigger dʹinsertion de type BEFORE pour vérifier que tout ajout dans la relation Empl  est  refusé  si  le nombre dʹemployés dont  le  taux horaire  est  supérieur  à 14.00 $ ne dépasse pas celui des employés dont  le  taux horaire est  inférieur ou égal à 14.00 $ (voir l’instance de référence de BD3).    2‐ Voici une partie de la BD dʹun CEGEP, qui est composée de deux relations dont lʹune a une clé composée : 

Eleve (mat*, nomE, adresCampus, moyE) Inscription (mat*, cours*, note) 

 Les requêtes ci‐dessous sont considérées typiques du traitement fait par le SGBD : 

SELECT E.mat, E.nomE, I.cours, I.note FROM Eleve [as] E, Inscription [as] I WHERE E.mat = I.mat and I.note > 2.5; 

 SELECT cours, note FROM Inscription WHERE  mat = ʹ9203498ʹ;  

SELECT mat, note FROM  Eleve E, Inscription  I WHERE E.mat = I.mat and      mat = ʹ92000000ʹ and      cours = ʹift‐14678ʹ;  

              2.1 Créer  le  schéma des  relations Élève et  Inscription en  spécifiant  les clés primaire et étrangère.   2.2‐ Sur quels attributs faut‐il créer un  index pour accélérer  le calcul de  la réponse aux  requêtes ci‐dessus? Commenter votre réponse.  2.3‐ Formuler les commandes nécessaires pour créer les index appropriés.                                   3‐  Créer et accorder à lʹutilisateur du compte25 les privilèges de lecture et de mise à jour sur les relations Eleve et Inscription et,  pour le compte31, les accès en lecture seulement sur la relation Eleve.  

Page 200: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

200

4‐ Créer les comptes bd345 et bd124 en leur associant respectivement les mots de passe ʹbv3m67ʹ et ʹu82jvg7ʹ. Pour faire cet exercice vous devez avoir le privilège de création de comptes.                            5‐ Désactiver la contrainte référentielle qui serait définie et activée dans la BD CEGEP.  6‐ Expliquer pourquoi  il ne peut pas y avoir de rollback dans un  trigger de BD stocké dans le dictionnaire? Suggestion : réfléchir au traitement dʹune cascade de triggers. 7‐ Développer un bloc PL/SQL pour augmenter de 15% le prix des articles en inventaire (BD1) qui ont une marge bénéficiaire.  8‐ Au moyen dʹune procédure PL/SQL, supprimer  les ventes faites à  ʹsergeʹ et qui sont inscrites dans la relation Ventes ( BD1).  9‐ Formuler un curseur PL/SQL qui donne  le matricule des transporteurs qui nʹont pas de stocks de pièces de rechange (BD2).   *  Utiliser la base de données BD3 pour répondre aux questions suivantes. 10‐  Ajouter  au  moyen  dʹune  procédure  PL/SQL,  20  000  tuples  dans  une  relation EmplListe dont  le schéma est  identique à celui de Empl. Les données ajoutées doivent être  conformes  au  type  utilisé  pour  les  attributs.  Chaque  tuple  doit  avoir  une  clé différente  et un nom  fictif  (pas nécessairement  significatif) qui peut  être  formé par  la concaténation du numéro de lʹemployé et dʹun nom répétitif quelconque. Les employés peuvent partager  le même  taux horaire. Le numéro de  lʹemployé est généré au moyen dʹun  compteur  initialisé  au départ  à  10  et  augmenté  progressivement  à  lʹintérieur de lʹitération PL/SQL.   11‐ Créer  un  index,  nom_idx,  avec  le  nom  de  lʹemployé.  Effectuer  une  recherche  de quelques noms dʹemployés et noter le temps de recherche. Supprimer lʹindex et effectuer à nouveau  la  recherche  avec  les mêmes  employés. Notez‐vous une différence dans  le temps de réponse?  12‐  Formuler  quelques  requêtes  et  utiliser  la  commande  EXPLAIN  PLAN  pour  faire afficher le plan dʹexécution de la requête traitée avec et sans index. Noter les différences dans le plan dʹexécution généré par le module dʹoptimisation.   13‐ Supprimer les 20 000 tuples ajoutés dans la relation EmplListe.  14‐ Développer un petit schéma de la base relationnelle avec des données hiérarchiques significatives. Par exemple, une relation qui représenterait le nas des abonnés successifs qui  ont  eu  un  même  indicatif  téléphonique  :  Abonne  (indicatif,  abonne_precedent, abonne_courant,  date_abonne_courant).  Formuler  une  requête  hiérarchique  pour afficher, depuis une date précise, les abonnés successifs dʹun indicatif particulier. 

Page 201: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

201

 Répondre  aux  questions  ci‐dessous  en utilisant,  sʹil  y  a  lieu,  le  schéma de  la  base de données BD3, Dotation des ressources humaines. Le schéma de cette base est le suivant :                             

Empl (noEmpl*, nom, tauxH)     Postes (noPoste*, description) Assignations (noPoste*, noEmpl*, debut, quart) 

N.B. Lʹattribut debut  est de type Date.                           15‐ Afficher  le nom des employés et  la date du début de  leur assignation  (mandat de travail) aux projets qui débutent après le 10 janvier 1992.  16‐ Augmenter le taux horaire de tous les employés de 10 %.  17‐ Lister le nom des mécaniciens par ordre alphabétique descendant.  18‐ Afficher la moyenne du taux horaire pour les employés qui travaillent la nuit.   19‐ Modifier la description du poste ʹj12ʹ pour celui de chef.  20‐ Ajouter une colonne à la table Employe, soit l’attribut diplôme du type char(20).  21‐ Lister le contenu de la table Employe et ensuite attribuer le diplôme  ‘dec’ (diplôme dʹétudes  collégiales)  à  tous  les  employés.  Afficher  son  nouveau  schéma  de relation(table).  22‐  Créer    une  vue  Personnel_V1  avec  la  table  des  employés.  Elle  est  composée  du numéro et du nom des employés dont le no‐empl est supérieur à la série ʹP400ʹ.  23‐ Lister les employés de la série P400 en ordre alphabétique descendant en utilisant la vue relationnelle Personnel_V1.  24‐ Ajouter une nouvelle employée, Megy Ryan, P600, à la liste des employés et lister la table des employés.  25‐ Afficher pour chaque matricule, le numéro de poste et la date du début.   26‐  Créer  une  vue  V1992  pour  afficher  les  attributs  nom  et  noPoste  des  employés embauchés depuis le 1 février 1992.  27‐ Formuler les ordres DML pour insérer lʹemployé ʹBeaumontʹ, embauché depuis le 12 janvier  1988  et  qui  travaille  le  soir.  Il  titularise  le  poste  ʹj75ʹ  et,  à  l’instar  des  autres employés, son taux horaire est celui prévu par la convention collective, soit 15.00 $. 

Page 202: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

202

 28‐  Expliquer  pourquoi  il  est  possible  dʹinsérer,  par  lʹentremise  de  la  vue V1992,  les informations concernant  lʹemployé  ʹBeaumontʹ ? Est‐il possible de relire  le  tuple  inséré par lʹentremise de la même vue ?  29‐ Modifier la vue V1992 pour interdire lʹinsertion de tout employé embauché après le 1 février.  

Page 203: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique  et de génie  logiciel, Faculté des  sciences  et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

203

   INDEX 

Activation dʹun trigger, 181 ADD_MONTHS (d, n), 68 ALL, 52, 79 ALTER PROFILE, 196 ALTER TABLE, 85 ALTER TABLE, 104 ALTER TRIGGER, 191 ANY, 52 AVG(), 80 

B*‐arbre, 19 B*‐arbre, 125 B*‐arbre, 135 B‐arbre, 133 B‐arbre, 16 base de données réactive, 176 BD1, 21 BD2, 22 BD3, 23 BEGIN, 170 bloc anonyme, 170 bloc PL/SQL, 171 boucle FOR, 173 

CASCADE, 30, 157 CAST, 46 CHANGE, 106 CHECK, 197 CHECK OPTION, 157 clé étrangère, 146 clé étrangère, 28 clés étrangères, 143 cluster, 148 Cluster avec Hashing explicite, 152 Cluster indexé, 152 

clustering index, 134 COALESCE(), 77 COLUMN, 106 COMMIT, 192 comptes‐utilisateurs, 194 concaténation, 64 Condition, 35 conversion des types, 71 conversions automatiques, 47 create [unique] index, 137 CREATE CLUSTER, 151 CREATE FORCE  VIEW, 155 CREATE INDEX, 134 CREATE INDEX BITMAP, 136 Create MATERIALIZED, 163 CREATE OR REPLACE view, 154 CREATE PROFILE, 196 CREATE ROLE, 198 CREATE SEQUENCE, 188 CREATE SESSION, 195 CREATE SYNONYM, 193 CREATE TABLE, 26, 103, 104 CREATE TABLESPACE, 20 CREATE TRIGGER, 178 create unique index, 139 CREATE USER, 194 Création des vues avec SQL, 164 Création dʹune table et le typage des attributs, 24 

data wharehouse, 135 Date par défaut, 70 DB2‐V2, 176 DECLARE, 170 DECODE(), 76 définition dʹun trigger de BD, 190 DELETE FROM, 100 Densité de lʹ index, 133 

Page 204: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique et de génie  logiciel, Faculté des  sciences et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

204

DESCRIBE, 102 dictionnaire de données, 102 Différence, 99 Directives de SQL, 106 DISABLE, 146 DISTINCT, 79 Division relationnelle, 87 DROP TABLE, 105 DUAL, 63 

échec dʹun trigger, 179 EDIT, 107 éditeur de ligne., 106 EXCEPTION, 170 exceptions, 174 Exercices, 111, 199 Exercices résolus, 108 Expression de table, 51 Expression de table partagée (voir DB2), 56 

Expression incluant un appel de fonction, 44 

Expression incluant une structure CASE, 45 

expressions régulières, 37 

Fonction dʹutilisateur, 74 fonctions scalaires, 61 Fonctions SQL, 61 Fonctions SQL dʹagrégation, 79 Formulation du GROUP BY avec une fonction, 82 

Fouille hiérarchique, 57 Fragmentation des grands tuples et chaînage, 14 

Générateur, 187 GET, 107 GRANT OPTION, 197 GRANT SELECT, 197 

GROUP BY, 83 Groupement et vue relationnelle, 83 

hashing, 132 HAVING count, 83 

index, 138 Index, 130 Index à clés transformées, 134 Index bitmap, 135 index composé, 137 index concaténé, 141 Index inversé, 135 Indexation, 125, 143, 154, 168, 169, 176, 187, 193, 194, 198, 199 

INFORMIX, 176 INSERT, 32, 99 INSERT INTO, 100 Instead Of, 186 INSTR(ch1,ch2,n,[i]), 64 Intersection, 98 

Jointure droite, 96 Jointure externe gauche, 95 Jointure naturelle, 85 Jointure thêta, 86 

LAST_DAY (d), 68 LENGTH (ch1), 65 LIST, 107 LTRIM(ch1[,setcar]), 64 

Matérialisation dʹune vue, 161 max(), 80 Migration des tuples, 14 min(), 80 Mise à jour, 101 

Page 205: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique et de génie  logiciel, Faculté des  sciences et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

205

Mise à jour, 99 mise à jour  et vue, 158 Mise à jour à travers une vue, 163 Modèle dʹexécution, 32 modèle dʹexécution  trigger;, 181 MONTHS_BETWEEN (d1, d2), 68 

NEW, 181 NO_DATA_FOUND, 175 NULLIF(), 79 NVL(), 76 

optimiseur, 139 Optimiseur et index, 142 Oracle, 176 ORDER BY, 46 

Page insérable, 13 PCTFREE, 12, 26, 144 PCTUSED, 12, 26 Performance, 145 Pertinence de lʹindexation, 147 PL/SQL, 169 Placement des données, 15 Placement par hashing (hash clustering), 150 

placement regroupé des tuples, 133 Prédicat IS NUL, 41 Prédicats spéciaux, 190 PRIMARY KEY, 143 privilège système, 190 profil, 196 PROFIL, 196 programme PL/SQL, 170 

RAISE_APPLICATION_ERROR( ), 182 Récursivité, 60 Récursivité des fonctions, 76 

refresh, 163 Regroupement inconditionnel des tuples, 81 

REPLACE, 83 REPLACE (ch1, si, par), 65 REPLACE()., 64 Requête corrélée, 54 Requête SQL, 31 RESTRICT, 157 REVOKE SELECT, 158 Rôle, 198 Rôle par défaut, 198 ROWID, 17 RTRIM(ch1[,setcar]), 64 RUN, 107 

SAVE, 107 Schéma de la BD, 24 SELECT DISTINCT, 39 Sélection, 35 SET  PAGESIZE, 106 SET BUFFER, 106 SET PAUSE, 106 signature Soundex, 66 SING(n), 77 snapshot, 168 Soundex, 66 SOUNDEX (ch1), 64 SPOOL, 106 SPOOL OFF, 106 SQL, 5 SQL*Plus, 6 SQLPLUS, 7 star schema, 135 START, 107 Stockage des triggers, 189 Structure générale de page, 11 SUBSTR (ch1, m, n), 64 Suppression, 100 Suppression d’un index, 140 Suppression de la vue, 157 Suppression du temps, 72 

Page 206: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique et de génie  logiciel, Faculté des  sciences et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

206

SYBASE, 176 syntaxe des variables, 172 SYSDATE, 68, 73 

table en mutation, 184 TO_CHAR(), 62 TO_CHAR(d, masque[, nlsp])), 71 TO_DATE(ch1,masque[,nlsp])), 71 TO_NUMBER(ch1,masque[,nlsp]), 71 TOO_MANY_ROWS, 175 transaction, 21, 101 TRANSLATE(ch1,s,c), 64 Tri, 46 trigger, 177 Trigger de tuple, 179 Trigger dʹénoncé, 179 Trigger Instead Of, 186 TRUNC(), 25, 62, 73 TRUNCATE TABLE, 100 TRUNCATE TABLE, 100 Types internes dʹOracle, 25 

Union, 98 UPDATE, 101 utilisation des index, 140 

valeurs dupliquées, 130 Variable de table, 155 variable hôte, 173 Variables de corrélation, 181 vue et droits dʹaccès;Ainsi, un usager Paul qui nʹest pas le propriétaire de la vue peut cependant lʹutiliser pour avoir accès aux ventes enregistrées après le 1 janvier 1995. Il doit auparavant  obtenir du propriétaire de la table le droit de sélection que ce dernier formulera ainsi:, 156 

vue matérialisée, 169 vue relationnelle, 154 

with grant option, 99 WITH GRANT OPTION, 197 

                                                       Références   1 COREY, M., ABBEY, M., DECHICHIO, D.  J., Tuning Oracle Version 7.x, Oracle Press, ISBN‐0‐07‐881181‐3, 1995. 2  RODGERS,  U.,  ORACLE,  A  Database  Developer’s  Guide,  Yourdon  Press  Computing Series, ISBN 0‐13‐488925‐8, 1991, 250p. 3 MIRANDA, Serge, L’art des bases de données; comprendre et évaluer SQL, Eyrolles, vol., 1990.   4 DATE, C. J., A  Guide to the SQL Standard, Addison‐Wesley, 1988, ISBN 0‐201‐05777‐8. 5 LUSARDI, F., The Database Expert Guide to SQL, McGraw‐Hill, 1988, ISBN 0‐07‐039002‐9 6  ORACLE  CORP.,  SQL*Plus  User’s  Guide  and  Reference,  version  3.1,  Cooperative Development Environment, ISBN‐5142‐31‐1192, 1992. 7 KOCH, George, ORACLE,  the Complete Reference, version 5 and 6, Osborne McGraw‐Hill, 1991, ISBN 0‐07‐881635‐1.  8 LONEY, K., ORACLE Data Handbook, Osborne‐Oracle Press, 1994, ISBN 0‐07‐881182‐1. 

Page 207: Architectures, modèles et langages de donnéesagamache/pageperso/LivreBDPDF/Chapitre78.pdf · 7.1 Langage SQL et l’exploitation de la base de données Le langage de données SQL

Chapitre 8 Indexation et vue relationnelle 

© André Gamache, Département d’informatique et de génie  logiciel, Faculté des  sciences et de génie, Université Laval, Québec, Qc, Canada, G1K 7P4. Courriel : [email protected]   

207

                                                                                                                                                              9 ODELL, Margaret K., Robert C. Russell, U. S. Patents 1261167, 1918. 10 RUSSELL, R., U.S. Patents 1435663, 1922. 11 BAIRD, Gus,  référence  citée par  Joe CELKO dans  son  livre  SQL  avancé publié par Thomson, 1997 12 PHILIPS, Laurence, Metaphone, Computer Language, 1990. 13  ORACLE,  CORP.,  Oracle7,  SQL  Language  Reference  Manual,  Cooperative  Server Technology, 1992, ISBN 778‐70‐1292.. 14  CORRIGAN,  Peter, GURRY, M., ORACLE  Performance  Tuning, O’Reilly Associates, 1994, ISBN 1‐56592‐048‐1. 15  DATE,  C.  J.,  An  Introduction  to  Database  Systems,  6ed.  edition,  The  Systems Programming Series, Addison‐Wesley, 1995, ISBN 0‐201‐54329‐X. 16 MAREE, C., LEDANT, G., SQL 2; Initiation et programmation, Armand Colin, 2e édition, ISBN 2‐200‐21411‐1, 1994.  17GAMACHE,  A.  Introduction  au  langage  PL/SQL,  Département  dʹinformatique, Université Laval, 1997, 63p. (Disponible aussi sur le WEB).