Sunteți pe pagina 1din 74

02/10/2018 BASE DE DONNEES

AVANCEES

BIYIHA NLEND JEAN AYMAR


ISTAG
ISTAG
COURS DE BASE DE DONNEES AVANCEES

LICENCE PROFESSIONNELLE

BIYIHA NLEND JEAN AYMAR

699 25 83 95 / 676 67 65 23

aymarcm@yahoo.fr

1
SOMMAIRE
SOMMAIRE ................................................................................................................................................................2
CHAPITRE 0 : RAPPELS ..........................................................................................................................................3
I. QUELQUES NOTIONS.......................................................................................................................................3
II. EXPOSES ..........................................................................................................................................................3
CHAPITRE I : INTRODUCTION SUR LE SGBD ORACLE ........................................................................................4
I. RAPPELS SUR LES SGBD .................................................................................................................................4
II. BASE DE DONNEES ORACLE ET STANDARDS SQL .......................................................................................6
III. ARCHITECTURE D’UN SERVEUR ORACLE .................................................................................................11
IV. LE DICTIONNAIRE DE DONNEES ................................................................................................................16
V. PROCEDURE DE CREATION D’UNE LA BASE DE DONNNEES ...................................................................19
CHAPITRE II : LES OBJETS DE LA BASES DE DONNEES ORACLE .....................................................................20
I. TABLESPACE ..................................................................................................................................................20
II. UTILISATEURS ..............................................................................................................................................24
III. TABLES .........................................................................................................................................................25
IV. CONTRAINTES D’INTEGRITE......................................................................................................................34
V. VUES ..............................................................................................................................................................38
VI. INDEX ...........................................................................................................................................................40
VII. DECLENCHEURS (TRIGGERS)....................................................................................................................42
VIII. SEQUENCES ...............................................................................................................................................43
IX. PRIVILEGES ..................................................................................................................................................44
CHAPITRE III : LE LANGAGE ORACLE PL SQL. ..................................................................................................49
I. INTRODUCTION .............................................................................................................................................49
II. LES INSTRUCTIONS DE BASES.....................................................................................................................53
III. LES TABLEAUX.............................................................................................................................................57
IV. STRUCTURES ...............................................................................................................................................59
V. TABLES ET STRUCTURES ............................................................................................................................59
VI. TRANSACTIONS ...........................................................................................................................................60
VII. EXCEPTIONS ...............................................................................................................................................60
VIII. SOUS-PROGRAMMES .................................................................................................................................63
IX. 1.6 CURSEURS .............................................................................................................................................64
X. CURSEURS PARAMETRES .............................................................................................................................65
XI. TRIGGERS.....................................................................................................................................................67
XII. PACKAGES...................................................................................................................................................72

2
CHAPITRE 0 : RAPPELS
I. QUELQUES NOTIONS
1. Différence en un SGBD et une BD
2. Exemple de SGBD
3. LDD (CREATE, ALTER, DROP)
4. LMD (INSERT, UPDATE, DELETE)
5. Formes normales
6. Modèle Conceptuel de Données
7. Modèle Logique de Données
8. Modèle Physique de Données
9. Exemple d’Application dans le cas d’une gestion de vol

II. EXPOSES
1. Benchmarks pour les SGBDs
2. Systèmes d’information décisionnels et les Bases de données décisionnelles
3. Les SGBDs Géographiques
4. Bases de Données Hétérogènes
5. les SGBD Orientés Objet
6. Les SGBD Parallèles
7. Répartition, Réplication, Nomadisme, Hétérogénéité dans les SGBDs
8. Les bases de données et XML

3
CHAPITRE I : INTRODUCTION SUR LE SGBD ORACLE
I. RAPPELS SUR LES SGBD
I.1. Qu'est-ce qu'une base de données?
Une base de données (son abréviation est BD, en anglais DB, database) est une entité
dans laquelle il est possible de stocker des données de façon structurée et avec le moins de
redondance possible. Ces données doivent pouvoir être utilisées par des programmes, par des
utilisateurs différents. Ainsi, la notion de base de données est généralement couplée à celle
de réseau, afin de pouvoir mettre en commun ces informations, d'où le nom de base. On parle
généralement de système d'information pour désigner toute la structure regroupant les
moyens mis en place pour pouvoir partager des données.
Afin de pouvoir contrôler les données ainsi que les utilisateurs, le besoin d'un système
de gestion s'est vite fait ressentir. La gestion de la base de données se fait grâce à un système
appelé SGBD (système de gestion de bases de données) ou en anglais DBMS (Database
management system). Le SGBD est un ensemble de services (applications logicielles)
permettant de gérer les bases de données, c'est-à-dire:
• permettre l'accès aux données de façon simple
• autoriser un accès aux informations à de multiples utilisateurs
• manipuler les données présentes dans la base de données (insertion, suppression,
modification).

I.2. Les générations des SGBD


Les SGBD ont vu le jour dans les années 60 pour gérer d’importants volumes de données
de gestion. Il s’agissait de systèmes propriétaires (appartenant à une marque d’ordinateur,
par exemple IBM [International Buisinesss Machine -Big Blue]), sur grands systèmes [main
frame] conçus selon un schéma d’organisation «hiérarchique» ou «réseau».
En 1970, Codd, chercheur chez IBM, proposa le modèle relationnel. Ce modèle
conceptuel constitue un progrès important car il repose sur une représentation unifiée de
l’information sous forme de tables. Il dispose d’un fondement mathématique solide avec
l’algèbre relationnelle (opérations ensemblistes). Il permet une plus grande indépendance
entre les applications, les données et le support physique [hardware et software]. Il propose
une démarche cohérente et unifiée pour la description (Langage de Description des Données
- LDD) et pour l’interrogation (Langage de Manipulation des Données - LMD). Enfin le modèle
relationnel supporte le langage SQL [Sequel : Standard English Query Language] aussi bien
comme LDD que LMD, basé lui-aussi sur l’algèbre relationnelle.
Georges GARDARIN, une personnalité ressource de théories des bases de données
décline l’historique des SGBD en quatre temps calqués sur les différents modèles révélés au
fil des années. Il distingue ainsi les Modèles Patrimoniaux, les Modèles Relationnels, les
modèles Objet-Relationnels et les Models XML. L’apparition de chacun de ces modèles a
donné naissance à une famille de SGBD. C’est ainsi qu’on a connu les SGBD réseaux et
hiérarchiques pour les modèles patrimoniaux, les SGBD Relationnels pour le Modèle
Relationnel, les SGBD Objet-Relationnels pour le modèle Objet-relationnel et les SGBD XML
pour le modèle XML.
Le tableau suivant apportera quelques informations supplémentaires à ce sujet.

4
Modèle Famille SGBD Langage utilisé Constructeur SGBD Avantages Inconvenients
Réseau Codasyl DML • Univers de • Evolution difficile du schéma
Patrimoniaux Hiérarchique IMS DL1 modélisation riche • Manque d’indépendance entre
• Accès rapide programme et données
Relationnel par E. F CODD • SQL1 en 86 • Oracle depuis 1977 • Modèle simple et • Ne supporte pas les données
en 1970 avec ACM • SQL2 en 92 • Ingres depuis 1980 facile complexes 1NF
(Association of Computer • SQL2 un langage • Peu de sémantique
Machinery) puissant
Relationnel • Théorie relationnelle
et logique bien assise
• Standards existants
• Support de gestion et
de décision
Objet-Relationnel SQL3 • Informix • Garde les atouts du • Modèle complexe
• Oracle Modèle R • Langage complexe
• Sybase • Modèle dérivé du GL • Types de données non
• IBM/DB2 • Modèle extensible standardisés
Objet-Relationnel
• CA-OpenIngres • Standards existents
• SQL Server
• Versant

XML • SQL/XML • Oracle • XQuery un langage


• XQuery puissant
• OWL • Types de données
extensibles
XML
• XML est partout
• Standrad émergeant
pour l’intégration
des données

5
II. BASE DE DONNEES ORACLE ET STANDARDS SQL
Le concept du modèle relationnel est apparu pour la première fois grâce aux travaux
du Dr E. F Codd qui faisait des recherches devant permettre le partage des données en 1970.
Il publia alors une revue intitulée : "A Relational Model of Data for Large Shared Data Banks"
dans un magazine de ACM (Association of Computer Machinery). Très vite ce modèle a été
adopté pour les RGBD relationnels. C’est ainsi que très tôt IBM conçu un premier langage
(SEQUEL) pour implémenter ce concept. Peu après ce langage fut remplacé par SQL
(Structured Query Language) qui lui a été accepté largement comme langage standard des
SGBDR. En 1979, une société ambitieuse au nom de Relational Software, Inc. Proposa au
public le marché le premier SGBD commercial ; cette société s’appellera plus tard Oracle.
Au jour d’aujourd’hui le langage SQL a traversé quatre mouvements de normalisation
respectivement en 1986, 1992, 1999 et 2003. La constructeur Oracle a largement contribué
dans les travaux de normalisation de ce langage dans les rangs des comités ANSI et ISO. De
même, il s’est déployé à arrimer ses produits à la norme. La version 9i d’Oracle a un bon
niveau de conformité avec le standard SQL2 (1992) et niveau moyen de conformité avec la
norme SQL3 (1999) ce d’autant plus qu’à cette date la norme faisait son premier âge.

II.1. Les fonctionnalités d'Oracle


Oracle est un SGBD permettant d'assurer :
• La définition et la manipulation des données
• La cohérence des données
• La confidentialité des données
• L'intégrité des données
• La sauvegarde et la restauration des données
• La gestion des accès concurrents

II.2. Les composants d'Oracle


Outre la base de données, la solution Oracle est un véritable environnement de travail
constitué de nombreux logiciels permettant notamment une administration graphique
d'Oracle, de s'interfacer avec des produits divers et d'assistants de création de bases de
données et de configuration de celles-ci.
On peut classer les outils d'Oracle selon diverses catégories :
• Les outils d'administration
• Les outils de développement
• Les outils de communication
• Les outils de génie logiciel
• Les outils d'aide à la décision

II.3. Les outils d'administration d'Oracle


Oracle est fourni avec de nombreux outils permettant de simplifier l'administration de
la base de données. Parmi ces outils, les plus connus sont :
• Oracle Manager (SQL*DBA)
• NetWork Manager
• Oracle Enterprise Manager
• Import/Export : un outil permettant d'échanger des données entre deux bases Oracle

II.4. Notion d’identificateurs


Dans une base de données Oracle, on distingue deux types d’objet : les objets reliés à
un schéma (schema objects) et les objets indépendants d’un quelconque schéma
(nonschema objects). Oracle définit un ensemble de règles de nomenclature des objets
appartenant à même schéma.

6
II.5. Nomenclature des objets de la base de données:
Il existe deux conventions de nomenclature des identificateurs : les identificateurs
sans doubles côtes et les identificateurs entourés des doubles côtes. Lorsqu’on crée un
objet par un identificateur avec des doubles côtes, celui-ci doit toujours être référencé avec
leurs côtes en respectant la casse. Par contre lorsqu’on définit des identifiants sans les côtes,
on est libre de les référencer avec ou sans celles-ci moyennant le respect de quelques règles.
Il faut du moins noter que quelques objets de la base de données ne peuvent être désignés
par des identifiants entourés de doubles côtes. Il s’agit notamment des liens des bases de
données logins des utilisateurs et de leurs mots de passe. Voici les principales règles des
identifiants :
• En fonction des plateformes Oracle recommande d’utiles les caractères ASCII standard
en raison de leur bonne compatibilité.
• Un identifiant peut comporter n’importe quel caractère alphanumérique y compris les
caractères suivants : #, $, _. Certains objets tels que les liens de base de données
admettent également les symboles suivants : @, et..
• Ne jamais commencer un identifiant par la chaîne (sys).
• Les identifiants sans côtes doivent forcement commencer par un caractère
alphabétique sans espace; cette contrainte n’est pas valable pour les identifiants avec
doubles côtes.
• Longueur : 1o à 30o (exceptés les noms des bases de données et les noms des liens de
bases de données qui ont respectivement un maximum de 8o et de 128o
• Les identifiants entourés des doubles côtes peuvent être des mots réservés Oracle
contrairement aux identifiants sans côtes (ceci n’est pas recommandé !).
• Les identifiants entourés de doubles côtes sont sensitifs à la casse contrairement aux
identifiants sans doubles côtes.
• A l’intérieur d’un espace de nom deux objets ne peuvent avoir le même nom ou
identifiant.

Un espace de nom est un annuaire propre à chaque schéma de la base de données qui
permet la résolution des noms des différents objets stockés dans ce schéma.

II.6. Résolution des noms d’objets.


• Comment accéder à un objet de son schéma ? Il suffit de fournir son nom.
Exemple : SELECT * FROM emp ;
• Comment accéder à un objet en dehors de son schéma ? Pour accéder à un objet
hors de son schéma, il faut obligatoirement le préfixer du nom de ce schéma.
Exemple: SELECT * FROM scott.emp;
• Comment accéder à un objet d’une autre base de données ?
Syntaxe : [Schéma.]objet@lien_de_labd
Remarque : Au vue de ce qui précède, on peut en déduire que la syntaxe de
désignation d’un objet sur Oracle est la suivante : [Schéma.]Objet[@Lienbd]. Il faut
également noter que certains objets sont contenus par d’autres. On peut citer par exemple
les colonnes d’une table. Pour les référencer, la règle est la suivante : Table.Colonne.

7
Objets liés à un schéma Objets indépendants d’un schéma
 Partagent un même espace de nom (Possède chacun son espace de nom) :
- Tables, Vues, - Rôles,
- Séquences, - Synonymes Publics,
- Synonymes Privés, - Liens Publics Base de Données,
- Procédures Indépendantes, - Espace de Table,
- Fonctions Stockées Indépendantes, - Segments d’Annulation,
- Packages, - Profils,
- Vues Matérialisées, - Fichiers de Paramètres (PFILEs),
- Types Utilisateurs. - Fichiers de Paramètres côté serveur
 Possède chacun son espace de nom (SPFILEs)
- Index, Contraintes, Dimensions,
- Clusters, Déclencheurs,
- Liens Privés de Bases de Données.

II.7. Les types de données


Chaque information manipulée en informatique est liée à un type de données. Ce type
de données désigne un ensemble de valeurs que peut prendre une donnée. Oracle admet les
types de données natifs et quelques types du standard SQL. En plus de ces deux types de
données, Oracle permet aux développeurs définir des types personnalisés. Il est également
capable de reconnaître les types d’autres environnements de développement tels que Java,
C, C++… Cependant pour se faire il faudrait lui associer un moteur d’exécution
(précompilateur). En fin Oracle supporte également les types de données XML.

II.8. Types natifs Oracle


Ces types de données sont suffisants pour définir n’importe quelle valeur sur Oracle.
C’est pourquoi le constructeur conseille vivement leur usage afin de tirer véritablement
profit de son système. Cependant aux dépends de quelques conversions, Oracle supporte
également les types de données ANSI, ceux de DB2 et de SQL/DS auxquels on peut recourir
pour une raison ou pour une autre.

Types de données natifs ORACLE


Large
Character Number Long & Row Datetime Object Rowid
NUMBER(p, s)
CHAR(size [, byte|char]) LONG DATE BFILE ROWID
1<=p<=38, -
max size=2000 max=2G [01/01/4712 BC, 31/12/9999 AC] max=G max=
84<=s<=127
LONG LONG RAW BLOB UROWID(n)
INTERVAL DAY (dp) to secnd(fsp)
max= 2G max=2G max=4G max=
NCHAR(size) RAW(size) CLOB
INTERVAL YEAR (yp) to month
max size=2000 max=2000 max=4G
NVARCHAR(size) NCLOB
TIMESTAMP(sp) [with [local]time zone]
max size=4000 max=4G
VARCHAR2(size [,
byte|char])
max size=4000

Equivalence de Type de données SQL


ANSI ORACLE
CHARACTER(n) CHAR(n)
CHAR(n)
CHARACTER VARYING(n) VARCHAR2(n)
CHAR VARYING(n)
NATIONAL CHARACTER(n) NCHAR(n)
NATIONAL CHAR(n)
8
NCHAR(n)
NATIONAL CHARACTER VARYING(n) NVARCHAR2(n)
NATIONAL CHAR VARYING(n)
NCHAR VARYING(n)
NUMERIC(p,s) NUMBER(p,s)
DECIMAL(p,s)
INTEGER NUMBER(38)
INT
SMALLINT
FLOAT(b) NUMBER
DOUBLE PRECISION
REAL

II.9. Les Opérateurs et expressions


Une expression est une combinaison d’une ou plusieurs valeurs, opérateurs ou de
fonctions SQL.
Au cours de l’exécution d’une expression Oracle exécute les opérations suivant un
ordre de priorité établie. La priorité sur les opérateurs distingue deux cas :
• 1er cas : les opérateurs sont de niveaux de priorités différentes. Dans ce cas
Oracle évalue d’abord les opérateurs de plus haute priorité et en fin ceux de
plus faible priorité.
• 2e cas : les opérateurs sont de niveaux de priorités égales. Dans ce cas Oracle
évalue l’expression de la gauche vers la droite.

OPERATEURS OPERATIONS Les Opérateurs Logiques


+, -, PRIOR Identité, Négation, Exponentiation
ARITHMETIQUES,
DATES, CHAINES

*, / Multiplication, Division AND TRUE FALSE NULL


Fortes Priorités

+, -, || Addition, Soustraction, Concatenation TRUE TRUE FALSE NULL


FALSE FALSE FALSE FALSE
NULL NULL FALSE NULL

= , != , < , > , <= , >= Egalité et Inégalité OR TRUE FALSE NULL


COMPARAISION

< [ALL|ANY|SOME] …. Egalité et Inégalité composées TRUE TRUE TRUE TRUE


Nullité FALSE TRUE FALSE NULL
….

IS NULL, [NOT] LIKE, Sous Chaine NULL TRUE NULL NULL


[NOT] BETWEEN,
[NOT] IN Iintervalle
Appartient à une liste NOT
NOT Negation, Exponentiel FALSE TRUE
LOGIQUES

AND Conjonction TRUE FALSE


,,,,

OR Disjonction NULL NULL

INTERSECT Intersection Note :


Faibles Priorités

ENSEMBLISTES

UNION Union V=Valeur Vraie,


MINUS Différence F=Valeur Fausse,
I=Valeur Inconnue ou absence
d’information.

Remarques : pour les opérateurs Arithmétiques


Quel que soit l’arité de l’opérateur, dès que l’un de ses opérandes est vaut « null »,
alors le résultat vaut « null ». Seul l’opérateur de concaténation déroge à cette règle. Ainsi
pour toute valeur numérique X, on a les résultats suivants :
• X+null=null
• X*null=null
• ‘banane’|| null=‘banane’

9
II.10. Les Fonctions
Les fonctions employées sur Oracle sont soit des fonctions SQL soit des fonctions
PL/SQL, soit encore des fonctions définies par l’utilisateur. Les fonctions SQL sont des
fonctions définies par Oracle et mises à la disposition des utilisateurs qui n’a pour seul effort
que les appeler. Par contre, les fonctions utilisateurs sont des fonctions que le développeur
implémente par exemple avec du PLSQL ou du Java qui sont des langages pour lesquels il
existe des moteurs d’exécution construits pour Oracle.
Nous nous intéresserons particulièrement aux fonctions SQL. A la base des fonctions
SQL, on distinguera plusieurs familles de fonctions SQL : les fonctions « single Row » (un
enregistrement à la fois), les fonctions d’agrégat, les fonctions analytiques. Nous verrons un
certain nombre de ces fonctions au fur et à mesure que le programme évolue.

QUELQUES FONCTIONS
Chaines
Travaillent beaucoup plus sur les
Dates Numériques
caractères ascii standard et sont
pour la plupart sensibles à la casse

add_months(dte, n) chr(n) ceil(n) : +ptt entier >= n


current_date initcap(ch) floor(n) : +grd entier <=n
current_timestamp[(precision)] instr(ch, ssch [, pos] [, occ] ) *** round(m,n) : Arrondi à 10-n
extract(motif from exp) lpad(ch, lg [,ch1]) sign(n)
last_day(dte) ltrim(ch, ch1) to_number(che [, fmt] [, nls_param])
local_timestamp replace(ch, chout [, chin]) *** trunc(m,n) : Troncature à 10-n
moths_between(d1, d2) // d1> d2: + / - rpad(ch, lg [,ch1]) vsize(exp) : |exp| en Octet
next_day(dte, week_day) rtrim(ch, ch1)
round(dte [,fmt]) sbstr(ch, pos [, lg])
Sysdate to_char(date|nbr [,fmt])
trunc(dte [,fmt]) trim([leading|trailing|both] tch from ch)
to_date(ch [,fmt] [, nls_param])
Non typées CASE
coallesce(exp1, ,,, exprn) forme de correspondance
decode(exp, V1, T1, .., Vn, Tn, Dft) select case exp
nullif(exp1, exp2) when V1 then T1,,,
nvl(exp, exp1) when Vn then Tn
nvl2(exp, exp1, exp2)
[else] Tdft end
sys_context(name_space, param [, lg] forme de prédicat
Uid select case when C1 then T1
User ,,,
Userenv when Cn then Tn
[else] Tdft end

II.11. Les instructions SQL


Comme nous l’avons vu plus haut, Oracle est conforme à la norme SQL-92 (SQL2) ainsi
qu’à SQL-99 (SQL3). Cependant, Oracle en s’appropriant les instructions du SQL standard les
a étendues pour mieux les adapter à ses concepts. Le jeu d’instruction d’Oracle est assez
dense et vairé selon l’activité entreprise. Il se décompose en six familles d’instructions ou
langages:
• Data Definition Language : DDL (Langage de Définition des Données)
• Data Manipulation Language : DML (Langage de Manipulation des Données)
• Transaction Control Statements : TCS (Instruction de contrôle des Transactions)
• Session Control Statement (Instructions de Contrôle de Session)
• System Control Statement (Instructions de Contrôle de Système)
10
• Embedded SQL Statements (Instruction incorporée)
Type Instruction Action
DDL: CREATE Création d’un objet utilisateur
Data Definition ALTER Modification d’un objet utilisateur
Language DROP Destruction d’un objet utilisateur
Statements RENAME Renommage d’un objet de la BD
TRUNCATE Réinitialisation d’un objet
GRANT Attribution de privilèges
REVOKE Retrait de privilèges
AUDIT Audit des opérations
NOAUDIT
DML: SELECT Sélection de données
Data Manipulation INSERT Insertion de données
Language MERGE Mise à jour conditionnelle de données
UPDATE Mise à jour de données
DELETE Suppression de données
LOCK TABLE Verrouillage d’une table
EXPLAIN PLAN Plan d’Exécution d’une Instruction
Transaction Control COMMIT Validation de la Transaction.
ROLLBACK Annulation de la Transaction.
SAVEPOINT Point de Reprise.
SET TRANSACTION Début de Transaction.
Session Control SET ROLE Activation/Désactivation de Rôle.
Statement ALTER SESSION Ajustement des paramètres de session.

System Control ALTER SYSTEM Ajustement des paramètres de l’instance (le serveur).
Statement
Embedded SQL DDL, DML ou TCS incorporée dans un langage
Statements procédural.

III. ARCHITECTURE D’UN SERVEUR ORACLE

Lorsqu’on parle d’architecture d’un serveur oracle, on aimerait connaître deux


choses :
• Comment les processus client se connectent au serveur de bases de données : ce que
l’on pourrait appeler l’architecture de l’application,
• Quelle configuration de processus serveur est mise en place ? Ceci peut être appelé
architecture des processus serveur.

III.1. Connexion a un serveur Oracle


Pour avoir accès aux données, les utilisateurs doivent tout d'abord se connecter à un
Serveur Oracle. Il existe trois types de connexions grâce auxquelles un utilisateur peut
accéder à un Serveur Oracle :
• Connexion locale : Selon cette méthode, un utilisateur est directement connecté sur
la machine faisant office de Serveur Oracle.
• Connexion Deux Tiers : Ce type de connexion est couramment nommé "Connexion
Client Serveur", un utilisateur se connecte à partir d'une machine directement
connectée à un Serveur Oracle. Prenons l’exemple d'un utilisateur qui lance un Oracle
Forms (Front End pour consulter des bases de données Oracle à travers des
formulaires.) sur un poste client sous Windows pour accéder à un serveur Oracle
résident sur une machine Windows NT Serveur.
• Connexion Multi Tiers : Dans une architecture multi tiers, la machine de l'utilisateur
se connecte à un Serveur applicatif (Par exemple un Serveur Web) qui lui même va se
connecter au serveur Oracle pour récupérer les données issues de la base de données.
11
Lorsque qu'un utilisateur est connecté à une machine sur laquelle réside un Serveur
Oracle, deux processus sont invoqués : Le processus utilisateur et le processus serveur.

Un processus utilisateur est créé lorsqu’un outil client désirant communiquer avec le
serveur Oracle est lancé (Un outil d'administration : SQL*Plus, OEM ; une application Oracle
Forms, etc.). Un processus utilisateur est un mécanisme qui va exécuter le code d'une
application ou d'un outil Oracle.
Pour faire fonctionner un outil application tel que SQL*Plus ou des applicatifs Oracle
Forms, Oracle crée un processus utilisateur (Client). L'UPI (User Program Interface) est un
mécanisme standardisé utilisé par un processus utilisateur pour communiquer avec un
processus serveur. C'est l'UPI qui génère l'appel au serveur Oracle.
Un processus serveur est créé lorsque un utilisateur se « logue » sur le serveur en
spécifiant un nom d'utilisateur, un mot de passe et un nom de base de données. Le
processus Serveur est créé sur le serveur Oracle. Le processus serveur va permettre
l'interaction entre le processus utilisateur et le serveur Oracle en récupérant les requêtes et
en les exécutant sur les serveurs Oracle. Le processus serveur inclus l'OPI (Oracle Program
Interface) qui est utilisé pour communiquer avec la base de données Oracle.
Une connexion se définit comme le lien entre un processus utilisateur et un processus
serveur.
Si l'utilisateur se connecte localement sur le serveur, le chemin de communication est
établi via un mécanisme de communication inter processus.
Si l'utilisateur se connecte via une machine cliente, un logiciel réseau est utilisé.
Une Session quant à elle est une connexion spécifique entre un utilisateur et un serveur
Oracle est appelé. La session démarre lorsque la demande de connexion de l'utilisateur est
validée par le serveur Oracle et se termine lorsqu'il se déconnecte ou lorsqu'une fin de
connexion prématurée se produit.

12
III.2. Architecture des processus Serveur
L’on rencontre trois types de processus dans un environnement Oracle :
• les processus utilisateur (User Processes),
• les processus d’arrière plan (BackGround Processes)
• les processus serveur (Server Processes).
Le type de processus qui nous intéresse c’est bien les processus serveur. Selon la
configuration que le DBA fait de ces processus, on aboutit à une certaine architecture. Ainsi,
on pourra configurer ces processus serveur pour obtenir deux types d’architecture de
serveurs: les serveurs dédiés et les serveurs partagés.
III.2.1. Serveur dédié (Dedicated Server)
Cette configuration prévoit que le nombre de processus client ne peut excéder le
nombre de processus serveur en SGA. En d’autres termes, si tous les processus serveur
démarrés sont déjà occupés par des processus client, alors s’il advient qu’un nouveau
processus client demande une session, Oracle démarre aussi un nouveau processus serveur
dédié. On constate ainsi qu’à mesure que les processus client augmentent, les processus
serveur augmentent également. On pourrait arriver une saturation de la mémoire par un
nombre excessif de processus serveur : conséquence, il y a baisse de performance. le schéma
suivant nous présente un schéma fonctionnel entre les processus serveur et les processus
client.

13
III.2.2. Serveur Partagé (Shared Server) :
Dans cette configuration plusieurs processus client peuvent partager un même serveur
au cours de leur session. Il s’avère qu’avec un certain nombre de serveur, Oracle arrive à
gérer un grand nombre de processus client. Le petit nombre de processus serveur réduit alors
la charge de la mémoire tout en imposant un plus grand rendement aux processus serveurs,
car ils sont appelés à travailler à plein temps. Cette solution est adéquate pour les systèmes
à forte sollicitation ou les serveurs de messagerie tels que yahoo. Contemplons le schéma
précédant

III.3. Configuration de serveurs partagés


La configuration des serveurs partagés nécessite juste de positionner quelques
paramètres d’initialisation :
Paramètres Signification
DISPATCHERS Définit le nombre de serveurs partagés à lancer au
Obligatoires

démarrage de l’instance.
SHARED_SERVERS Définit le nombre de dispatchers à lancer au démarrage de
l’instance.

MAX_DISPATCHERS Nombre maximum des dispatchers.


Optionnel

MAX_SHARED_SERVERS Nombre maximum de serveurs partagés.


CIRCUITS Définit le nombre de circuits virtuels.
s

SHARED_SERVER_SESSIONS Définit le nombre de session adminissibles en mode shared


servers.
Remarque: pour que l’architecture Shared Servers fonctionne, il est nécessaire que
l’utilitaire soit installé sur la machine client, même si le client et le serveur sont sur la même
machine.

III.4. Composants d’un serveur Oracle


Au-delà de tous ces modèles d’architecture, les éléments constituant un serveur
Oracle sont quasi identiques d’un serveur à un autre. Un serveur Oracle est toujours constitué
de deux modules : un module de traitement et un module de stockage que sont
respectivement l’instance et la base de données. Le schéma ci dessus nous en fait une bonne
illustration graphique.

14
Composants d’un serveur Oracle
III.4.1. Instance Oracle

L’instance est le module de traitement des données d’un serveur Oracle. Il est lui-
même constitué de deux classes d’objet : les structures de la mémoire et les processus
d’arrière plan. La structure de mémoire d’une instance s’appelle SGA (System Global Area).
La SGA se comporte en plusieurs composants dont les principales sont présentées ci-dessus.
Paramètre
Nom Rôle
d’Initialisation
Database Buffer
DB_CACHE_SIZE cache de traitement des transactions
Cache
Obligatoires

Redo Log Buffer cache de journalisation des différentes


LOG_BUFFER
Cache transactions
Shared Pool qui est à son tour composée de la Libary Cache et
SHARED_POOL_SIZE de la Data Dictionary Cache : espace d’analyse
des instructions.
Large Pool espace réservé aux traitements particuliers :
LARGE_POOL_SIZE
Optionnels

Shared Servers, backup recovery.


Java Pool
espace réservé aux blocs de code Java.
JAVA_POOL_SIZE

Les processus d’arrière-plan qu’un serveur Oracles sont divers et jouent chacun un
rôle précis lorsqu’il a été initialisé. Cependant parmi ces processus, il y en a qui sont
indispensables. On les appelle les processus d’arrière-plan obligatoires (mandatory
background processes). Le tableau ci-dessous nous en donne la liste exhaustive de ces
processus.

15
Processus Appellation Rôle
DBWn DataBase Transfère les données traitées en mémoire pour les stocker
Writer définitivement sur les fichiers de données.
LGWR Log Copies les entrées redo dans les fichiers redo online :
obligatoires
Processus

Writer fichier journaux en cours d’utilisation.


CKPT Checkpoint Matérialise le point de reprise sur les en-têtes des fichiers
de données et les fichiers de contrôle.
PMON Process Monitor Gestionnaire des processus de l’instance.
SMON System Monitor Gestionnaire de l’instance, chargé de la cohérence du
système.
Les autres processus sont facultatifs et peuvent être initialisés en cas de besoin. C’est
le cas par exemple des processus ARCn qui sont automatiquement initialisés lorsque la base
de données fonctionne avec le mode d’archivage des fichiers de journalisation. C’est aussi le
cas du processus RECO qui est initialisé lorsqu’on travaille en serveur parallèle ou RAC (Real
Application Clusters) pour gérer les transactions distribuées. Un extrait des processus
d’arrière-plan optionnels est présenté à la suite.
Code Signification Rôle
RECO Recoverer
QMNn Advanced Queuing mise en file des tâches
ARCn Archiver chargé de l’archivage des fichiers journaux
Processus de Fond

LCKn RAC Lock Manager, Instance gestionnaire des verrous en environnement multi instances
Optionnels

Locks (RAC Real Application Clustrers).


CJQ0 Snapshot Refresh: Coordinateur des gestionnaires de tâches planifiées
Dnnn Dispatcher dispatche des requêtes en environnement de serveurs
partagés.
Snnn Shared Server: serveurs Traites les requêtes des clients
partagés
Pnnn Parallel Query Slaves Processus de sauvegarde et restauration

III.4.2. Base de données Oracle


C’est le module de stockage des données du serveur Oracle. La base de données est
constituée de trois types de fichiers :
• Les fichiers de contrôle (Control Files)
• Les fichiers de journalisation (Online Redo Log Files)
• Les fichiers de données (Data Files)
Le serveur gère également d’autres fichiers tels que le fichier de mots de passe, les
fichiers d’archivage et le fichier de paramètres. Ces fichiers ne sont pas souvent considérés
comme fichiers de la base de données parce que le serveur peut fonctionner sans ces
derniers ; ce qui n’est pas faisable pour les trois premiers fichiers.

IV. LE DICTIONNAIRE DE DONNEES


IV.1. Présentation du dictionnaire de données
On pourrait définir le dictionnaire de données du serveur Oracle comme l’annuaire de
tous ces objets logiques et physiques. Les utilisateurs des bases de données, les développeurs
d'applications, les administrateurs de bases de données et le serveur Oracle utilisent le
dictionnaire de données comme une source centrale d’information associée à une base de
données.
Concrètement, le dictionnaire de données est un ensemble de tables et de vues. A la
base nous avons des tables. Mais à cause de leur complexité, elles ne sont pas facilement
accessibles. Alors Oracle implémente un script pour créer des vues au-dessus de ces tables
pour un accès plus convivial.

16
Le dictionnaire de données est automatiquement mis à jour par Oracle lorsque des
commandes de langage de définition des données (DDL) ou des commandes de manipulation
des données (DML), débouchant par exemple sur l'extension d'une table, sont exécutées.
Le dictionnaire de données stocke les informations sur :
• La structure de stockage de la base de données : Par exemple, les informations sur
les tablespaces, les blocs de données, les extensions et les segments d'une base de
données.
• La structure physique de la base de données, notamment les informations sur les
fichiers de contrôle, les fichiers redo log et les fichiers de données.
• Les noms et les définitions des objets, tels que les tables, les vues, les index, les
clusters, les séquences, les triggers (ou déclencheurs), les fonctions, les procédures et
les packages mais aussi les informations sur les espaces alloués et l’espace actuellement
utilisé par les objets.
• Les contraintes d’intégrité définies pour les tables d'une base de données.
• Les noms des utilisateurs de la base de données et les privilèges et les rôles attribués
à chaque utilisateur. Les privilèges définissent les opérations qu’un utilisateur peut
effectuer dans la base de données. Un rôle est constitué d’un ensemble de privilèges.
• L’audit sur une base de données : par exemple, le dictionnaire de données fournit les
informations sur les utilisateurs qui ont accédé à des objets ou les ont mis à jour. L’audit
correspond à l’enregistrement d’opérations spécifiques en fonction d'un utilisateur, d'un
objet ou d'un privilège.
Le dictionnaire de données possède deux composants :
• les tables de base
• les vues du dictionnaire de données.

IV.2. Les tables de base


Les tables de base sont les tables réelles d'Oracle qui stockent les informations sur
une base de données. Ces tables sont créées avec le script sql.bsq. Ce script est stocké dans
le répertoire %ORACLE_HOME%\rdbms\admin sous Windows respectivement dans
$ORACLE_HOME\rdbms\admin sous Linux. Les informations stockées dans les tables de base
sont lues et écrites par le serveur Oracle. Ces informations sont rarement accédées
directement par les utilisateurs car ces informations sont normalisées et stockées sous un
fichier chiffré.
Les utilisateurs ou administrateurs de bases de données ne doivent pas utiliser de
commandes DML, telles que INSERT, UPDATE et DELETE, pour mettre à jour les tables de base
directement, à l'exception de la table de trace d'audit lorsque la fonctionnalité d'audit est
utilisée.

IV.3. Les vues du dictionnaire de données.


Les vues du dictionnaire de données sont des vues sur les tables de base. Celles-ci
sont créées automatiquement lorsque la base de donnés est créée par DBCA (DataBase
Configuration Assistant) ou automatiquement pendant l’installation du serveur. Cependant,
lorsque la base de donnés est créée manuellement, le DBA se doit également de créer les
vues du dictionnaire de données pareillement (manuellement). Le script de création de ces
vues se nomme catalog.sql. Il est situé dans le même répertoire que le script de création
des tables de base du dictionnaire de données (%ORACLE_HOME%\rdbms\admin pour
Windows). Les vues du dictionnaire de données simplifient et synthétisent les informations
contenues dans les tables de base. Les vues du dictionnaire stockent également ces
informations sous une forme que les utilisateurs de la base de données peuvent lire
facilement. Ces vues permettent au DBA de gérer et tuner la base de données.
Comme pour toutes les tables ou vues, on peut prendre au hasard une vue du
dictionnaire de données et chercher sa description avec la commande SQL*Plus DESC.
17
L’exécution d’un script sur SQL*Plus ou SQL*Worksheet se fait en exécutant @ ou
encore START.
Exemple :
@ %ORACLE_HOME%\rdbms\admin\catalog.sql
Ou encore
START %ORACLE_HOME%\rdbms\admin\catalog.sql
Remarque : il faut être connecté en tant que sysdba
En réalité l’exécution du script catalog.sql ne fait rien d’autres que d’appeler d’autres
scripts qui ont des rôles précis :
Cataudit.sql : crée la tables SYS.AUD$ utiliser pour l’audit des opérations sur le serveur.
Catldr.sql : crée des vues pour l’utilitaire SQl*Loader
Catexp.sql : crée des vues pour l’utilitaire exp/imp pour l’export et l’import des données.
Catpart.sql : crée des vues qui reconnaissent les partitions (de tables).
Catadt.sql : crée des vues qui reconnaissent les types de données utilisateur.
Standard.sql : crée le package STANDARD qui stocke tous les types natifs et les fonctions
prédéfinies d’Oracle.
Remarque : tous ces scripts se trouvent au même endroit que catalog.sql.

IV.4. Catégories des vues du dictionnaire de données


Oracle a défini une nomenclature pour les vues du dictionnaire de données. Cette
nomenclature se base sur deux principales notions : la notion de portée et la notion de
thème.
La notion de thème permet de définir le type d’information que la vue renferme. On
distinguera ainsi les vues qui décrivent les tables des vues qui décrivent les utilisateurs de la
base de données. On distinguera aussi par exemple les vues qui décrivent les différents
tablespaces des vues qui présent les fichiers redo (journaux), etc.
La notion de portée quant à elle permet de se fixer sur le niveau de couverture d’informations
de la vue. On distingue ainsi trois niveaux de portée :
• les USER_vues : ces vues ne peuvent renvoyer que des informations sur les objets dont
l’utilisateur courant est le propriétaire : les objets de son schéma.
• les ALL_vues : ces vues ne peuvent renvoyer que des informations sur les objets auxquels
l’utilisateur courant a des droits d’accès. Il est évident que ces vues contiennent les
USER_vues.
• les DBA_vues : ces vues renvoient toutes les informations possibles pour peu qu’elles
rentrent dans le thème défini. Une fois de plus il est clair que ces vues contiennent les
ALL_vues pour ne plus citer les USER_vues. Seuls les utilisateurs possédant le privilège
SELECT_CATALOG_ROLE sont habilités à interroger les DBA_vues. Cependant les
utilisateurs qui possèdent le privilège système SELECT ANY TABLE ou des privilèges
supérieurs peuvent aussi y avoir accès. Le privilège SELECT ANY TABLE permet aux
utilisateurs d’interroger toutes les tables de la base de données.
On a peut remarquer qu’il existe une relation d’inclusion entre les différents niveaux
de portée. Le schéma ci-dessous nous l’illustre encore mieux.
Vues fournissant des informations sur tous les objets de la base de données.

DBA_views : tous les objets de la Base de Données

ALL_views : toutes les vues accessibles à l’utilisateur

USER_views : schéma et objets de l’utilisateur,


privilèges et rôles liés aux objets de l’utilisateur

18
IV.5. Informations contenues dans le dictionnaire de données
Vues Descriptions
Dictionary Vues générales
dict_columns
dba_tables Informations sur les objets, tels que les tables, les
dba_objects contraintes, les gros objets et les colonnes
dba_lobs
dba_tab_columns
dba_constraints
dba_users Informations sur les privilèges et les rôles des
dba_sys_privs utilisateurs
dba_roles
dba_extents Allocation d’espace pour les objets de la base de
dba_free_space Données
dba_segments
dba_rollback_segs Structures générales de la base de données
dba_data_files
dba_tablespaces
Dba_audit_trail Informations d’audit
Dba_audit_objects
Dba_audit_obj_opts
La vue DICTIONARY ou DICT ou CATALOG ou encore CAT (qui sont des synonymes) du
dictionnaire de données fournit une vue d’ensemble de toutes les données du dictionnaire de
données. Utiliser la vue DICTIONARY afin de vous éviter d'avoir à se souvenir de toutes les
vues et des informations fournies par chacune de ces vues.
Exemple :
L’objectif est de récupérer les noms des segments de rollback de la base de données
en interrogeant la vue DICTIONARY.
SELECT *
FROM dictionary
WHERE table_name LIKE UPPER (‘%ROLLBACK%’);

TABLE_NAME COMMENTS
---------------------------- --------------------------
DBA_ROLLBACK_SEGS Description of rollback segments

Cette requête affiche le nom des vues qui contiennent des informations sur les
segments de rollback. Pour afficher les noms des segments de rollback :
SELECT segment_name FROM dba_rollback_segs;

SEGMENT_NAME
------------------------------
SYSTEM
RB_TEMP
RB1
RB2
RB3

V. PROCEDURE DE CREATION D’UNE LA BASE DE DONNNEES


Pendant l’installation d’un serveur Oracle et de la suite de logiciels qui
l’accompagnent, il est possible de créer une base de données par défaut, ceci grâce à DBCA
(DataBase Configuration Assistant). Une fois le serveur installé, il est encore possible de créer
des bases de données soit manuellement (avec un script contenant l’instruction CREATE
DATABASE…) soit avec DBCA.

19
CHAPITRE II : LES OBJETS DE LA BASES DE DONNEES
ORACLE
I. TABLESPACE
Un tablespace est un espace logique qui contient les objets stockés dans la base de
données comme les tables ou les indexes. En d’autres termes, le tablespace est une unité
logique de stockage composée de fichiers de données. Un tablespace est composé d'au moins
un datafile, c'est à dire un fichier de données qui est physiquement présent sur le serveur à
l'endroit stipulé lors de sa création. C’est à partir de cet objet que l’on va gérer le stockage
principalement ; ranger les objets par type (application, service, index, tables, etc…) et ainsi
permettre une administration plus fluide et plus souple, une meilleure optimisation, et
performances. Le stockage est organisé en segments et extent. Autrement dit, chaque
datafile est constitué de segments d'au moins un extent (ou page) lui-même constitué d'au
moins 3 blocs : l'élément le plus petit d'une base de données.
Une base de données Oracle possède au minimum 4 tablespaces.
• SYSTEM (dictionnaire de données - Tablespace SYSTEM)
• SYSAUX (system auxiliaire composants oracle - Tablespace SYSAUX)
• UNDOTBS (segments d’annulations - Tablespace UNDO)
• TEMP (segments temporaires - Tablespace TEMPORAIRE)
Puis des tablespace spécifiquement créés pour des données applicatives et
utilisateurs.
Il est déconseillé de stocker des données applicatives / utilisateurs dans SYSTEM et
SYSAUX.
Voir les tablespace dans Oracle
SELECT tablespace_name, status, contents, extent_management
FROM dba_tablespaces;

I.1. Creation d’un tablespace permanent avec l'ordre sql CREATE TABLESPACE.
On appelle Tablespace permanents, les Tablespace autres que TBS UNDO et TBS
TEMPORARY
Syntaxe de création d’un tablespace
CREATE [ BIGFILE | SMALLFILE ] TABLESPACE Name
DATAFILE file_specification SIZE integer [ K | M | G | T | P | E ] [REUSE]
AUTOEXTEND
{ OFF
| ON [ NEXT integer [ K | M | G | T | P | E ]]
[ MAXSIZE { UNLIMITED | integer [ K | M | G | T | P | E ] } ]
| DEFAULT [ { COMPRESS | NOCOMPRESS } ]
STORAGE
({ INITIAL integer [ K | M | G | T | P | E ]
| NEXT integer [ K | M | G | T | P | E ]
| MINEXTENTS integer
| MAXEXTENTS { integer | UNLIMITED }
| PCTINCREASE integer
| FREELISTS integer
| FREELIST GROUPS integer
| OPTIMAL [ integer [ K | M | G | T | P | E ]
| NULL
]
| BUFFER_POOL { KEEP | RECYCLE | DEFAULT }
})
EXTENT MANAGEMENT
{ LOCAL
[ AUTOALLOCATE
| UNIFORM
20
[ SIZE integer [ K | M | G | T | P | E ] ]
]
| DICTIONARY
}
SEGMENT SPACE MANAGEMENT { AUTO | MANUAL }
| [ MINIMUM EXTENT integer [ K | M | G | T | P | E ]
| BLOCKSIZE integer [ K ]
| { LOGGING | NOLOGGING }
| FORCE LOGGING
| FLASHBACK { ON | OFF }
| { ONLINE | OFFLINE };

Descriptions de quelques Options.


• BIGFILE | SMALLFILE. Si cette clause est omise, Oracle prendra le type par défaut défini au niveau de la
base de données.
• Name : C'est le nom que vous donnerez à votre Tablespace.
• DATAFILE file_specification : Permet de préciser l'emplacement du fichier de données pour le Tablespace.
• AUTOEXTEND : Indique si le fichier pourra grossir une fois l'espace alloué est utilisé.
• NEXT : Espace alloué lors de l'extension.
• MAXSIZE : Taille maximale du fichier.
• EXTENT MANAGEMENT : Mode de gestion des extensions du Tablespace.
• SEGMENT SPACE MANAGEMENT : Mode de gestion de l'espace libre des segments dans le Tablespace.(clause
valable si TBS géré localement uniquement).
• MINIMUM EXTENT : Taille minimum des Extensions dans le Tablespace. (clause valable si TBS géré dans le
Dictionnaire uniquement).
• BLOCKSIZE : Taille du bloc utilisée par le Tablespace. (2k, 4K, 8K, 16K, 32K).
• LOGGING | NOLOGGING. Définit le mode de journalisation des segments qui seront stockés dans le
Tablespace. Clause ignorée si FORCE LOGGING est actif niveau Tablespace ou Base de données.
• FORCE LOGGING. Permet de garantir que les modifications sont enregistrées dans les fichiers de
journalisation.
• FLASHBACK { ON | OFF}. Indique si le Tablespace participe aux opérations de FLASHBACK Database.
• ONLINE | OFFLINE. Indique si le Tablespace est crée Online ou Offline.

Exemples :
CREATE SMALLFILE TABLESPACE "DATA"
DATAFILE 'C:\ORACLE\PRODUCT\10.2.0\ORADATA\DBTEST\DATA.DBF' SIZE 2G
AUTOEXTEND ON NEXT 100M MAXSIZE 5000M
LOGGING
ONLINE
PERMANENT
BLOCKSIZE 8192
EXTENT MANAGEMENT LOCAL UNIFORM SIZE 10M
SEGMENT SPACE MANAGEMENT AUTO;

I.2. Modification Tablespace avec l'ordre SQL ALTER TABLESPACE / DATABASE.


Comment ajouter un fichier de données dans un tablespace permanent de ma base de
données Oracle ou comment renommer, déplacer un fichier de données, passer le Tablespace
OFFLINE ou en READ-ONLY ou en FORCE LOGGING ou augmenter la taille d'un fichier de
données Oracle ?
Syntaxe ordre sql ALTER TABLESPACE Permanent.
ALTER TABLESPACE tablespace
{ DEFAULT
[ table_compression ] storage_clause
| MINIMUM EXTENT integer [ K | M | G ]
| RESIZE integer [ K | M | G | T ]
| COALESCE
| RENAME TO new_tablespace_name
| { BEGIN | END } BACKUP
{ ADD { DATAFILE } [ file_specification ]
| DROP {DATAFILE } { 'filename' | file_number }
| RENAME DATAFILE 'filename' [, 'filename' ]... TO
'filename' [, 'filename' ]
21
| { DATAFILE } { ONLINE | OFFLINE }
}
{
| [ NO ] FORCE LOGGING
}
TABLESPACE GROUP { tablespace_group_name | '' }
{ ONLINE
| OFFLINE [ NORMAL | TEMPORARY | IMMEDIATE ]
}
| READ { ONLY | WRITE }
| { PERMANENT }
AUTOEXTEND
{ OFF
| ON [ NEXT integer [ K | M | G | T ] ]
[ MAXSIZE { UNLIMITED | integer [ K | M | G | T ] } ]
}
FLASHBACK { ON | OFF }
RETENTION { GUARANTEE | NOGUARANTEE }
} ;
Exemple
Ajouter un fichier de données au TABLESPACE avec ADD DATAFILE.
SQL> ALTER SYSTEM SET DB_CREATE_FILE_DEST =
'C:\ORACLE\PRODUCT\10.2.0\ORADATA\DBTEST';
SQL> ALTER TABLESPACE data ADD DATAFILE AUTOEXTEND ON MAXSIZE 3G;

sinon

SQL> ALTER TABLESPACE data ADD DATAFILE


'C:\ORACLE\PRODUCT\10.2.0\ORADATA\DBTEST\DATA_2.DBF'
SIZE 2G AUTOEXTEND ON MAXSIZE 3G;

I.3. DROP (Suppression) TABLESPACE avec l'ordre SQL DROP TABLESPACE.


Syntaxe ordre sql DROP TABLESPACE.
DROP TABLESPACE tablespace
[ INCLUDING CONTENTS [ {AND | KEEP} DATAFILES ]
[ CASCADE CONSTRAINTS ]
] ;
Descriptions Options.
• INCLUDING CONTENTS : Cette clause est nécessaire si le tablespace n'est pas vide.
• AND DATAFILES : Supprime les fichiers physique du Tablespace (En Oracle-managed files
suppression par défaut sans cette commande).
• KEEP DATAFILES : En Oracle-managed files, permet de ne pas supprimer les fichiers
physique du Tablespace.
• CASCADE CONSTRAINTS : Supprime les contraintes d'intégrité référentielle des tables hors
du tablespace et qui référencent des tables à l'intérieur de celui-ci.
Attention, pas de rollback possible (ordre DDL), les fichiers physiques même encore présent
sur le disque si l'option AND DATAFILES n'est pas utilisée sont irrécupérables. Avant toute
suppression d'un TABLESPACE, faire une sauvegarde complète de la base de données.
Suppression d'un TABLESPACE permanent avec Tables et Index et Contraintes.
SQL> DROP TABLESPACE data INCLUDING CONTENTS CASCADE CONSTRAINTS;

Suppression d'un TABLESPACE permanent avec Tables et Index et Contraintes + Fichiers


Physiques.
SQL> DROP TABLESPACE data INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTS;

22
ATTENTION, la clause AND DATAFILES n'est pas nécessaire pour Oracle-managed files, car
ils sont retirés du système, même si vous ne spécifiez pas AND DATAFILES.
Donc si vous êtes en Oracle-managed files et que vous ne désirez pas supprimer les fichiers
physiques, utilisez KEEP DATAFILES.
I.4. Oracle Tablespace temporaire (TEMPORARY TABLESPACE)
Oracle effectue de nombreux tris (utilisateurs et noyau) suite aux requêtes du type ORDER
BY, GROUP BY, UNION, DISTINCT, etc.
Ils sont principalement effectués dans une zone de tri en mémoire (PGA) sauf si celle-ci est
insuffisante alors il utilisera le TEMPORARY TABLESPACE.
Attention si votre base de données n’en possède pas, les tris seront effectués dans le
tablespace SYSTEM. Le tablespace temporaire peut être géré en mode local ou dictionnaire.
Le mode conseillé est le mode LOCAL. Plusieurs tablespace temporaires peuvent être en
ligne et actifs simultanément dans une base de données et faire partie d'un groupe de
tablespaces temporaires. Amélioration des temps de réponses pour les requêtes en
parallèles.
Création d’un Tablespace temporaire avec CREATE TABLESPACE.
SQL> CREATE TEMPORARY TABLESPACE temp
TEMPFILE 'c:\oracle\oradata\dbtest\temp01.dbf' SIZE 1000M
EXTENT MANAGEMENT LOCAL
AUTOEXTEND ON NEXT 100M MAXSIZE 5000M ;

Définir le TEMPORARY TABLESPACE par défaut.


SQL> ALTER DATABASE DEFAULT TEMPORARY TABLESPACE temp;

Ajouter un fichier de données temporaire.


SQL> ALTER TABLESPACE temp
ADD TEMPFILE 'c:\oracle\oradata\dbtest\temp02.dbf' SIZE 1000M
AUTOEXTEND ON NEXT 100M MAXSIZE 5000M ;

Supprimer un fichier de données temporaire avec ALTER DATABASE DROP INCLUDING.


SQL> ALTER DATABASE
TEMPFILE 'c:\oracle\oradata\dbtest\temp01.dbf'
DROP INCLUDING DATAFILES;

I.5. Oracle Tablespace Annulation (UNDO)


Oracle stocke temporairement les données en cours de modifications dans des segments
d’annulations. Ces segments d’annulations sont en attente de validation ou d’annulation
(COMMIT ou ROLLBACK).
Utile pour la notion de lecture cohérente des données pendant des opérations de mises à
jour, pour la récupération de données (FLASHBACK) et le RECOVER.
Création d’un Tablespace UNDO avec CREATE UNDO TABLESPACE
SQL> CREATE SMALLFILE UNDO TABLESPACE undotbs2
DATAFILE 'c:\oracle\oradata\dbtest\undotbs2_01.dbf' SIZE 5G
AUTOEXTENT ON NEXT 1G MAXSIZE 20G;

Ajouter des fichiers au Tablespace UNDO avec ALTER TABLESPACE


SQL> ALTER TABLESPACE undotbs2
ADD DATAFILE 'c:\oracle\oradata\dbtest\undotbs2_02.dbf' SIZE 5G
AUTOEXTENT ON NEXT 1G MAXSIZE 20G;

Changement de Tablespace UNDO actif (si plusieurs) avec ALTER SYSTEM


SQL> ALTER SYSTEM SET UNDO_TABLESPACE = undotbs2 SCOPE=BOTH;
Si vous changez de Tablespace UNDO, et que des segments d’annulations sont utilisés dans
des transactions, leurs états ne seront pas OFFLINE mais PENDING OFFLINE jusqu'à la fin des
transactions en cours. Vous pouvez ensuite le supprimer par exemple.
Supprimer un Tablespace UNDO avec DROP TABLESPACE INCLUDING CONTENTS
SQL> DROP TABLESPACE undotbs2 INCLUDING CONTENTS AND DATAFILES
23
II. UTILISATEURS
On peut créer une analogie entre les utilisateurs physiques et les utilisateurs logiques
d’une base de données. Il est d’ailleurs recommandé que sauf dans les cas extrêmes chaque
utilisateur physique ait un compte dans la base de données, en d’autres termes qu’il soit
reconnu dans la table des utilisateurs du système. Dans un serveur Oracle les mécanismes
d’authentification et d’accès sont réalisés à travers les informations liées aux différents
utilisateurs de la base de données. Il se pose donc ainsi entre autre besoin celui d’attribuer
des droits d’accès et de définir le mécanisme d’authentification pour chaque utilisateur créé.
Voici les différentes étapes qui seront nécessaire à la création d'un utilisateur Oracle:
• Choisir un nom d'utilisateur,
• Choisir une méthode d'authentification : par le dictionnaire de données, le OS ou un
service tiers du réseau,
• Choisir les TABLESPACE par défaut de l’utilisateur : celui dans lequel ses objets seront
par défaut stockés,
• Définir les TABLESPACE temporaire de l’utilisateur,
• Définir les quotas sur les tablespaces auxquels l’utilisateur a accès
• Créer l'utilisateur
• Assigner les rôles et privilèges à l'utilisateur

Remarque :
Un utilisateur Oracle peut être identifié par le Système d'exploitation ou par Oracle.
Les droits utilisateurs sont gérés avec des privilèges systèmes (ex : droit de créer une table).
Les droits utilisateurs sont gérés avec des privilèges objets (ex : droit de mettre à jour une
table). Privilèges systèmes et Privilèges objets peuvent être regroupés dans un RÔLE. Un
RÔLE est un regroupement de privilèges systèmes et de privilèges objets. On définit à la
création du USER le ou les Tablespace (ou aucun) dans lesquels il sera autorisé à créer des
objets. On définit à la création du USER des Quota d'utilisation dans les Tablespace.

Un utilisateur nouvellement créé ne possède aucun privilège, même pas celui de


l’ouverture d’une session. Comme tous les objets logiques d’une base de données Oracle,
une fois créé un utilisateur peut par la suite être modifié avec l’instruction ALTER USER ou
tout simplement supprimé par l’instruction DROP USER.
Considérons les valeurs des paramètres suivants :
• Hostname de mon serveur Oracle --> SRV_ORA
• Compte OS en cours --> DANIEL

Syntaxe ordre sql CREATE USER.


CREATE USER user
IDENTIFIED { BY password
| EXTERNALLY [ AS 'certificate_DN' ]
| GLOBALLY [ AS '[ directory_DN ]' ]
}
[ DEFAULT TABLESPACE tablespace
| TEMPORARY TABLESPACE
{ tablespace | tablespace_group_name } ]
[ QUOTA integer [ K | M | G | T | P | E ]
| UNLIMITED
}
ON tablespace ]
| PROFILE profile
| PASSWORD EXPIRE
| ACCOUNT { LOCK | UNLOCK };

24
Création d'un compte utilisateur (User) identifié par le système d'exploitation.
SQL> CREATE USER "SRV_ORA\DANIEL"
IDENTIFIED EXTERNALLY
DEFAULT TABLESPACE data
TEMPORARY TABLESPACE temp
PROFILE DEFAULT
ACCOUNT UNLOCK;
A ce moment précis, aucune connexion possible encore.
SQL> connect /
ERROR:
ORA-01045: l'utilisateur SRV_ORA\DANIEL n'a pas le privilege CREATE
SESSION ;
connexion refusée
Nous allons donc donner le rôle CONNECT à l'utilisateur Daniel (CREATE SESSION fait partie
de ce RÔLE).
SQL> GRANT CONNECT TO "SRV_ORA\DANIEL";
Grant succeeded.:m

SQL> connect /
Connected.
SQL> show user
USER is "SRV_ORA\DANIEL"

Création d'un compte utilisateur (User) identifié par Oracle.


SQL> CREATE USER sysdan IDENTIFIED BY "sysdan"
DEFAULT TABLESPACE "data"
TEMPORARY TABLESPACE "temp"
PROFILE DEFAULT
QUOTA UNLIMITED ON "data"
QUOTA 30M ON "data_vente"
PASSWORD EXPIRE;

SQL> GRANT "CONNECT" TO sysdan;


L'utilisateur SYSDAN devra à la première connexion changer son mot de passe.

Descriptions de quelques Options.


• IDENTIFIED : Cette clause indique la manière dont l'utilisateur sera identifié ( par l'OS ou par
Oracle).
• DEFAULT TABLESPACE : Indique le Tablespace dans lequel les objets de l'utilisateur seront
crées.
• TEMPORARY TABLESPACE : Indique le Tablespace dans lequel les tris par exemple seront
effectués pour cet utilisateur.
• QUOTA : Limite d'espace attribué à l'utilisateur sur un Tablespace.
• PASSWORD EXPIRE : Permet de forcer un changement de mot de passe à la première connexion
de l'utilisateur.
• ACCOUNT LOCK / UNLOCK : Permet de verrouiller ou déverrouiller le compte utilisateur.

III. TABLES
III.1. Présentation
Une table est un objet de la base de données qui sert à stocker les données des
utilisateurs. C’est un ensemble de lignes et de colonnes. L'intersection d'une ligne et d'une
colonne est appelée un champ. Une table peut contenir au maximum 1000 colonnes et doit
être nommée selon les conventions de nommage d'Oracle. En plus de ces règles, il y a
quelques comportements qu’un bon développeur Oracle devrait adopter :

25
• Les noms de tables et des colonnes doivent être explicites et représentatifs des
informations contenues respectivement dans les tables et les colonnes.
• Il est fortement conseillé de nommer de manière identique une colonne qui fait
référence à une autre colonne d'une autre table.
Oracle propose plusieurs types de tables dont on peut user pour stocker nos
informations. Le choix du type de table est basé sur les vertus et les limites éventuelles de
types de tables présentés.
Les différents types disponibles sont les suivants :
• Les tables normales : c’est l'élément le plus communément utilisé pour stocker les
données utilisateur. Il s'agit du type de table par défaut qui constitue le sujet principal
de ce paragraphe
• Les tables partitionnées : elle permet de créer des applications évolutives. Elles sont
adaptées pour les tables volumineuses avec accès simultanés. Elle contient une ou
plusieurs partitions qui stockent chacune les lignes partitionnées. Une partition
constitue un segment qui peut se trouver dans un tablespace différent.
• Les tables organisées en index : c’est une table normale contenant un index de clé
primaire dans une ou plusieurs de ses colonnes. Ce type de table nous évite l’usage de
deux espaces de stockage distincts pour la table et un index. Ces tables accélèrent
l'accès par clé aux données des tables dans les interrogations impliquant des
recherches de correspondance exacte ou des recherches sur des plages de données.
Les insertions de nouvelles données sont plus coûteuses dans la mesure où, il faut les
insérer au bon endroit quitte à déplacer plusieurs enregistrements.
• Les tables incluses dans un cluster : Un cluster est constitué de plusieurs tables qui
partagent les mêmes blocs de données, regroupés du fait qu'ils partagent des colonnes
et souvent utilisés conjointement. Il est possible de stocker les données de plusieurs
tables dans un même objet ; cet objet s’appelle un cluster de tables.
Il faut noter que le serveur Oracle permet également de manipuler les tables
temporaires. La différence entre une table temporaire et une table permanente est que les
données d’une table temporaire sont stockées en mémoire contrairement aux données d’une
table permanente qui sont stockés dans des fichiers qui sont des supports permanents.
Lorsque les données d’une table temporaire deviennent volumineuses, certaines sont
transférées dans un tablespace temporaire. Une chose qui en fait la différence est qu’une
fois créée, une table temporaire est accessible à tous les utilisateurs moyennant le fait que
l’on ne peut accéder qu’aux données que l’on a introduites. Il en est de même pour la
troncature des tables temporaires.

III.2. Créer une table


Comment créer une table dans une base de données Oracle.
Remarques
• Pour créer une table dans votre schéma, il vous faut le privilège CREATE TABLE ou le
privilège CREATE ANY TABLE.
• On crée une table avec la commande SQL CREATE TABLE.
• On modifie la structure d'une table avec la commande SQL ALTER TABLE.
• On supprime une table avec la commande SQL DROP TABLE.
• On vide totalement une table avec la commande SQL TRUNCATE TABLE.

III.2.1. Privilèges CREATE TABLE ou CREATE ANY TABLE.


SQL> GRANT CREATE TABLE TO SCOTT;
Grant succeeded.
SQL> GRANT CREATE ANY TABLE TO SCOTT;
Grant succeeded.
CREATE ANY TABLE autorise la création de tables dans tout schéma.
CREATE TABLE autorise la création de tables uniquement dans son schéma.
26
III.2.2. Syntaxe commande SQL CREATE TABLE.
La syntaxe simplifiée suivante permet de créer une table.
CREATE TABLE [schema.] table
( column1 datatype [DEFAULT expr] [NOT NULL][(inline_constraint| inline_ref_constraint )],
[column2 datatype [DEFAULT expr] [NOT NULL][(inline_constraint| inline_ref_constraint )]],
[column3 datatype [DEFAULT expr] [NOT NULL][(inline_constraint| inline_ref_constraint )]],
[...],
[table_constraint [,…]]
[table_ref_constraint [,…]]
)
[TABLESPACE tablespace ]
[ PCTFREE integer ]
[ PCTUSED integer ]
[ INITRANS integer ]
[ MAXTRANS integer ]
[ STORAGE storage-clause ]
[LOGGING | NOLOGGING]
[CACHE | NOCACHE]

Schema est le propriétaire de la table.
Table est le nom de la table.
Column est le nom de la colonne.
Datatype est le type de données de la colonne.
TABLESPACE indique le tablespace de destination de la table à créer.
PCTFREE correspond à l'espace réservé dans chaque bloc (sous la forme d'un pourcentage de l'espace
total moins l'en-tête de bloc) à l'augmentation de la longueur des lignes,
PCTUSED définit la limite inférieure de l'espace utilisé dans un bloc (après utilisation de l'espace défini
par le paramètre PCTFREE) à partir de laquelle d'autres lignes peuvent être insérées.
INITRANS définit le nombre d'entrées de transaction pré allouées dans chaque bloc (la valeur par défaut
est 1).
MAXTRANS limite le nombre d'entrées de transaction pouvant être allouées à chaque bloc (la valeur par
défaut est 255).
STORAGE identifie la clause de stockage qui détermine l'allocation des extensions (ensemble de blocs
contigus) à la table.
LOGGING indique que la création de la table sera consignée dans le fichier de journalisation (redo log),
(indique également que toutes les opérations suivantes effectuées sur la table sont
enregistrées; il s'agit de la valeur par défaut).
NOLOGGING indique que la création de la table et de certains types de chargement de données ne sera
pas consignée dans le fichier de journalisation.
CACHE indique que les blocs extraits pour cette table sont placés à l'extrémité la plus récemment
utilisée de la liste LRU du cache de tampons (buffer cache), même lorsque la table est balayée
en totalité.
NOCACHE indique que les blocs extraits de cette table sont placés à la fin de la liste LRU du cache des
tampons, lorsque la table est balayée en totalité.

Remarques :
• En général, les tables doivent être créées avec une clé primaire.
• Si vous avez défini le paramètre MINIMUM EXTENT du tablespace, la taille des
extensions la table est arrondie au multiple suivant le plus proche.
• Si vous omettez la clause [NO] LOGGING, l'attribut de journalisation de la table
correspond par défaut à celui du tablespace dans lequel elle réside.
• Si vous affectez au paramètre MINEXTENTS une valeur supérieure à 1 et que le
tablespace contient plusieurs fichiers de données, les extensions sont réparties dans
les différents fichiers du tablespace.
Exemple :
CREATE TABLE employee (
id NUMBER (7),
last_name VARCHAR2 (25),
dept_id NUMBER (7))
PCTFREE 20 PCTUSED 50
27
STORAGE (INITIAL 200K NEXT 200K PCTINCREASE 0 MAXEXTENTS 50)
TABLESPACE data;
Exemple : CREATE TABLE avec une PRIMARY KEY et CHECK.
CREATE TABLE scott.vehicule
( vehicule_id NUMBER(6)
, vehicule_marque VARCHAR2(30) CONSTRAINT ck_vehic_marq_nn NOT NULL
, vehicule_modele VARCHAR2(30) CONSTRAINT ck_vehic_mod_nn NOT NULL
, date_sortie DATE
, vehicule_prix NUMBER(10,2)
, CONSTRAINT pk_vehicule_id PRIMARY KEY (vehicule_id)
)
TABLESPACE data;
Exemple : CREATE TABLE avec une PRIMARY KEY (INDEX COMPOSITES sur 3 Colonnes).
CREATE TABLE scott.vehicule
( vehicule_id NUMBER(6)
, vehicule_marque VARCHAR2(30) DEFAULT 'RENAULT'
, vehicule_modele VARCHAR2(30)
, date_sortie DATE
, vehicule_prix NUMBER(10,2)
, CONSTRAINT pk_vehicule_id PRIMARY KEY (vehicule_id,
vehicule_marque,
vehicule_modele)
)
TABLESPACE data;
Exemple : CREATE TABLE avec un Index UNIQUE (unicité) et 3 CHECK.
CREATE TABLE scott.vehicule
( vehicule_id NUMBER(6)
, vehicule_marque VARCHAR2(30)
, vehicule_modele VARCHAR2(30)
, date_sortie DATE CONSTRAINT ck_vehic_date_nn NOT NULL
, vehicule_prix NUMBER(10,2) CONSTRAINT ck_vehic_prix_nn NOT NULL
, CONSTRAINT ck_vehic_prix_min CHECK (vehicule_prix > 0)
, CONSTRAINT un_vehicule_id UNIQUE (vehicule_id)
)
TABLESPACE data;
COMMENT ON COLUMN SCOTT.VEHICULE.VEHICULE_PRIX IS 'Prix neuf';
Remarques
Quelques règles à observer lors de la création des tables :
• Placez les tables dans des tablespaces distincts et non dans des tablespaces contenant
des segments de undo, des segments temporaires et des index.
• Placez les tables dans des tablespaces gérés localement pour éviter la fragmentation.
• Pour améliorer les performances du balayage complet de tables, alignez les tailles
d'extension à l'aide du paramètre d'initialisation.
• Utilisez la clause CACHE pour les petites tables de référence pouvant être
fréquemment utilisées.

III.2.3. Création d’une table par Copie d’une table existante


Il est possible de crée une table et de l’alimenter immédiatement avec des données
provenant d’une table déjà existante. Dans ce cas, on utilisera toujours l’instruction CRATE
TABLE , cette fois avec une sous requête qui permettra d’extraire les données qu’on désire
dans une table donné. Ces données peuvent représenter la totalité des données existantes,
soit une partie. Ces données peuvent être transformées avant d’être stockées dans la
nouvelle table. Une syntaxe simplifiée :
CREATE TABLE [schema.]table
[LOGGING | NOLOGGING]
...
AS
Subquery

28
Les autres clauses, telles que TABLESPACE, STORAGE et les paramètres d'utilisation
des blocs peuvent être définis lors de la création d'une table à partir d'une autre table.
Utilisez la clause NOLOGGING pour interdire la génération d'entrées de journalisation (redo
log entries) et accélérer la création de la table. Lorsque vous créez une table en copiant une
table, les contraintes, les déclencheurs et les privilèges de table ne sont pas copiées. Si la
table d'origine contient une colonne NOT NULL, cette colonne existe également dans la
nouvelle table.
III.2.4. Création des tables temporaires
Outre les tables permanentes, vous pouvez créer des tables temporaires qui
contiennent les données privées des sessions qui n'existent que le temps d'une transaction ou
d'une session.
La commande CREATE GLOBAL TEMPORARY TABLE permet de créer une table
temporaire spécifique à une transaction ou à une session. Les données d'une table
temporaire de transaction et celles d'une table temporaire de session existent
respectivement pendant la durée de la transaction et pendant la durée de la session.
Les données d'une session sont privées. Chaque session ne peut voir et modifier que ses
propres données. Aucun verrou DML n'est placé sur les données d'une table temporaire. Les
clauses qui contrôlent la durée de stockage des lignes sont :
• ON COMMIT DELETE ROWS : indique que les lignes sont uniquement visibles dans la
transaction,
• ON COMMIT PRESERVE ROWS : indique que les lignes sont visibles pour toute la
session.
Vous pouvez créer des index, des vues et des déclencheurs dans les tables temporaires
et utiliser également les utilitaires Export et Import pour exporter et importer la définition
d'une table temporaire. Toutefois, aucune donnée n'est exportée, même si vous utilisez
l'option ROWS. La définition d'une table temporaire est visible dans toutes les sessions.
Exemple :
CREATE GLOBAL TEMPORARY TABLE employee_temp
AS SELECT * FROM employee;

III.2.5. Création d’une table external.


Comment accéder en lecture seule aux données dans une table externe ? Oracle nous
permet de disposer de ces données comme s'il s'agissait de données résidant dans une table
de la base de données. Les données externes peuvent être ensuite interrogés directement
via SQL.
Aucune opération DML (UPDATE, INSERT ou DELETE) sont possibles sur des tables
external.
Nous allons mapper un fichier dans C:\DIRECTORY_ORA\Fichier_TAB.txt en tant que table
externe.
• séparateur = TAB définie par fields terminated by 0X'09'
• Champs texte avec ponctuation sont entre des " afin de ne pas confondre les points
virgules, virgules comme d'éventuels séparateurs définie par OPTIONALLY ENCLOSED
BY '"'
Aperçu du fichier Fichier_TAB.txt

ID NOM PRENOM VILLE TEL COM


1 Durand Jean Paris 0165656565 "Commentaire, ; avec ponctuation
"
2 Dupond Pierre Versailles 0165656566 "Commentaire, avec; ponctuation
;"
3 Morin Jean-Pierre Paris 0165656567 "Commentaire, avec ponctuation ;"
Nous allons créer simplement un DIRECTORY Oracle (indispensable).
Création du DIRECTORY + GRANT en SYSDBA.
29
SQL> CONNECT / AS SYSDBA;
SQL> CREATE OR REPLACE DIRECTORY mydirectory as 'C:\directory_ora';
SQL> GRANT READ, WRITE ON DIRECTORY mydirectory TO myuser;
Création de la table externe avec CREATE TABLE.
SQL> CONNECT myuser/****;
SQL> CREATE TABLE Ma_Table (ID NUMBER(7),
Nom VARCHAR2(30),
Prenom VARCHAR2(30),
Ville VARCHAR2(30),
Tel VARCHAR2(15),
Com VARCHAR2(50))
ORGANIZATION EXTERNAL ( TYPE ORACLE_LOADER
DEFAULT DIRECTORY mydirectory
ACCESS PARAMETERS ( records delimited by newline
skip 1
badfile MYDIRECTORY:'Ma_Table.bad'
logfile MYDIRECTORY:'Ma_Table.log'
fields terminated by 0X'09'
OPTIONALLY ENCLOSED BY '"'
missing field values are null)
LOCATION ('Fichier_TAB.txt'))
PARALLEL REJECT LIMIT UNLIMITED;
Interrogation de la table via SQL
SQL> SELECT * FROM Ma_Table;
ID Nom Prenom Ville Tel Com
1 Durand Jean Paris 0165656565 Commentaire, ; avec ponctuation
2 Dupond Pierre Versailles 0165656566 Commentaire, avec; ponctuation ;
3 Morin Jean-Pierre Paris 0165656567 Commentaire, avec ponctuation ;
Maintenant à partir de cette table externe vous pouvez insérer les lignes dans une
table Oracle avec l'instruction INSERT INTO table(champs1, champs2,....) SELECT * FROM
Ma_Table;

III.3. Modifier les informations sur une table


III.3.1. Renommer le nom d'une Table Oracle.
Les deux commandes SQL pour renommer une table.
ALTER TABLE table_name RENAME TO new_table_name;
RENAME table_name TO new_table_name ;

Exemple des commandes ALTER TABLE RENAME TO et RENAME TO.


SQL> ALTER TABLE emp RENAME TO emp_old;
Table modifiée.

SQL> RENAME emp_old TO emp;


Table renommée.

III.3.2. Ajouter un champ dans une table Oracle avec ALTER TABLE ADD.
Syntaxe ALTER TABLE ADD.
ALTER TABLE [ schema. ]table ADD { ( column [ datatype ] ) } ;

Exemple ALTER TABLE ADD.


SQL> ALTER TABLE countries ADD (duty_pct NUMBER(2,2),
visa_needed VARCHAR2(3));
III.3.3. Modifier un champ de table Oracle avec ALTER TABLE MODIFY.
Pour modifier une colonne dans une table existante, on utilisera la syntaxe ALTER
TABLE MODIFY.
Syntaxe ALTER TABLE MODIFY.
ALTER TABLE [schema.]table MODIFY {( column [ datatype ] ) } ;

30
Exemple ALTER TABLE MODIFY.
SQL> ALTER TABLE countries MODIFY (duty_pct NUMBER(3,2));•Passage de NUMBER(2,2) à NUMBER(3,2)
SQL> ALTER TABLE supplier MODIFY supplier_name NOT NULL; •Passage de NULL autorisé à NOT NULL

III.3.4. Renommer une colonne avec ALTER TABLE RENAME COLUMN.


SYNTAXE COMMANDE SQL ALTER TABLE RENAME COLUMN.
ALTER TABLE table_name RENAME COLUMN column_name TO new_column_name;

Exemple : RENOMMER LA COLONNE D'UNE TABLE ORACLE.


Ici changement de nom de la colonne EMPNO en NEW_EMPNO.
SQL> ALTER TABLE emp RENAME COLUMN empno TO new_empno;
Table modifiée.
DESCRIBE TABLE APRES LE RENAME COLUMN.
SQL> DESC emp;
Nom NULL ? Type
----------------------------------------- -------- -------------
NEW_EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(15)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)

III.3.5. Troncature d’une table


La troncature d'une table supprime toutes les lignes d'une table et libère l'espace
inutilisé.

Syntaxe :
TRUNCATE TABLE [schema.] table
[{DROP | REUSE} STORAGE]

Cette commande a les effets suivants :


• Elle supprime toutes les lignes de la table.
• Aucune donnée d'annulation n'est générée et la commande valide implicitement les
données, car la commande TRUNCATE TABLE est une commande DDL.
• Elle tronque les index correspondants.
• Une table référencée par une clé étrangère ne peut être tronquée.
• Les déclencheurs de suppression ne sont pas activés.
• Si vous utilisez la clause DROP (clause par défaut) :
 toutes les extensions, à l'exception de ceux définis par le paramètre
MINEXTENTS, sont libérées,
 le paramètre NEXT_EXTENT de la table a pour valeur la taille de l'extension
libérée ayant l'ID le plus bas. Par exemple, si la valeur du paramètre
MINEXTENTS est égale à 2, la valeur du paramètre NEXT_EXTENT est égale à la
taille du troisième extension de la table.
 Vous devez définir la clause REUSE pour conserver tout l'espace inutilisé
de la table.
 Les index sont affectés par la clause REUSE ou DROP.

III.4. Suppression une table


III.4.1. La syntaxe DROP TABLE
Vous pouvez supprimer une table devenue inutile ou une table que vous souhaitez
réorganiser.
31
Syntaxe
Utilisez la commande suivante pour supprimer une table :
DROP TABLE [schema.] table
[CASCADE CONSTRAINTS]
Exemple :
DROP TABLE summit.department
CASCADE CONSTRAINTS;
Lorsque vous supprimez une table, vous libérez les extensions qu'elle utilise. Si les
extensions sont contiguës, vous pouvez les fusionner automatiquement ou manuellement plus
tard.
Remarque : vous devez utiliser l'option CASCADE CONSTRAINTS s'il s'agit de la table
mère d'une relation de clé étrangère.
III.4.2. Supprimer une colonne d’une table

SYNTAXE COMMANDE SQL ALTER TABLE DROP COLUMN.


ALTER TABLE table_name DROP { COLUMN column | (column [, column ]...)}
[ { CASCADE CONSTRAINTS | INVALIDATE } ];

SUPPRIMER UNE COLONNE AVEC LA CLAUSE CASCADE CONSTRAINTS.


Avec la clause CASCADE CONSTRAINTS la suppression de la colonne est une réussite.
SQL> ALTER TABLE emp DROP COLUMN empno CASCADE CONSTRAINTS;
Table modifiée.
SUPPRIMER PLUSIEURS COLONNES AVEC ALTER TABLE DROP COLUMN
Pour supprimer plusieurs colonnes d'une table dans Oracle, nous utilisons ALTER TABLE DROP
sans le mot clé COLUMN. Les colonnes à supprimer sont placées entre parenthèses juste après
le mot clé DROP de la commande ALTER TABLE.
SQL> ALTER TABLE emp DROP (ename,job);
Table modifiée.

Exemple
ALTER TABLE employee
DROP COLUMN comments
CASCADE CONSTRAINTS CHECKPOINT 1000;
Remarque : La suppression d'une colonne peut prendre un certain temps, car toutes
les données de la colonne sont supprimées de la table.

UTILISER UN POINT DE REPRISE LORS DE LA SUPPRESSION D'UNE COLONNE


La suppression d'une colonne peut prendre un certain temps et nécessiter un espace
d'annulation conséquent. Lorsque vous supprimez des colonnes dans des tables volumineuses,
vous pouvez dé finir des points de reprise (checkpoint) pour réduire l'espace d'annulation
utilisé. Dans l'exemple suivant, un point de reprise se constitue toutes les 1 000 lignes. La
table a l'attribut INVALID tant que l'annulation est en cours.
Si l'instance connaît un incident pendant l'annulation, la table conserve l'attribut
INVALID au démarrage, et l'opération doit être poursuivie.
Utilisez l'instruction suivante pour reprendre une annulation interrompue :
ALTER TABLE orders
DROP COLUMNS CONTINUE;
Remarque : Cette commande génère une erreur lorsque la table a l'attribut VALID.
III.4.3. Utiliser l'option UNUSED
On peut marquer une colonne UNUSED pour signifier au serveur quelle n’est pas
utilisée. La syntaxe d’une telle instruction est la suivante :
ALTER TABLE table
SET UNUSED COLUMN colonne
32
CASCADE CONSTRAINTS;
Le fait d’avoir précédemment marquer la colonne UNUSED nous permet d’interdire la
manipulation des données de cette colonne. Mais remarquons que nous avons gagné en temps
parce qu’il faut le savoir l’instruction ALTER TABLE table DROP COLUMN existe bel et bien,
mais elle est coûteuse en temps.
Pendant les heures creuses des activés de l’entreprise, l’administrateur peut alors
supprimer la colonne marquée un peu plus tôt. Voici la commande :
ALTER TABLE table
DROP UNUSED COLUMNS [CHECKPOINT n];

Remarque : Les colonnes inutilisées sont considérées comme n'appartenant pas à la


table. Les interrogations ne peuvent pas voir les données des colonnes inutilisées. En outre,
les noms et les types de données de ces colonnes n'apparaissent pas lorsque la commande
DESCRIBE est exécutée. L'utilisateur peut ajouter une colonne en utilisant le nom d'une
colonne inutilisée.
III.4.4. Restrictions relatives à la suppression d'une colonne
• Impossible de supprimer une colonne d'une table de type objet,
• Impossible de supprimer des colonnes dans des tables imbriquées,
• Impossible de supprimer toutes les colonnes d'une table,
• Impossible de supprimer une colonne de clé de partitionnement,
• Impossible de supprimer une colonne des tables dont SYS est propriétaire,
• Impossible de supprimer une colonne de clé parent,
• Impossible de supprimer une colonne d'une table organisée en index si la colonne est
une clé primaire.

III.5. Extraire les informations relatives à une table

Vous pouvez obtenir des informations sur les tables à partir du dictionnaire de données.
Pour obtenir le numéro d'objet de données et l'emplacement de l'en-tête de table de toutes
les tables appartenant à l'utilisateur SUMMIT, lancez l'interrogation suivante :
SELECT t.table_name, o.data_object_id, s.header_file, s.header_block
FROM dba_tables t, dba_objects o, dba_segments s
WHERE t.owner=o.owner
AND t.table_name=o.object_name
AND t.owner=s.owner
AND t.table_name=s.segment_name
AND t.owner='SUMMIT';

TABLE_NAME DATA_OBJECT_ID HEADER_FILE HEADER_BLOCK


33
---------- -------------- ----------- ------------
CUSTOMER 12743 2 902
DEPARTMENT 12745 2 912
EMPLOYEE 2748 2 927
IMAGE 12751 2 942
INVENTORY 12753 2 952
ITEM 12755 2 962

IV. CONTRAINTES D’INTEGRITE


Les contraintes d’intégrité sont des objets de la base de données qui permettent au
serveur Oracle de maintenir la cohérence de ses données. En effet dans un système
transactionnel, seules les instructions qui modifient les données en transportant la base de
données d’un état cohérent vers un autre état cohérent. La cohérence de la base de données
est assurée par l’ensemble des contraintes d’intégrité définies sur la base de données à la
base des règles de gestion retenues lors de l’analyse du système.
Une contrainte d'intégrité permet de contraindre la modification de tables, faite par
l'intermédiaire de requêtes d'utilisateurs, afin que les données saisies dans la base soient
conformes aux données attendues. Ces contraintes peuvent être exprimées dès la création
de la table.
Sur Oracle on distingue plusieurs types de contraintes d’intégrité :
• La non nullité : NOT NULL
• L’unicité : UNIQUE
• La contrainte de clé primaire : PRIMARY KEY (UNIQUE et NOT NULL)
• La contrainte de domaine : CHECK IN
• Les contraintes référentielles : FOREIGN KEY... REFERENCES
• La valeurs par défaut : DEFAULT

Les contraintes peuvent être rajoutées ou enlevées ou modifiées après la création de


la table. Dans la définition d'une table, on peut indiquer des contraintes d'intégrité portant
sur une ou plusieurs colonnes.
Toute définition de table doit comporter au moins une contrainte de type PRIMARY
KEY. Chaque contrainte doit être nommée (ce qui permettra de la désigner par un ordre
ALTER TABLE, et ce qui est requis par les nouvelles normes SQL) :
CONSTRAINT nom-contrainte définition-contrainte
Le nom d'une contrainte doit être unique parmi toutes les contraintes de toutes les
tables de la base de données. Il existe des contraintes :
• sur une colonne : la contrainte porte sur une seule colonne. Elle suit la définition de
la colonne dans un ordre CREATE TABLE (pas possible dans un ordre ALTER TABLE).
• sur une table : la contrainte porte sur une ou plusieurs colonnes. Elle se place au
même niveau que la définition des colonnes dans un ordre CREATE TABLE ou ALTER
TABLE.

IV.1. Définir une valeur par défaut


Le langage SQL permet de définir une valeur par défaut lorsqu'un champ de la base
n'est pas renseigné grâce à la clause DEFAULT. Cela permet notamment de faciliter la
création de tables, ainsi que de garantir qu'un champ ne sera pas vide.
La clause DEFAULT doit être suivie par la valeur à affecter. Cette valeur peut être un
des types suivants:
• constante numérique
• constante alphanumérique (chaîne de caractères)
• le mot clé USER (nom de l'utilisateur)
• le mot clé NULL
• le mot clé CURRENT_DATE (date de saisie)

34
• le mot clé CURRENT_TIME (heure de saisie)
• le mot clé CURRENT_TIMESTAMP (date et heure de saisie)

IV.2. Forcer la saisie d'un champ (NOT NULL)


Le mot clé NOT NULL permet de spécifier qu'un champ doit être saisi, c'est-à-dire que
le SGBD refusera d'insérer des tuples dont un champ comportant la clause NOT NULL n'est pas
renseigné.

IV.3. Emettre une condition sur un champ (Contrainte CHECK)


CHECK(condition) donne une condition que les colonnes de chaque ligne devront
vérifier.On peut ainsi indiquer des contraintes d'intégrité de domaines. Cette contrainte peut
être une contrainte de colonne ou de table. Si c'est une contrainte de colonne, elle ne doit
porter que sur la colonne en question.
Ainsi, Il est possible de faire un test sur un champ grâce à la clause CHECK() comportant
une condition logique portant sur une valeur entre les parenthèses. Si la valeur saisie est
différente de NULL, le SGBD va effectuer un test grâce à la condition logique. Celui-ci peut
éventuellement être une condition avec des ordres SELECT...
CREATE TABLE Film (titre VARCHAR (50) NOT NULL,
annee INTEGER CHECK (annee BETWEEN 1890 AND 2000) NOT NULL,
genre VARCHAR2 (10)CHECK (genre IN (’Histoire’,’Western’,’Drame’)),
idMES INTEGER,
codePays INTEGER,
PRIMARY KEY (titre),
FOREIGN KEY (idMES) REFERENCES Artiste (idMES),
FOREIGN KEY (codePays) REFERENCES Pays (codePays)
);

Quelques contraintes sur des colonnes :


CREATE TABLE EMP (
MATR INTEGER CONSTRAINT KEMP PRIMARY KEY,
NOME VARCHAR2(10) CONSTRAINT NOM_UNIQUE UNIQUE
CONSTRAINT MAJ CHECK (NOME = UPPER(NOME)),
.........
DEPT INTEGER CONSTRAINT R_DEPT REFERENCES DEPT(DEPT)
CONSTRAINT NDEPT CHECK (DEPT IN (10, 20, 30, 35, 40)))

Des contraintes de colonne peuvent être mises au niveau de la table :


CREATE TABLE EMP (
MATR INTEGER,
NOME VARCHAR2(10) CONSTRAINT NOM_UNIQUE UNIQUE
CONSTRAINT MAJ CHECK (NOME = UPPER(NOME)),
.........
CONSTRAINT NDEPT DEPT INTEGER CHECK (DEPT IN (10, 20, 30, 35, 40)),
CONSTRAINT KEMP PRIMARY KEY (MATR),
CONSTRAINT R_DEPT FOREIGN KEY (DEPT) REFERENCES DEPT(DEPT))

Certaines contraintes portent sur plusieurs colonnes et ne peuvent être indiquées


que comme contraintes de table :
CREATE TABLE PARTICIPATION (
MATR INTEGER CONSTRAINT R_EMP REFERENCES EMP,
CODEP VARCHAR2(5) CONSTRAINT R_PROJET REFERENCES PROJET,
.........
CONSTRAINT PKPART PRIMARY KEY(MATR, CODEP))

35
IV.4. Tester l'unicité d'une valeur
La clause UNIQUE permet de vérifier que la valeur saisie pour un champ n'existe pas
déjà dans la table. Cela permet de garantir que toutes les valeurs d'une colonne d'une table
seront différentes.
(Pour une contrainte sur une table :)
UNIQUE (colonne1, colonne2,...)
(Pour une contrainte sur une colonne :)
UNIQUE
Interdit qu'une colonne (ou la concaténation de plusieurs colonnes) contienne deux
valeurs identiques.
Cette contrainte UNIQUE convient à des clés candidates. Cependant une colonne
UNIQUE peut avoir des valeurs NULL et une contrainte UNIQUE ne correspond donc pas
toujours à un identificateur.

IV.5. Définition de clés


Grâce à SQL, il est possible de définir des clés, c'est-à-dire spécifier la (ou les)
colonne(s) dont la connaissance permet de désigner précisément un et un seul tuple (une
ligne).
IV.5.1. Contrainte de clé primaire
L'ensemble des colonnes faisant partie de la table en cours permettant de désigner
Jde façon unique un tuple est appelé clé primaire et se définit grâce à la clause PRIMARY
KEY suivie de la liste de colonnes, séparées par des virgules, entre parenthèses. Ces colonnes
ne peuvent alors plus prendre la valeur NULL et doivent être telles que deux lignes ne puissent
avoir simultanément la même combinaison de valeurs pour ces colonnes.
(pour une contrainte sur une table :)
PRIMARY KEY (colonne1, colonne2,...)
(pour une contrainte sur une colonne :)
PRIMARY KEY
Aucune des colonnes qui forment cette clé ne doit avoir une valeur NULL.
Exemples :
CREATE TABLE Notation (idFilm INTEGER NOT NULL,
email VARCHAR (50) NOT NULL,
note INTEGER DEFAULT 0,
PRIMARY KEY (titre, email));

CREATE TABLE Artiste(id INTEGER NOT NULL,


nom VARCHAR (30) NOT NULL,
prenom VARCHAR (30) NOT NULL,
anneeNaiss INTEGER,
PRIMARY KEY (id),
UNIQUE (nom, prenom));

CREATE TABLE Cinema


(nom VARCHAR (30) NOT NULL,
adresse VARCHAR(50) UNIQUE,
PRIMARY KEY (nomCinema));

IV.5.2. Contrainte de clé étrangère


Lorsqu'une liste de colonnes de la table en cours de définition permet de définir la clé
primaire d'une table étrangère, on parle alors de clé étrangère, et on utilise la clause
FOREIGN KEY suivie de la liste de colonnes de la table en cours de définition, séparées par
36
des virgules, entre parenthèses, puis de la clause REFERENCES suivie du nom de la table
étrangère et de la liste de ses colonnes correspondantes, séparées par des virgules, entre
parenthèses.
(pour une contrainte sur une table :)
FOREIGN KEY (colonne1, colonne2,...)
REFERENCES tableref [(col1, col2,...)]
[ON DELETE CASCADE]
(pour une contrainte sur une colonne :)
REFERENCES tableref [(col1 )]
[ON DELETE CASCADE]
indique que la concaténation de colonne1, colonne2,... (ou la colonne que l'on définit
pour une contrainte sur une colonne) est une clé étrangère qui fait référence à la
concaténation des colonnes col1, col2,... de la table tableref (contrainte d'intégrité
référentielle). Si aucune colonne de tableref n'est indiquée, c'est la clé primaire de tableref
qui est prise par défaut.
Cette contrainte ne permettra pas d'insérer une ligne de la table si la table tableref
ne contient aucune ligne dont la concaténation des valeurs de col1, col2,... est égale à la
concaténation des valeurs de colonne1, colonne2,...
col1, col2,... doivent avoir la contrainte PRIMARY KEY ou UNIQUE. Ceci implique qu'une
valeur de colonne1, colonne2,... va référencer une et une seule ligne de tableref.
L'option « ON DELETE CASCADE » indique que la suppression d'une ligne de tableref
va entraîner automatiquement la suppression des lignes qui la référencent dans la table. Si
cette option n'est pas indiquée, il est impossible de supprimer des lignes de tableref qui sont
référencées par des lignes de la table.
A la place de « ON DELETE CASCADE » on peut donner l'option « ON DELETE SET
NULL ». Dans ce cas, la clé étrangère sera mise à NULL si la ligne qu'elle référence dans
tableref est supprimée.

CREATE TABLE Film (idFilm INTEGER NOT NULL,


titre VARCHAR (50) NOT NULL,
annee INTEGER NOT NULL,
idMES INTEGER,
codePays INTEGER,
PRIMARY KEY (idFilm),
FOREIGN KEY (idMES) REFERENCES Artiste,
FOREIGN KEY (codePays) REFERENCES Pays);

Les clés étrangères permettent de définir les colonnes d'une table garantissant la
validité d'une autre table. Ainsi, il existe des éléments (appelés triggers, ou en français
gâchettes ou déclencheurs) permettant de garantir l'ensemble de ces contraintes que l'on
désigne par le terme d'intégrité référentielle, c'est-à-dire notamment de s'assurer qu'un
tuple utilisé à partir d'une autre table existe réellement.

Ces triggers sont ON DELETE et ON UPDATE:


• ON DELETE est suivi d'arguments entre accolades permettant de spécifier l'action à
réaliser en cas d'effacement d'une ligne de la table faisant partie de la clé étrangère:
o CASCADE indique la suppression en cascade des lignes de la table étrangère dont
les clés étrangères correspondent aux clés primaires des lignes effacées
o RESTRICT indique une erreur en cas d'effacement d'une valeur correspondant à
la clé
o SET NULL place la valeur NULL dans la ligne de la table étrangère en cas
d'effacement d'une valeur correspondant à la clé
o SET DEFAULT place la valeur par défaut (qui suit ce paramètre) dans la ligne de
la table étrangère en cas d'effacement d'une valeur correspondant à la clé
37
• ON UPDATE est suivi d'arguments entre accolades permettant de spécifier l'action à
réaliser en cas de modification d'une ligne de la table faisant partie de la clé étrangère:
o CASCADE indique la modification en cascade des lignes de la table étrangères
dont les clé primaires correspondent aux clés étrangères des lignes modifiées
o RESTRICT indique une erreur en cas de modification d'une valeur correspondant
à la clé
o SET NULL place la valeur NULL dans la ligne de la table étrangère en cas de
modification d'une valeur correspondant à la clé
o SET DEFAULT place la valeur par défaut (qui suit ce paramètre) dans la ligne de
la table étrangère en cas de modification d'une valeur correspondant à la clé

CREATE TABLE Film (titre VARCHAR (50) NOT NULL,


annee INTEGER NOT NULL,
idMES INTEGER,
codePays INTEGER,
PRIMARY KEY (titre),
FOREIGN KEY (idMES) REFERENCES Artiste
ON DELETE SET NULL,
FOREIGN KEY (codePays) REFERENCES Pays);

CREATE TABLE Salle (nomCinema VARCHAR (30) NOT NULL,


no INTEGER NOT NULL,
capacite INTEGER,
PRIMAR KEY (nomCinema, no),
FOREIGN KEY (nomCinema) REFERENCES Cinema
ON DELETE CASCADE
ON UPDATE CASCADE
)

IV.6. Ajouter, supprimer ou renommer une contrainte


Il est possible de donner un nom à une contrainte grâce au mot clé CONSTRAINT suivi
du nom que l'on donne à la contrainte, de telle manière à ce que le nom donné s'affiche en
cas de non-respect de l'intégrité, c'est-à-dire lorsque la clause que l'on a spécifiée n'est pas
validée.
Si la clause CONSTRAINT n'est pas spécifiée, un nom sera donné arbitrairement par le
SGBD. Toutefois, le nom donné par le SGBD risque fortement de ne pas être compréhensible,
et ne sera vraisemblablement pas compris lorsqu'il y aura une erreur d'intégrité. La stipulation
de cette clause est donc fortement conseillée.

Des contraintes d'intégrité peuvent être alors ajoutées ou supprimées par la commande
ALTER TABLE. On peut aussi modifier l'état de contraintes par MODIFY CONSTRAINT. On ne
peut ajouter que des contraintes de table. Si on veut ajouter (ou modifier) une contrainte de
colonne, il faut modifier la colonne.
Exemple
ALTER TABLE EMP
DROP CONSTRAINT NOM_UNIQUE
ADD CONSTRAINT SAL_MIN CHECK (SAL + NVL (COMM,0) > 1000)
RENAME CONSTRAINT NOM1 TO NOM2
MODIFY CONSTRAINT SAL_MIN DISABLE

V. VUES
L’exécution d’une requête produit toujours une relation. Cela suggère la possibilité
d’ajouter au schéma des tables ’virtuelles’ qui ne sont rien d’autres que le résultat de

38
requêtes stockées. De telles tables sont nommées des vues dans la terminologie
relationnelle. On peut interroger des vues comme des tables stockées.
Une vue n’induit aucun stockage puisqu’elle n’existe pas physiquement, et permet
d’obtenir une représentation différente des tables sur lesquelles elle est basée.
On peut donner plusieurs définitions aux vues dans une base de données et chacune
de ces définitions est révélatrice des nombreuses vertus que nous offrent les vues.
Une vue est une structure logique basée sur une table ou une autre vue. A ce titre, on
peut remarquer qu’une vue ne peut exister que si sa table de base ou sa vue de base existe
bel et bien. On peut aussi dire qu’une vue est une table virtuelle ou une requête stockée.
Cette définition nous montre l’importance des vues sur le plan temps d’exécution des
requêtes. En effet, étant une requête compilée et stockée, on gagne en temps avec les vues
plutôt que d’utiliser une imbrication des sous requêtes qui prendront plus de temps dans la
phase de l’analyse, et ce chaque fois qu’elle sera invoquée.
Intérêts des vues :
• Simplification de l’accès aux données en masquant la complexité des éventuelles
opérations de jointures sous-jacentes.
• Sauvegarde indirecte des requêtes complexes.
• Présentation de mêmes données sous différentes formes adaptées aux différents
usagers.
• Support de l’indépendance logique : si la table de base est modifiée, les vues associées
doivent être refaites, mais les requêtes qui interrogent ces vues n’en sont pas
affectées.
• Renforce la sécurité des données dans la mesure où seules les lignes et colonnes
destinées à un utilisateur lui sont présentées.

V.1. Création et interrogation d’une vue


Une vue est tout point comparable à une table : en particulier on peut l’interroger par
SQL. La grande différence est qu’une vue est le résultat d’une requête, avec la
caractéristique essentielle que ce résultat est réévalué à chaque fois que l’on accède à la
vue. En d’autre termes une vue est dynamique : elle donne une représentation fidèle de la
base au moment de l’évaluation de la requête.
Une vue est essentiellement une requête à laquelle on a donné un nom. La syntaxe de
création d’une vue est très simple :
CREATE VIEW <nom-vue>
AS <requête>
[WITH CHECK OPTION]
CREATE [OR REPLACE ] VIEW vue [(Col1, .., Colk)] AS Requête

Exemple : on peut créer une vue qui ne contient que les cinémas parisiens :
CREATE VIEW ParisCinemas
AS SELECT * FROM Cinema WHERE ville = ’Paris’
On peut aussi en profiter pour restreindre la vision des cinémas parisiens à leur nom
et à leur nombre de salles.
CREATE VIEW SimpleParisCinemas
AS SELECT nom, COUNT(*) AS nbSalles
FROM Cinema c, Salle s
WHERE ville = ’Paris’
AND c.nom = s.nomCinema
GROUP BY c.nom
Enfin un des intérêts des vues est de donner une représentation dénormalisée de la
base, en regroupant des informations par des jointures. Par exemple on peut créer une vue
Casting donnant explicitement les titres des films, leur année et les noms et prénoms des
acteurs.
CREATE VIEW Casting (film, annee, acteur, prenom) AS
39
SELECT titre, annee, nom, prenom
FROM Film f, Role r, Artiste a
WHERE f.idFilm = r.idFilm
AND r.idActeur = a.idArtiste
Remarque : on a donné explicitement des noms d’attributs au lieu d’utiliser les
attributs de la clause SELECT.
Maintenant, on peut utiliser les vues et les tables dans des requêtes SQL. Par exemple
la requête : Quels acteurs ont tourné un film en 1997 s’exprime par :
SELECT acteur, prenom
FROM Casting
WHERE annee = 1997
On peut ensuite donner des droits en lecture sur cette vue pour que cette information
limitée soit disponible à tous.
GRANT SELECT ON Casting TO PUBLIC

V.2. Mise à jour et suppression d’une vue


L’idée de modifier une vue peut sembler étrange puisqu’une vue n’a pas de contenu.
En fait il s’agit bien entendu de modifier la table qui sert de support à la vue. Il existe de
sévères restrictions sur les droits d’insérer ou de mettre-à-jour des tables à travers les vues.
Un exemple suffit pour comprendre le problème.
Imaginons que l’on souhaite insérer une ligne dans la vue Casting.
INSERT INTO CASTING (film, annee, acteur, prenom)
VALUES (’Titanic’, 1998, ’DiCaprio’, ’Leonardo’);
Cet ordre s’adresse à une vue issue de trois tables. Il n’y a clairement pas assez
d’information pour alimenter ces tables de manière cohérente, et l’insertion n’est pas
possible (de même que toute mise à jour). De telles vues sont dites non modifiables.
Les règles définissant les vues modifiables sont très strictes.
1. La vue doit être basée sur une seule table.
2. Toute colonne non référencée dans la vue doit pouvoir être mise à NULL ou disposer
d’une valeur par défaut.
3. On ne peut pas mettre-à-jour un attribut qui résulte d’un calcul ou d’une opération.
Il est donc tout à fait possible d’insérer, modifier ou détruire la table Film au travers
de la vue Paris-Cinema.
INSERT INTO ParisCinema
VALUES (1876, ’Breteuil’, 12, ’Cite’, ’Lyon’)
En revanche, en admettant que la ville est définie à NOT NULL, il n’est pas possible
d’insérer dans SimpleParisCinemas.
L’insertion précédente illustre une petite subtilité : on peut insérer dans une vue, sans
être en mesure de voir la ligne insérée au travers de la vue par la suite ! Afin d’éviter ce
genre d’incohérence, SQL2 propose l’option WITH CHECK OPTION qui permet de garantir que
toute ligne insérée dans la vue satisfait les critères de sélection de la vue.
CREATE VIEW ParisCinemas
AS SELECT * FROM Cinema
WHERE ville = ’Paris’
WITH CHECK OPTION
L’insertion donnée en exemple ci-dessus devient impossible. Enfin on détruit une vue
avec la syntaxe courante SQL :
DROP VIEW ParisCinemas

VI. INDEX
Un index est un objet utilisé pour optimiser la recherche des éléments dans une table
à l'aide d'un pointeur. L’usage des index est transparent à l'utilisateur final dont les sens ne
peuvent qu’apprécier la rapidité ou la lenteur du système. Il incombe donc aux développeurs
et administrateurs de la base de données de bien choisir quel type d’index est bon pour leur
40
système. Lorsqu‘ils sont créés, leur but est de réduire les lectures physiques (le nombre
d'entrées/sorties) et par ricochet le temps de recherche des enregistrements. Lorsqu’une
recherche est effectuée sur une colonne qui n'a pas été indexée, la requête fait une
recherche séquentielle sur chaque ligne et vérifie si les critères de recherche lui sont
applicables. Par contre si la colonne a été indexée, le serveur localise directement les lignes
qui correspondent, d'où un gain de temps. Il faut cependant être vigilant quant à l'utilisation
des index car ils ne sont pas une garantie pour l'amélioration de la vitesse, car chaque
opération DML effectuée force le serveur à mettre à jour les index.

VI.1. Types d'index


Un index est une arborescence permettant d'accéder directement à une ligne
spécifique dans une table. Les index peuvent être classifiés en fonction de leur conception
(classification logique) ou de leur implémentation physique (classification physique).
Classification logique
Avec une classification logique, les index sont regroupés du point de vue de
l'application. Les différents types d'index logiques sont les suivants :
• Un index à une colonne comprend une seule colonne dans la clé d'index. Par exemple,
un index créé à partir de la colonne "empno" de la table "emp" est un index à une
colonne.
• Un index concaténé, également appelé index composé, est créé à partit de plusieurs
colonnes d'une table. Les colonnes d'un index concaténé ne doivent pas
nécessairement être dans le même ordre que les colonnes de la table. En outre, ces
colonnes ne sont pas forcément adjacentes. Par exemple, un index créé à partir des
colonnes "deptno" et "job" de la table "emp" est un index concaténé.
• Un index unique est un type d’index utilisé pour garantir que deux lignes d'une table
n'ont pas la même valeur dans la colonne qui définit l'index. Par conséquent, une clé
d'index d'un index unique ne peut pointer que vers une seule ligne d'une table. Ce type
d’index est souvent utilisé pour garantir les contraintes d’intégrité d’unicité de champ
ou de clé primaire.
• Dans un index non unique, une même clé peut avoir plusieurs lignes associées.
• Un index basé sur des fonctions est créé lorsqu’on utilise des fonctions ou des
expressions qui appellent une ou plusieurs colonnes dans la table indexée. Ce type
d’index pré-calcule la valeur de la fonction ou de l’expression et le stocke dans l’index
de la base de données. Les index basés sur des fonctions peuvent être crées comme B-
tree ou index bitmap.
• Les index de domaines sont des index propres à certaines applications (Text,
spatial…).

VI.2. Création d'index


CREATE [UNIQUE] INDEX [schema.]index ON [schema.]table
(column [ASC|DESC][,column [ASC|DESC]]...)
[TABLESPACE tablespace_name]
[PCTFREE integer]
[INITRANS integer]
[MAXTRANS interger]
[STORAGE clause]
[LOGGING | NOLOGGING]
[NOSORT];
Exemple :
Créons un index B-tree normal EMP_IND1 appartenant au schéma SCOTT. Cet index
doit être créé pour la table EMP dans le tablespace INDEX01 avec la valeur du paramètre
PCTFREE à 25. Créer l'index à partir de la colonne EMPNO.
CREATE INDEX SCOTT.EMP_IND1 ON SCOTT.EMP(EMPNO)
41
PCTFREE 25
TABLESPACE INDEX01;
Index created.

VI.3. Gestion d'index


Voici la syntaxe permettant de modifier les paramètres de stockage d'un index :
ALTER INDEX [schema.]index
[storage clause]
[INITRANS integer]
[MAXTRANS integer]
Exemple :
Pour augmenter l'espace disponible pour l'index EMP_IND1, il faut modifier ses
paramètres de stockage en augmentant la valeur des paramètres MAXEXTENTS et MAXTRANS
pour permettre à davantage d'extents et de transactions d'accéder à l'index simultanément.
ALTER INDEX SCOTT.EMP_IND1
MAXTRANS 255
STORAGE (MAXEXTENTS 200);
Index altered.

VI.4. Suppression d'un index


La syntaxe de la commande SQL permettant de supprimer un index est la suivante :
DROP INDEX [schéma.]index;

VI.5. Informations sur les index


Les index de la base de données peuvent être surveillés en extrayant des informations
générales sur ces index ou des informations relatives aux colonnes indexées à partir des vues
DBA_INDEXES : informations sur tous les index.
DBA_IND_COLUMNS: informations sur les colonnes de la clé d’index.
DBA_IND_EXPRESSIONS: informations sur les index bases sur une fonction.
V$OBJECT_USAGE : informations sur l’usage des index.
Tableau synoptique :
Contexte Référence
Paramètre d’initialisation CREATE_BITMAPàREA_SIZE
V$ Aucun
Tables et Vues du DD DBA_INDEXES
DBA_IND_COLUMNS
DBA_OBJECTS
IND$
INDEX_STATS
Commandes CREATE INDEX…
CREATE UNIQUE INDEX…
CREATE BITMAP INDEX…
CREATE INDEX ... REVERSE
ALTER INDEX ... STORAGE
ALTER INDEX ... INITRANS ... MAXTRANS
ALTER INDEX ... ALLOCATE EXTENT
ALTER INDEX ... DEALLOCATE UNUSED
ALTER INDEX .... REBUILD
ALTER INDEX .... REBUILD ... REVERSE
ALTER INDEX .... REBUILD ... NOREVERSE
ANALYZE INDEX ... VALIDATE STRUCTURE
DROP INDEX
Packages et Procédures Stockées Aucun

VII. DECLENCHEURS (TRIGGERS)


Théoriquement, les déclencheurs sont des routines (blocs de codes) stockées qui sont
lancées automatiquement par des évènements liés à des actions sur la base de données. Sur
42
le plan opérationnel, ils permettent d’assurer les règles de gestion assez complexes qui ne
peuvent se présentées sous la forme habituelle des contraintes d’intégrités classiques. Ce
sont des bouts de code écrits dans un langage procédural étendant le SQL d’Oracle, ils sont
stockés dans la base de données. Les évènements que ces blocs de codes interceptent sont
de natures variées :
• DML qui modifient des données dans une table (INSERT, DELETE or UPDATE).
• DDL
• Des évènements système tels que : le démarrage, l’arrêt, les messages d’erreurs.
• Des évènements liés aux utilisateurs tels que la connexion ou la déconnexion.
Les déclencheurs sont écrits en PL/SQL, JAVA ou C. Ils peuvent invoquer des
procédures stockées dans la base de données.

Exemple de bloc PL/SQL :


CREATE [ or replace ]TRIGGER trigger
{BEFORE | AFTER} {INSERT | DELETE | UPDATE} ON table
FOR EACH ROW
Bloc PL/SQL de traitement

VIII. SEQUENCES
Une séquence est un objet de la base de données qui génère des numéros uniques qui
pourront être insérés dans une colonne comme clé primaire. Les séquences ne sont pas des
objets propres à un schéma (utilisateur), ils peuvent donc être utilisés par tous les
utilisateurs.
Une séquence incrémente ou décrémente un compteur dans une routine Oracle (ce qui
génère un gain de temps et de codage). Il est possible de stocker les valeurs dans un cache,
ce qui accélèrera l'accès aux valeurs de la séquence.
CREATE SEQUENCE [schema.]séquence
[INCREMENT BY n]
[START WITH n]
[MAXVALUE n | NOMAXVALUE]
[MINVALUE n | NOMINVALUE]
[CYCLE | NOCYCLE]
[CACHE n | NOCACHE]
[ORDER | NOORDER];
Remarques
• Si aucune de ces clauses n’est définie, alors Oracle pose INCREMENT BY 1, START WITH
1.
• Si on pose INCREMENT BY -1, START WITH -1, alors Oracle construit une séquence
décroissante.
• On accède aux séquences avec les instructions par SELECT, INSERT, UPDATE.

Exemple :
DROP SEQUENCE RCCM.SEQ_PLCODEPERSONNEL;

CREATE SEQUENCE RCCM.SEQ_PLCODEPERSONNEL


START WITH 1
MAXVALUE 9999999999999999999999999999
MINVALUE 1
NOCYCLE
CACHE 50
NOORDER;

43
IX. PRIVILEGES
Un privilège attribué à un utilisateur lui donne l’accès à un certain nombre d’action
sur la base de données. On distingue les privilèges objets et les privilèges systèmes. Les
privilèges objets sont des droits accordés à un utilisateur afin qu’il puisse effectuer des
opérations DML sur des objets déjà existants. Les privilèges système sont des droits accordés
à un utilisateur pour effectuer des opérations DDL sur des objets inexistants ou déjà existants.
Un rôle est un ensemble de privilèges attribuables à des utilisateurs qui ont en commun
certaines tâches dans le système nécessitant les mêmes privilèges.
Pour qu’un exécuter une instruction sur le serveur Oracle, ce dernier doit détenir des
privilèges suffisants à cet effet. On distingue deux familles de privilèges : les privilèges
système et les privilèges objet.
IX.1. Les privilèges système
Les privilèges système sont les privilèges qui confère à un utilisateur de la base de
données de pourvoir de créer et de maintenir des objets de la base de donnés tels que les
synonymes, les tables, les séquences, etc. On dénombre plus de 100 privilèges système
repartis sur les différents objets de la base de données ou des domaines d’activité.
Objet ou Domaine d’Activité Privilèges
Fonction administrative ALTER SYSTEM
AUDIT SYSTEM
AUDIT ANY
ALTER DATABASE
ANALYSE ANY
SYSDBA
SYSOPER
GRANT ANY
Accès à la BD(Database Access) CREATE SESSION
ALTER SESSION
RESTRICTED SESSION
Tablespaces CREATE TABLESPACE
ALTER TABLESPACE
DROP TABLESPACE
MANAGE TABLESPACE
UNLIMITED TABLESPACE
Utilisateurs (Users) CREATE USER
BECOME USER
ALTER USER
DROP USER
Segments d’Annulation (Undo CREATE ROLLBACK SEGMENT
Segments) ALTER ROLLBACK SEGMENT
DROP ROLLBACK SEGMENT
Tables CREATE TABLE
CREATE ANY TABLE
ALTER ANY TABLE
BACKUP ANY TABLE
LOCK ANY TABLE
COMMENT ANY TABLE
DROP ANY TABLE
INSERT ANY TABLE
SELECT ANY TABLE
UPDATE ANY TABLE
DELETE ANY TABLE
Clusters CREATE CLUSTER

44
CREATE ANY CLUSTER
ALTER ANY CLUSTER
DROP ANY CLUSTER
Index CREATE ANY INDEX
ALTER ANY INDEX
DROP ANY INDEX
Synonymes (Synonyms)
Vues (Views) CREATE SYNOYM
CREATE ANY SYNONYM
DROP ANY SYNONYM
CREATE PUBLIC SYNONYM
DROP PUBLIC SYNOSYM
Séquences CREATE SEQUENCE
CREATE ANY SEQUENCE
ALTER ANY SEQUENCE
DROP ANY SEQUENCE
SELECT ANY SEQUENCE
Liens de BD (Database Links) CREATE DATABASE LINK
CREATE PUBLIC DATABASE LINK
DROP PUBLIC DATABASE LINKK
Rôles CREATE ROLE
DROP ANY ROLE
GRANT ANY ROLE
ALTER ANY ROLE
Transactions FORCE TRANSACTION
FORCE ANY TRANSACTION
PL/SQL CREATE PROCEDURE
CREATE ANY PROCEDURE
ALTER ANY PROCEDURE
DROP ANY PROCEDURE
EXECUTE ANY PROCEDURE
Déclencheurs (Triggers) CREATE TRIGGER
CREATE ANY TRIGGER
ALTER ANY TRIGGER
DROP ANY TRIGGER
Profils (Profiles) CREATE PROFILE
ALTER PROFILE
DROP PROFILE
ALTER RESOURCE COST
Vues matérialisées (Materialized CREATE SNAPSHOT
Views) CREATE ANY SNAPSHOT
Ou (Snapshot) LATER ANY SNAPSHOT
DROP ANY SNAPSHOT
Annuaires (Directories) CREATE ANY DIRECTORY
DROP ANY DIRECTORY
Types (Types) CREATE TYPE
CREATE ANY TYPE
ALTER ANY TYPE
DROP ANY TYPE
EXECUTE ANY TYPE
Bibliothèques (Libraries) CREATE LIBRARY
CREATE ANY LIBRARY
ALTER ANY LIBRARY
45
DROP ANY LIBRARY
EXECUTE ANY LIBTRARY

NB :
Tout privilège comportant le mot ANY est un privilège système
Les privilèges SYSDBA et SYSOPER
Seuls les utilisateurs habilités à faire des tâches administratives doivent se connectés
avec les privilèges SYSDBA et SYSOPER.
Catégorie Exemple
SYSOPER ALTER DATABASE ARCHIVELOG
RECOVER DATABASE
ALTER DATABASE BACKUP CONTROLFILE TO
ALTER DATABASE OPEN | MOUNT
SHUTDOWN
STARTUP
SYSDBA SYSOPER PRIVILEGES WITH ADMIN OPTION
CREATE DATABASE
ALTER DATABASE BEGIN/END BACKUP
RESTRICTED SESSION
RECOVER DATABASE UNTIL
IX.1.1. Attribution d’un privilège système
Pour attribuer un privilège système à un utilisateur le donateur doit lui-même avoir
reçu ce privilège avec l’option WITH ADMIN OPTION ou encore posséder au moins le privilège
GRANT ANY PRIVILEGE.
Syntaxe :
GRANT system_privilege [, system_privilege ]
TO {user | role | PUBLIC} [, {user | role | PUBLIC}]
[WITH ADMIN OPTION]
Sémantique:
system_privilege : spécifie le privilège système à accorder à un utilisateur ou un rôle.
PUBLIC : Attribut le système privilège à tous les utilisateurs
WITH ADMIN OPTION : permet à l’utilisateur d’attribuer à son tour le(s) privilège(s)
reçu(s) à d’autres utilisateurs ou rôles.
NB : cette opération peut également être réalisée avec OEM dans son module sécurité.
IX.1.2. Supprimer des privilèges système
Un privilège système peut être supprimé avec la commande REVOKE. Un utilisateur
peut supprimer un privilège système à un autre utilisateur dès lors qu’il possède un privilège
système avec ADMIN OPTION.
NB : il n’est pas nécessaire que celui qui révoque soit celui qui avait accordé le
privilège système.

Syntaxe:
REVOKE system_privileg [, system_privilege]
FROM {user | role | PUBLIC} [, {user|role|PUBLIC}]

IX.2. Les privilèges Objet


Un privilège objet un privilège accordé à un utilisateur pour exécuter une action sur
un objet de la base de données appartenant à un autre utilisateur. Par défaut, le propriétaire
d’un objet possède tous les droits sur cet objet, c’est également pour cette raison que le
propriétaire d’un objet ne saurait avoir besoin de privilèges objet supplémentaires sur l’objet
qui lui appartient. De même pour céder un privilège objet à un utilisateur, il être soi-même
propriétaire de cet objet ou alors avoir reçu le même privilège avec WITH GRANT OPTION.
46
Le tableau suivant présente les différents privilèges objets possibles.
Privilèges Table Vue Séquence Procédure
Objet
ALTER   
DELETE  
EXECUTE 
INDEX  
INSERT  
REFERENCES 
SELECT   
UPDATE  
IX.2.1. Attribution des Privilèges Objet
Syntaxe:
GRANT { object_privilege [(column_list)] [, object_privilege
[(column_list)]] |ALL [PRIVILEGES]}
ON [schema.]object
TO {user | role | PUBLIC} [, {user | role | PUBLIC} ]
[WITH GRANT OPTION]
Sémantique:
object_privilege : qui spécifie le privilège objet à attribuer
column_list : définit une colonne d’une table ou d’une vue (Cela ne peut être définit
uniquement lors d’ l’attribution des privilèges INSERT, REFERENCE ou UPDATE)
ALL : Accorde tous les privilèges pour l’objet qui a été accordé avec WITH ADMIN
OPTION
ON object : identifie l’objet sur lequel les privilèges ont été attribués
WITH GRANT OPTION : donne la possibilité d’attribué des privilèges objets à d’autre
utilisateurs ou rôle.
NB : ici WITH GRANT OPTION remplace WITH ADMIN OPTION qu’on avit pour les
privilèges système. Son effet est de céder au bénéficiaire le privilège de pourvoir céder les
privilèges reçus à autre utilisateur.
IX.2.2. Suppression des Privilèges Objet
L’instruction REVOKE est utilisé pour supprimer des privilèges objets. Pour supprimer
un privilège objet, l’utilisateur doit être celui qui l’a accordé.
Syntaxe:
REVOKE { object_privilege [(column_list)] [, object_privilege
[(column_list)] ] | ALL [PRIVILEGES]}
ON [schema.]object
TO {user|role|PUBLIC} [, {user|role|PUBLIC} ]
[CASCADE CONSTRAINTS]

Sémantique:
ALL : Supprime tous les privilèges objet qui ont été accordé à l’utilisateur
ON : Identifie l’objet sur lequel les privilèges objet sont supprimés
FROM : Identifie des utilisateurs ou des rôles qui ont leurs privilèges objets supprimés
CASCADE CONSTRAINTS : Supprime toutes les contraintes d’intégrité référentielle que
la suppression a définit en utilisant les privilèges REFERENCES ou ALL
Des effets en cascade peuvent être observés lors de la suppression d’un privilège
système relié à une opération de DML. Par exemple, si SELECT ANY TABLE est attribué à un
utilisateur et que ce dernier a créé des procédures utilisant la table, toutes les procédures
se trouvant dans le schéma de l’utilisateur doivent être recompilées avant qu’elles ne
puissent être réutilisées.
47
La suppression d’objet privilège aura aussi un effet en cascade quand WITH GRANT
OPTION est donné.
Bon à savoir:
 Un utilisateur désireux d’exécuter une procédure n’a pas besoin d’avoir les droits
respectifs sur les objets que la procédures manipule dans son code. Il n’a besoin que
du privilège EXECUTE. Cependant le propriétaire de la procédure lui a besoin de ces
privilèges. Ces privilèges doivent lui être cédés directement et non à travers des rôles.
 Une procédure stockée a besoin d’être recompilée
 Le retrait du privilège REFERENCES à un utilisateur qui en avait déjà usé pour créer
une CI référentielle pourrait poser des problèmes si l’on ne fait pas usage de l’option
CASCADE CONTRAINT. Cependant, l’usage de cette option entraîne également la
suppression de la CI créée par ce privilège.
Illustration: REVOKE REFERENCES ON emp FROM panky CASCADE CONSTRAINT
IX.3. Informations sur les privilèges
Quatre vues du dictionnaire de données permettent d’obtenir des informations sur les
privilèges :
Vue Contenu
DBA_SYS_PRIVS liste les privilèges système attribués aux utilisateurs et aux rôles.
SESSION_PRIVS liste les privilèges dont les utilisateurs disposent actuellement.
DBA_TAB_PRIVS liste toutes les attributions de privilèges sur tous les objets de la
base de données.
DBA_COL_PRIVS décrit toutes les attributions de privilèges sur les colonnes dans
la base de données.

48
CHAPITRE III : LE LANGAGE ORACLE PL SQL.
I. INTRODUCTION
Le PL de PL/SQL signifie Procedural Language. Le langage Oracle PL/SQL est un
langage procédural et est une extension procédurale du langage SQL. Il permet de grouper
des commandes et de les soumettre au noyau en un bloc unique de traitement. Le langage
SQL est non procédural alors que le PL/SQL est un langage procédural qui s’appuie sur toutes
les structures de programmations traditionnelles (variables, itérations, tests, séquences). Le
PL/SQL sert à programmer des procédures, des fonctions, des triggers, des packages. Le
PL/SQL s’intègre dans les outils SQL*FORMS, SQL*PLUS, PRO*C, ...il sert à programmer des
procédures, des fonctions, des triggers, et donc plus généralement, des packages.
Ecrivez-le dans un éditeur dont vous copierez le contenu dans SQL+. Un script écrit en
PL/SQL se termine obligatoirement par un /, sinon SQL+ ne l'interprète pas. S'il contient des
erreurs de compilation, il est possible d'afficher les messages d'erreur avec la commande
SQL+ : SHOW ERRORS.

Nous allons considérer le modèle physique suivant :

I.1. Structure d’un programme PL/SQL


Tout code écrit dans un langage procédural est formé de blocs. Chaque bloc comprend
une section de déclaration de variables, et un ensemble d'instructions dans lequel les
variables déclarées sont visibles. Un programme PL/SQL se décompose en trois parties :
DECLARE --section optionnelle
déclaration variables, constantes, types, curseurs,...

BEGIN --section obligatoire


contient le code PL/SQL

EXCEPTION --section optionnelle


traitement des erreurs
49
END; --obligatoire
• La zone DECLARE sert à la déclaration des variables, des constantes, ou des curseurs,
• La zone BEGIN constitue le corps du programme,
• La zone EXCEPTION permet de préciser les actions à entreprendre lorsque des erreurs
sont rencontrées (pas de référence article trouvée pour une insertion, ...),
• Le END répond au BEGIN précédent, il marque la fin du script.

Un bloc peut être imbriqué dans le code d’un autre bloc. Un sous-bloc peut aussi se
trouver dans la partie des exceptions.
DECLARE --section optionnelle
déclaration variables, constantes, types, curseurs,...

BEGIN --section obligatoire


contient le code PL/SQL
DECLARE --section optionnelle
déclaration variables, constantes, types, curseurs,...

BEGIN --section obligatoire


contient le code PL/SQL

EXCEPTION --section optionnelle


traitement des erreurs

END; --obligatoire
EXCEPTION --section optionnelle
traitement des erreurs

END; --obligatoire
Dans le code PL/SQL (partie procédural) nous pouvons avoir :
• des structures conditionnelles (IF-THEN-ELSE / IF-THEN-ELSIF / CASE)
• des structures répétitives (WHILE, LOOP, FOR,...)
• des ordres LMD (SELECT, UPDATE, DELETE, INSERT,...)
• des gestions de transactions (COMMIT, SAVEPOINT, ROLLBACK,...)
• des appels de fonctions, procédures, packages,...

I.2. Les différentes types de données


Les différents types utilisés pour les variables PL/SQL sont :

50
I.2.1. Conversion implicite
Le PL/SQL opère des conversions de type implicites en fonctions des opérandes en
présence. Il est nécessaire de bien connaître ces règles comme pour tous les langages.
Cependant, le typage implicite des variables (cf. paragraphe sur les variables) permet de
simplifier la déclaration des variables.

I.2.2. Conversion explicite


Le programmeur peut être maître d’œuvre du typage des données en utilisant des
fonctions standards comme to_char, to_date, etc. Des exemples seront donnés plus loin dans
le cours.

51
I.3. Gestion de l’affichage
Il est évidemment possible d’utiliser des fonctions prédéfinies d’entrée/sortie. Ces
fonctions servent essentiellement durant la phase de test des procédures PL/SQL (l’affichage
étant généralement géré du côté client). Par défaut, les fonctions d'affichage sont
désactivées. Il faut d’abord activer le package DBMS_OUTPUT par la commande SET
SERVEROUTPUT ON. Ensuite on peut utiliser la fonction PUT_LINE de ce package.
Pour afficher le contenu d'une variable, les procédures DBMS_OUTPUT.PUT() et
DBMS_OUTPUT.PUT_LINE() prennent en argument une valeur à afficher ou une variable dont
la valeur est à afficher.
affiche.sql
SET SERVEROUTPUT ON
DECLARE
message varchar2(100);
BEGIN
message := 'Essai d''affichage';
DBMS_OUTPUT.put_line ('Test : ' || message);
END;
/
Exécution
SQL> @affiche
Test : Essai d'affichage
PL/SQL procedure successfully completed.
Noter l’emploi de '' pour pouvoir afficher le caractère ', et du double pipe || pour pouvoir
concaténer plusieurs chaînes de caractères. La concaténation est souvent nécessaire car la
fonction put_line n’accepte qu’une seule chaîne de caractères en argument. Lorsque les
données affichées « défilent » trop vite on pourra utiliser deux méthodes :
• Utiliser la commande set pause on (une commande set pause off devra lui
correspondre pour revenir à la normale). Il faut alors frapper la touche RETURN pour
faire défiler les pages d’affichage.
• Utiliser la commande spool nom_fichier. Elle permet de diriger l’affichage, en plus
de la sortie standard qui est l’écran, vers un fichier nommé nom_fichier.lst. La
commande spool off est nécessaire pour arrêter la re-direction (attention aux fichiers
de spool qui grossissent inconsidérément).

I.4. Les variables et les constantes


La déclaration d’une variable ou d’une constante se fait dans la partie DECLARE d’un
programme PL/SQL. On peut déclarer le type d’une variable d’une façon implicite ou
explicite. Une variable se déclare de la sorte : nom type [ := initialisation] ;
L'initialisation est optionnelle. Les affectations se font avec la syntaxe variable :=
valeur ;
exemples:
SET SERVEROUTPUT ON
DECLARE
c varchar2 (15) := 'Hello World!' ;
BEGIN
DBMS_OUTPUT.PUT_LINE(c);
END;
/
DECLARE
nouveau_vol article.prixunit%TYPE ; -- type implicite
ancien_vol NUMBER ; -- type explicite
autre_vol NUMBER DEFAULT 0 ; -- initialisation à 0

52
L’utilisation de l’attribut %ROWTYPE permet à la variable d’hériter des
caractéristiques d’une ligne de table
DECLARE
V_vol vol%ROWTYPE ;
Si une variable est déclarée avec l’option CONSTANT, elle doit être initialisée. Si une
variable est déclarée avec l’option NOT NULL, elle doit être initialisée et la valeur NULL ne
pourra pas lui être affectée durant l’exécution du programme.
I.5. Les structures
Définition d’une structure art_qtecom (article et quantité commandée)
/* création du type enregistrement typ_vol*/
type typ_vol is record
( v_novol vol.no_vol%type ,
v_dest vol.destination%type
) ;
Déclaration d’une variable de type v_vol :
/* affectation du type typ_vol à v_vol*/
v_vol typ_vol;
Accès aux membres de la structure :
v_vol.v_dest := ‘Tahiti’;
Source complet
DECLARE
type typ_vol is record
( v_novol vol.no_vol%type ,
v_dest vol.destination%type
) ;
v_vol typ_vol;
BEGIN
v_vol.v_dest := ‘Tahiti’;
END;
/

II. LES INSTRUCTIONS DE BASES


II.1. Condition
Le IF et le CASE fonctionnent de la même façon que dans les autres langages impératifs
:
IF /* condition 1 */ THEN
/* instructions 1 */
ELSE
/* instructions 2 */
END IF ;
voire
IF /* condition 1 */ THEN
/* instructions 1 */
ELSIF /* condition 2 */
/* instructions 2 */
ELSE
/* instructions 3 */
END IF ;

Exemple : une société d’informatique augmente le salaire de ses employés d’un


montant variant de 100 à 500 euros, en fonction de la demande de leur supérieur hiérarchique
:
IF salaire < =1000 THEN
nouveau_salaire := ancien_salaire + 100;

53
ELSEIF salaire > 1000 AND emp_id_emp = 1 THEN
nouveau_salaire := ancien_salaire + 500;
ELSE nouveau_salaire := ancien_salaire + 300;
END IF;

II.2. L’expression CASE


L’expression CASE, introduite en version 8.1.6, permet d’implémenter en SQL une
logique de type IF…THEN…ELSE.
Première syntaxe
CASE expression
WHEN expression_comparaison THEN expression_résultat
[ … ]
[ ELSE expression_résultat_par_défaut ]
END
Ou encore
CASE /* variable */
WHEN /* valeur 1 */ THEN
/* instructions 1 */
WHEN /* valeur 2 */ THEN
/* instructions 2 */
...
WHEN /* valeur n */ THEN
/* instructions n */
ELSE
/* instructions par défaut */
END CASE;

• Toutes les expressions doivent être de même type.


• Oracle recherche la première clause WHEN..THEN, telle que expression est égale à
expression_comparaison et retourne : l’expression_résultat associée
• Si aucune clause WHEN…THEN ne vérifie cette condition et qu’une clause ELSE existe,
Oracle retourne l’expression_résultat_par_défaut associée
• NULL sinon
-- Exemple
BEGIN
FOR l IN (SELECT nom,sexe FROM employe WHERE emploi = ‘Aviateur’)
LOOP
CASE l.sexe
WHEN 'M' THEN
DBMS_OUTPUT.PUT_LINE('Monsieur' || l.nom);
WHEN 'F' THEN
DBMS_OUTPUT.PUT_LINE('Madame' || l.nom);
ELSE
DBMS_OUTPUT.PUT_LINE(l.nom);
END CASE;
END LOOP;
END;
/
Deuxième syntaxe
CASE
WHEN condition THEN expression_résultat
[ … ]
[ ELSE expression_résultat_par_défaut ]
END CASE
Même principes, que la première syntaxe, mais avec recherche de la première clause
WHEN…THEN telle que condition est vraie. La deuxième syntaxe offre plus de liberté dans les
54
conditions ; la première syntaxe est limitée à des conditions d’égalité. Par contre, pour des
conditions d’égalité, la première syntaxe est plus performante, l’expression étant évaluée
une seule fois. Bien noter que l’instruction CASE génère une exception si aucune condition
n’est vérifiée et qu’il n’y a pas de ELSE. S’il est normal qu’aucune condition ne soit vérifiée,
et qu’il n’y a rien à faire dans ce cas là, il est possible de mettre une clause ELSE NULL;
(l’instruction NULL ne faisant justement rien).
Par contre, dans les mêmes circonstances, l’expression CASE ne génère pas
d’exception mais retourne une valeur NULL.

Performance
CASE expression
WHEN expression1 THEN résultat1
WHEN expression2 THEN résultat2

est plus performant que
CASE
WHEN expression = expression1 THEN résultat1
WHEN expression = expression2 THEN résultat2

L’expression CASE ne supporte pas plus de 255 arguments, chaque clause WHEN…THEN
comptant pour 2.
-- Première syntaxe
SELECT
nom,
CASE sexe
WHEN 'M' THEN 'Monsieur'
WHEN 'F' THEN CASE mariée
WHEN 'O' THEN 'Madame'
WHEN 'N' THEN 'Mademoiselle'
END
ELSE 'Inconnu'
END CASE
FROM employe
/
--Deuxième syntaxe
SELECT
nom,
CASE sexe
WHEN sexe = 'M' THEN 'Monsieur'
WHEN sexe = 'F' AND mariée = 'O' THEN 'Madame'
WHEN sexe = 'F' AND mariée = 'N' THEN 'Mademoiselle'
ELSE 'Inconnu'
END CASE
FROM
employe
/
Il est possible d’avoir des instructions CASE imbriquées.

II.3. Expression GOTO


L’instruction GOTO effectue un branchement sans condition sur une autre commande
de la même section d’exécution d’un bloc PL/SQL. Le format d’une instruction GOTO est le
suivant :
GOTO Nom_Etiquette ;
<<Nom_Etiquette>>
instructions
Nom_Etiquette est le nom d’une étiquette identifiant l’instruction cible

55
Exemple :
BEGIN
GOTO deuxiemeàffichage
Dbms_output.putline(‘Cette ligne ne sera jamais affichée’) ;
<<deuxiemeàffichage>>
dbms_output.putline(‘Cette ligne sera toujours affichée’) ;
END ;
/
Limites de l’instruction GOTO
L’instruction GOTO comporte plusieurs limites :
• L’étiquette doit être suivie d’au moins un ordre exécutable
• L’étiquette cible doit être dans la même portée que l’instruction GOTO,
chacune des structures suivantes maintien sa propre portée : fonctions,
procédures blocs anonymes, instruction IF, boucles LOOP, gestionnaire
d’exceptions, instruction CASE.
• L’étiquette cible doit être dans la même partie de bloc que le GOTO

Expression NULL
Lorsque vous voulez demander au PL/SQL de ne rien faire, l’instruction NULL devient
très pratique. Le format d’une instruction NULL est le suivant :
NULL;
Le point-virgule indique qu’il s’agit d’une commande et non pas de la valeur NULL.
--
IF :etat.selection = ‘detail’ Then
Exec_etat_detaille;
Else
NULL ; -- ne rien faire
END IF ;

II.4. Itération
On dispose de l’instruction LOOP que l’on peut faire cohabiter avec les traditionnelles
WHILE et FOR. La commande EXIT permet d’interrompre la boucle.

LOOP ... END LOOP ; permet d'implémenter les boucles


LOOP
/* instructions */
END LOOP ;

L'instruction EXIT WHEN permet de quitter une boucle.


LOOP
/* instructions */
EXIT WHEN /* condition */ ;
END LOOP ;

La boucle FOR existe aussi en PL/SQL :


FOR /* variable */ IN /* inf */.. /*sup*/ LOOP
/* instructions */
END LOOP ;
Ou encore
FOR compteur IN borne_inférieure..borne_supérieure
LOOP
séquences
END LOOP;

Ainsi que la boucle WHILE :


WHILE /* condition */ LOOP
56
/* instructions */
END LOOP ;
Ou encore
WHILE condition
LOOP
séquences
END LOOP;

Exemple
OPEN curs1;
LOOP
FETCH curs1 into ancien_salaire;
EXIT WHEN curs1%NOTFOUND;
IF salaire <=1000 THEN
nouveau_salaire := ancien_salaire + 100;
ELSEIF salaire > 1000 AND emp_id_emp = 1 THEN
nouveau_salaire := ancien_salaire + 500;
ELSE nouveau_salaire := ancien_salaire + 300;
END IF;
UPDATE employe SET
salaire = nouveau_salaire
WHERE current of curs1;
END LOOP;

III. LES TABLEAUX


Un tableau en PL/SQL est en fait une table qui ne comporte qu’une seule colonne.
Cette colonne ne peut correspondre qu’à un type scalaire et non à un type composé (table
ou record).
La structure de données nécessaire pour gérer une table ORACLE nécessitera donc
autant de types tables que la table possède de colonnes. On pourra éventuellement
regrouper ces tables à l’intérieur d’un RECORD.
Une table PL/SQL est indexée par une clé de type BINARY_INTEGER.
III.1. Création d'un type tableau
Les types tableau doivent être définis explicitement par une déclaration de la forme
TYPE /*type*/ IS VARRAY (/*taille*/)OF /*typeElements*/ ;
• type est le nom du type tableau crée par cette instruction
• taille est le nombre maximal d'éléments qu'il est possible de placer dans le
tableau.
• typeElements est le type des éléments qui vont être stockés dans le tableau, il
peut s'agir de n'importe quel type.
Par exemple, créons un type tableau de nombres indicé de 1 à 10, que nous appelerons
numberTab
TYPE numberTab IS VARRAY (10) OF NUMBER;
III.2. Déclaration d'un tableau
Dorénavant, le type d'un tableau peut être utilisé au même titre que NUMBER ou
VARCHAR2. Par exemple, déclarons un tableau appelé t de type numberTab,
DECLARE
TYPE numberTab IS VARRAY (10) OF NUMBER;
t numberTab ;
BEGIN
/* instructions */
END;
/

57
III.3. Allocation d'un tableau
La création d'un type tableau met à disposition un constructeur du même nom que le
type crée. Cette fonction réserve de l'espace mémoire pour ce tableau et retourne l'adresse
mémoire de la zone réservée, il s'agit d'une sorte de malloc. Si, par exemple, un type tableau
numtab a été crée, la fonction numtab() retourne une tableau vide.
DECLARE
TYPE numberTab IS VARRAY (10) OF NUMBER;
t numberTab ;
BEGIN
t:= numberTab() ;
/* utilisation du tableau */
END;
/
Une fois cette allocation faite, il devient presque possible d'utiliser le tableau...
III.4. Dimensionnement d'un tableau
Le tableau retourné par le constructeur est vide. Il convient ensuite de réserver de
l'espace pour stocker les éléments qu'il va contenir. On utilise pour cela la méthode EXTEND().
EXTEND s'invoque en utilisant la notation pointée. Par exemple,
DECLARE
TYPE numberTab IS VARRAY (10) OF NUMBER;
t numberTab ;
BEGIN
t:=numberTab() ;
t.EXTEND(4) ;
/* utilisation du tableau */
END;
/
III.5. Utilisation d'un tableau
On accède, en lecture et en écriture, à l’i-ème élément d’une variable tabulaire
nommé T avec l’instruction T (i).
Les éléments sont indicés à partir de 1.
Exécutons, par exemple, une permutation circulaire vers la droite des éléments du
tableau t.
DECLARE
TYPE numberTab IS VARRAY (10) OF NUMBER;
t numberTab ;
i number ;
k number ;
BEGIN
t := numberTab ( ) ;
t.EXTEND ( 1 0 ) ;
FOR i IN 1..10 LOOP
t(i):=i ;
END LOOP;
k:=t(10) ;
FOR i in REVERSE 2..10 LOOP
t(i):=t(i-1) ;
END LOOP ;
t (1):=k ;
FOR i IN 1..10 LOOP
DBMS_OUTPUT.PUT_LINE(t(i)) ;
END LOOP ;
END;
/

58
IV. STRUCTURES
Une structure est un type regroupant plusieurs types. Une variable de type structuré
contient plusieurs variables, ces variables s'appellent aussi des champs.
IV.1. Création d'un type structuré
On définit un type structuré de la sorte :
TYPE /* nomType */ IS RECORD
(
/* liste des champs */
) ;
nomType est le nom du type structuré construit avec la syntaxe précédente. La liste
suit la même syntaxe que la liste des colonnes d'une table dans un CREATE TABLE. Par
exemple, construisons le type point (dans IR2),
TYPE point IS RECORD
(
abscisse NUMBER,
ordonnee NUMBER
) ;
Notez bien que les types servant à définir un type structuré peuvent être quelconques
: variables scalaires, tableaux, structures, etc.
Déclaration d'une variable de type structuré point est maintenant un type, il devient
donc possible de créer des variables de type point, la règle est toujours la même pour
déclarer des variables en PL/SQL, par exemple
p point ; permet de déclarer une variable p de type point.

IV.2. Utilisation d'une variable de type structuré


Pour accéder à un champ d'une variable de type structuré, en lecture ou en écriture,
on utilise la notation pointée :
v.c est le champ appelé c de la variable structuré appelée v. Par exemple,
DECLARE
TYPE point IS RECORD
(
abscisse NUMBER,
ordonnee NUMBER
) ;
p point ;
BEGIN
p.abscisse:=1;
p.ordonnee :=3;
DBMS_OUTPUT.PUT_LINE('p.abscisse= '|| p.abscisse||'and p.ordonnee ='||p.ordonnee);
END;
/
Le script ci-dessous crée le type point, puis crée une variable t de type point, et enfin
affecte aux champs abscisse et ordonnée du point p les valeurs 1 et 3.

V. TABLES ET STRUCTURES
Si vous ne tenez pas à vous prendre la tête pour choisir le type de chaque variable,
demandez-vous ce que vous allez mettre dedans ! Si vous tenez à y mettre une valeur qui se
trouve dans une colonne d'une table, il est possible de vous référer directement au type de
cette colonne avec le type nomTable.nomColonne%type. Par exemple,
DECLARE
num PRODUIT.numprod%type ;
nom PRODUIT.nomprod%type := 'Poupée Batman' ;
BEGIN
SELECT numprod INTO num
59
FROM PRODUIT
WHERE nomprod = nom;
DBMS_OUTPUT.PUT_LINE ('L''article '||nom||' a pour numéro '||num) ;
END;
/
Pour aller plus loin, il est même possible de déclarer une structure pour représenter
une ligne d'une table, le type porte alors le nom suivant : nomTable%rowtype.
DECLARE
nom PRODUIT.nomprod%type := 'Poupée Batman ' ;
ligne PRODUIT%rowtype ;
BEGIN
SELECT INTO ligne
FROM PRODUIT
WHERE nomprod = nom ;
DBMS_OUTPUT.PUT_LINE('L''article '||ligne.nomprod||' a pour numéro '||ligne.numprod ) ;
END;
/
VI. TRANSACTIONS
Un des mécanismes les plus puissants des SGBD récents réside dans le système des
transactions. Une transaction est un ensemble d'opérations atomiques", c'est-à-dire
indivisible. Nous considérerons qu'un ensemble d'opérations est indivisible si une exécution
partielle de ces instructions poserait des problèmes d'intégrité dans la base de données.
Par exemple, dans le cas d'une base de données de gestion de comptes en banque, un
virement d'un compte à un autre se fait en deux temps : créditer un compte d'une somme s,
et débiter un autre de la même somme s. Si une erreur survient pendant la deuxième
opération, et que la transaction est interrompue, le virement est incomplet et le patron va
vous assassiner.
Il convient donc de disposer d'un mécanisme permettant de se protéger de ce genre
de désagrément. Plutôt que se casser la tête à tester les erreurs à chaque étape et à balancer
des instructions permettant de revenir en arrière", nous allons utiliser les instructions COMMIT
et ROLLBACK.
Voici le squelette d'un exemple :
/*instructions*/
IF /*erreur*/ THEN
ROLLBACK;
ELSE
COMMIT;
END;
Le ROLLBACK annule toutes les modifications faites depuis le début de la transaction
(donc depuis le précédent COMMIT), COMMIT les enregistre définitivement dans la base de
données.
La variable d'environnement AUTOCOMMIT, qui peut être positionnée à ON ou à OFF
permet d'activer la gestion des transactions. Si elle est positionnée à ON, chaque instruction
a des répercussions immédiates dans la base, sinon, les modifications ne sont effectives
qu'une fois qu'un COMMIT a été exécuté.

VII. EXCEPTIONS
Le mécanisme des exceptions est implémenté dans la plupart des langages récent,
notamment orientés objet. Cette façon de programmer a quelques avantages immédiats :
• obliger les programmeurs à traiter les erreurs : combien de fois votre prof de C a hurlé
en vous suppliant de vérifier les valeurs retournées par un malloc, ou un fopen ? La
plupart des compilateurs des langages à exceptions (notamment java) ne compilent que
si pour chaque erreur potentielle, vous avez préparé un bloc de code (éventuellement
vide...) pour la traiter. Le but est de vous assurer que vous n'avez pas oublié d'erreur.
60
• Rattraper les erreurs en cours d'exécution : Si vous programmez un systéme de sécurité
de centrale nucléaire ou un pilote automatique pour l'aviation civile, une erreur de
mémoire qui vous afficherait l'écran bleu de windows, ou le message "Envoyer le rapport
d'erreur ?", ou plus simplement le fameux "Segmentation fault" produirait un effet des
plus mauvais. Certaines erreurs d'exécution sont rattrapables, autrement dit, il est
possible de résoudre le problème sans interrompre le programme.
• Ecrire le traitement des erreurs à part : Pour des raisons fiabilité, de lisibilité, il a été
considéré que mélanger le code "normal" et le traitement des erreurs était un style de
programmation perfectible... Dans les langages à exception, les erreurs sont traitées à
part.

VII.1. Rattraper une exception


Je vous ai menti dans le premier cours, un bloc en PL/SQL a la forme suivante :
DECLARE
/* déclarations */
BEGIN
/* instructions */
EXCEPTION
/* traitement des erreurs */
END;
Une exception est une "erreur type", elle porte un nom, au même titre qu'une variable
a un identificateur, par exemple GLUBARF. Lorsque dans les instructions, l'erreur GLUBARF
se produit, le code du BEGIN s'interrompt et le code de la section EXCEPTION est lancé. On
dit aussi que quand une exception est levée (raised) (on dit aussi jetée (thrown)), on la
rattrape (catch) dans le bloc EXCEPTION. La section EXCEPTION a la forme suivante :
EXCEPTION
WHEN E1 THEN
/* traitement */
WHEN E2 THEN
/* traitement */
WHEN E3 THEN
/* traitement */
WHEN OTHERS THEN
/* traitement */
END;
On énumère les erreurs les plus pertinentes en utilisant leur nom et en consacrant à
chacune d'elle un traitement particulier pour rattraper (ou propager) l'erreur. Quand un bloc
est traité, les WHEN suivants ne sont pas évalués.
OTHERS est l'exception par défaut, OTHERS est toujours vérifié, sauf si un cas
précédent a été vérifié. Dans l'exemple suivant :
DECLARE
/* déclarations */
BEGIN
/* instructions */
COMMIT;
EXCEPTION
WHEN GLUBARF THEN
ROLLBACK;
DBMS_OUTPUT.PUT_LINE ('GLUBARF exception raised!');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE ('SQLCODE = ' || SQLCODE);
DBMS_OUTPUT.PUT_LINE ('SQLERRM = ' || SQLERRM);
END;

61
Les deux variables globales SQLCODE et SQLERRM contiennent respectivement le code
d'erreur Oracle et un message d'erreur correspondant à la dernière exception levée. Chaque
exception a donc, en plus d'un nom, un code et un message.

VII.2. Exceptions prédéfinies


Bon nombre d'exceptions sont prédéfinies par Oracle, par exemple
• NO DATA FOUND est levée quand la requête d'une instruction de la forme SELECT ...
INTO ... ne retourne aucune ligne
• TOO MANY ROWS est levée quand la requête d'une instruction de la forme SELECT ...
INTO ... retourne plusieurs lignes
• DUP VAL ON INDEX est levée si une insertion (ou une modification) est refusée à cause
d'une contrainte d'unicité.
On peut enrichir notre exemple de la sorte :
DECLARE
num NUMBER;
nom VARCHAR2(30) := 'Poupée Batman ' ;
BEGIN
SELECT numprod INTO num
FROM PRODUIT
WHERE nomprod = nom;
DBMS_OUTPUT.PUT_LINE ('L ''article'||nom || 'a pour numéro '|| num ) ;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE ('Aucun article ne porte le nom ' || nom) ;
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE ('Plusieurs articles portent le nom ' || nom ) ;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE ( ' Il y a un gros probléme...' ) ;
END;
/
SELECT numprod INTO num... lève une exception si la requête renvoie un nombre de lignes
différent de 1.

VII.3. Codes d'erreur


Certaines exceptions n'ont pas de nom. Elles ont seulement un code d'erreur, il est
conseillé de se reporter à la documentation pour les obtenir. On les traite de la façon suivante
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = CODE1 THEN
/* traitement */
ELSIF SQLCODE = CODE2 THEN
/* traitement */
ELSE
DBMS_OUTPUT.PUT_LINE ('J'' vois pas c'' que ca peut être...') ;
END;
C'est souvent le cas lors de violation de contraintes.

VII.4. Déclarer et lancer ses propres exceptions


Exception est un type, on déclare donc les exceptions dans une section DECLARE. Une
exception se lance avec l'instruction RAISE. Par exemple,

DECLARE
GLUBARF EXCEPTION;
BEGIN
RAISE GLUBARF;
62
EXCEPTION
WHEN GLUBARF THEN
DBMS_OUTPUT.PUT_LINE (' glubarf raised.') ;
END;
/

VIII. SOUS-PROGRAMMES
VIII.1. Procédures
VIII.1.1. Syntaxe
On définit une procédure de la sorte
CREATE OR REPLACE PROCEDURE /* nom */ (/* parametres */) IS
/* declaration des variables locales */
BEGIN
/* instructions */
END;
Les paramètres sont une simple liste de couples nom type. Par exemple, la procédure
suivante affiche un compte à rebours.
CREATE OR REPLACE PROCEDURE compteARebours (n NUMBER) IS
BEGIN
IF n >= 0 THEN
DBMS_OUTPUT.PUT_LINE (n);
compteARebours ( n-1 ) ;
END IF;
END;
VIII.1.2. Invocation
En PL/SQL, une procédure s'invoque tout simplement avec son nom. Mais sous SQL+,
on doit utiliser le mot-clé CALL. Par exemple, on invoque le compte à rebours sous SQL+ avec
la commande CALL compteARebours(20).
Passage de paramètres
Oracle permet le passage de paramètres par référence. Il existe trois types de passage
de paramètres :
• IN : passage par valeur
• OUT : aucune valeur passée, sert de valeur de retour
• IN OUT : passage de paramètre par référence
Par défaut, le passage de paramètre se fait de type IN.
CREATE OR REPLACE PROCEDURE incr (val IN OUT NUMBER) IS
BEGIN
val := val + 1 ;
END;

VIII.2. Fonctions
VIII.2.1. Syntaxe
On crée une nouvelle fonction de la fa_con suivante :
CREATE OR REPLACE FUNCTION /*nom*/ (/* parametres */) RETURN /*type*/ IS
/* declaration des variables locales */
BEGIN
/* instructions */
END;
L'instruction RETURN sert à retourner une valeur. Par exemple,
CREATE OR REPLACE FUNCTION module (a NUMBER, b NUMBER) RETURN NUMBER IS
BEGIN
IF a < b THEN
RETURN a;
ELSE
RETURN module (a - b,b) ;
63
END IF ;
END;
VIII.2.2. Invocation
Tout comme les procédures, l'invocation des fonctions ne pose aucun problème en
PL/SQL, par contre, sous SQL+, c'est quelque peu particulier. On passe par une pseudo-table
nommée DUAL de la façon suivante :

SELECT module (21,12) FROM DUAL ;


Passage de paramètres
Les paramètres sont toujours passés avec le type IN.

IX. 1.6 CURSEURS


IX.1. Introduction
Les instructions de type SELECT ... INTO ... manquent de souplesse, elles ne
fonctionnent que sur des requêtes retournant une et une seule valeur. Ne serait-il pas
intéressant de pouvoir placer dans des variables le résultat d'une requête retournant plusieurs
lignes ?
IX.2. Les curseurs
Un curseur est un objet contenant le résultat d'une requête (0, 1 ou plusieurs lignes).
Déclaration
Un curseur se déclare dans une section DECLARE :
CURSOR /* nomcurseur */ IS /* requ$ete */ ;
Par exemple, si on tient à récupérer tous les employés de la table EMP, on déclare le
curseur suivant.
CURSOR emp_cur IS SELECT * FROM EMP;
Ouverture
Lors de l'ouverture d'un curseur, la requête du curseur est évaluée, et le curseur
contient toutes les données retournées par la requête. On ouvre un curseur dans une section
BEGIN :
OPEN /* nomcurseur */;
Par exemple,
DECLARE
CURSOR emp_cur IS SELECT * FROM EMP;
BEGIN
OPEN emp_cur ;
/* Utilisation du curseur */
END;
Lecture d'une ligne
Une fois ouvert, le curseur contient toutes les lignes du résultat de la requête On les
récupère une par une en utilisant le mot-clé FETCH :
FETCH /* nom curseur */ INTO /* liste variables */;
La liste de variables peut ^être remplacée par une structure de type nom
curseur%ROWTYPE. Si la lecture de la ligne échoue, parce qu'il n'y a plus de ligne à lire,
l'attribut %NOTFOUND prend la valeur vrai.
DECLARE
CURSOR emp_cur IS
SELECT * FROM EMP ;
ligne emp_cur%rowtype
BEGIN
OPEN emp_cur;
LOOP
FETCH emp_cur INTO ligne ;
EXIT WHEN emp_cur%NOTFOUND ;
DBMS_OUTPUT.PUT_LINE ( ligne.ename ) ;

64
END LOOP ;
/*...*/
END;
Fermeture
Aprés utilisation, il convient de fermer le curseur.
CLOSE /* nomcurseur */ ;
Complétons notre exemple,
DECLARE
CURSOR emp_cur IS
SELECT * FROM EMP;
ligne emp_cur%rowtype ;
BEGIN
OPEN emp_cur ;
LOOP
FETCH emp_cur INTO ligne;
EXIT WHEN emp_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE (ligne.ename) ;
END LOOP;
CLOSE emp_cur;
END;
/
Le programme ci-dessus peut aussi s'écrire
DECLARE
CURSOR emp_cur IS
SELECT * FROM EMP;
ligne emp_cur%rowtype ;
BEGIN
OPEN emp_cur ;
FETCH emp_cur INTO ligne;
WHILE emp_cur%FOUND LOOP
DBMS_OUTPUT.PUT_LINE (ligne.ename );
FETCH emp_cur INTO ligne;
END LOOP;
CLOSE emp_cur;
END;
Boucle FOR
Il existe une boucle FOR se chargeant de l'ouverture, de la lecture des lignes du curseur
et de sa fermeture,
FOR ligne IN emp_cur LOOP
/* Traitement */
END LOOP ;
Par exemple,
DECLARE
CURSOR emp_cur IS
SELECT * FROM EMP;
ligne emp_cur%rowtype ;
BEGIN
FOR ligne IN emp_cur LOOP
DBMS_OUTPUT.PUT_LINE ( ligne.ename ) ;
END LOOP ;
END;
/

X. CURSEURS PARAMETRES
X.1. Introduction
A votre avis, le code suivant est-il valide ?
DECLARE
65
NUMBER n := 14 ;
BEGIN
DECLARE
CURSOR C IS
SELECT * FROM PERSONNE
WHERE numpers >= n;
ROW C%rowType ;
BEGIN
FOR ROW IN C LOOP
DBMS_OUTPUT.PUT_LINE (ROW.numpers);
END LOOP;
END;
END;
/
Réponse : non. La requête d'un curseur ne peut pas contenir de variables dont les
valeurs ne sont pas fixées.
Pourquoi ? Parce que les valeurs des n sont susceptibles de changer entre la Déclaration
du curseur et son ouverture.
Le remède est un curseur paramétré.
X.2. Définition
Un curseur paramétré est un curseur dont la requête contient des variables dont les
valeurs ne seront fixées qu'à l'ouverture.
X.3. Déclaration
On précise la liste des noms et des type des paramètres entre parenthèses après le
nom du curseur :
CURSOR /* nom */ (/* liste des paramètres */) IS
/* requête */
Par exemple, créons une requête qui, pour une personne donnée, nous donne la liste
des noms et prénoms de ses enfants :
CURSOR enfants(numparent NUMBER) IS
SELECT * FROM PERSONNE WHERE pere = numparent OR mere = numparent ;
X.4. Ouverture
On ouvre un curseur paramétré en passant en paramètre les valeurs des variables :
OPEN /* nom */ (/* liste des paramètres */)
Par exemple, OPEN enfants (1) ;

X.5. Lecture d'une ligne, fermeture


La lecture d'une ligne suit les mêmes règles qu'avec un curseur non paramétré.

X.6. Boucle pour


La boucle pour se charge de l'ouverture, il convient donc de placer les paramètres dans
l'entête de la boucle,
FOR /* variable */ IN /*nom*/ (/* liste paramètres */) LOOP
/* instructions */
END LOOP;
Par exemple,
FOR e IN enfants (1) LOOP
DBMS_OUTPUT.PUT_LINE (e.nompers || ' ' || e.prenompers );
END LOOP;
X.7. Exemple récapitulatif
DECLARE
CURSOR parent IS
SELECT * FROM PERSONNE;
p parent%rowtype ;
CURSOR enfants (numparent NUMBER) IS
66
SELECT * FROM PERSONNE
WHERE pere = numparent OR mere = numparent ;
e enfants%rowtype ;
BEGIN
FOR p IN parent LOOP
DBMS_OUTPUT.PUT_LINE ('Les enfants de '||p.prenom||' '||p.nom||' sont: ');
FOR e IN enfants (p.numpers ) LOOP
DBMS_OUTPUT.PUT_LINE ( ' _ ' || e.prenom || ' ' || e.nom ) ;
END LOOP;
END LOOP ;
END;
/
XI. TRIGGERS
XI.1. Principe
Un trigger est une procédure stockée qui se lance automatiquement lorsqu'un
événement se produit. Par événement, on entend dans ce cours toute modification des
données se trouvant dans les tables. On s'en sert pour contrôler ou appliquer des contraintes
qu'il est impossible de formuler de façon déclarative.
XI.2. Classification
Type d'événement
Lors de la création d'un trigger, il convient de préciser quel est le type d'événement
qui le déclenche. Nous réaliserons dans ce cours des triggers pour les événements suivants :
• INSERT
• DELETE
• UPDATE
Moment de l'exécution
On précise aussi si le trigger doit être exécuté avant (BEFORE) ou après (AFTER)
l'événement.
Evénements non atomiques
Lorsque l'on fait un DELETE ..., il y a une seule instruction, mais plusieurs lignes sont
affectées. Le trigger doit-il être exécuté pour chaque ligne affectée (FOR EACH ROW), ou
seulement une fois pour toute l'instruction (STATEMENT) ?
• un FOR EACH ROW TRIGGER est exécuté à chaque fois qu'une ligne est affectée.
• un STATEMENT TRIGGER est exécutée à chaque fois qu'une instruction est lancée.
XI.3. Création
Syntaxe
On déclare un trigger avec l'instruction suivante :
CREATE OR REPLACE TRIGGER nomtrigger
[ BEFORE | AFTER ] [INSERT | DELETE | UPDATE] ON nomtable
[ FOR EACH ROW j ]
DECLARE
/* déclarations */
BEGIN
/* instructions */
END;
Par exemple,
CREATE OR REPLACE TRIGGER pasDeDeleteDansClient
BEFORE DELETE ON CLIENT
BEGIN
RAISE_APPLICATION_ERROR (-20555, 'Va te faire...’) ;
END;
/
Déclencheur créé.

67
SQL> SELECT COUNT(*)FROM CLIENT ;
COUNT(* )
---------
21
SQL> DELETE FROM CLIENT;
SQL> DELETE FROM CLIENT
*
ERREUR à la ligne 1 :
ORA-20555: Va te faire.. .
ORA-06512: à "SCOTT.PASDEDELETEDANSCLIENT" , ligne 2
ORA-04088: erreur lors de l’exécutions du déclencheur
'SCOTT.PASDEDELETEDANSCLIENT'
SQL> SELECT COUNT(*) FROM CLIENT ;
COUNT(*)
-----------------
21
L'instruction RAISE_APPLICATION_ERROR(code, message) lève une exception sans nom
portant un code code et un message d'erreur message. Vous remarquez que comme l'erreur
a été levée avant la suppression, les données sont toujours présentes dans la table CLIENT.
Le trigger a contrôlé une règle, et comme elle n'était pas respectée, il a lancé une erreur.
Combinaisons d'événements
Il est possible, en séparant les types d'événement par le mot-clé OR, de définir un
trigger déclenché par plusieurs événements. Les variables booléennes INSERTING, UPDATING
et DELETING permettent d'identifier l'événement qui a déclenché le trigger.
CREATE OR REPLACE TRIGGER afficheEvenement
BEFORE INSERT OR UPDATE OR DELETE ON CLIENT
FOR EACH ROW
BEGIN
IF INSERTING THEN
DBMS_OUTPUT.PUT_LINE ('Insertion dans CLIENT');
ELSIF UPDATING THEN
DBMS_OUTPUT.PUT_LINE ('Mise à jour dans CLIENT');
ELSE
DBMS_OUTPUT.PUT_LINE ('Suppression dans CLIENT');
END IF;
END;
XI.4. Accès aux lignes en cours de modification
Dans les FOR EACH ROW triggers, il est possible avant la modification de chaque ligne,
de lire l'ancienne ligne et la nouvelle ligne par l'intermédiaire des deux variables structurées
:old et :new. Par exemple le trigger suivant empêche de diminuer un salaire :
CREATE OR REPLACE TRIGGER pasDeBaisseDeSalaire
BEFORE UPDATE ON EMP
FOR EACH ROW
BEGIN
IF (:old.sal > : new.sal) THEN
RAISE_APPLICATION_ERROR (-20567,'Pas de baisse de salaire!');
END IF;
END;
Tables en mutation
Il est impossible, dans un trigger de type FOR EACH ROW de faire un SELECT sur la
table en cours de modification.
CREATE OR REPLACE TRIGGER beforeStatement
BEFORE UPDATE ON CLIENT
DECLARE
NB NUMBER;

68
BEGIN
SELECT COUNT(*) INTO NB FROM CLIENT ;
END;
/
Déclencheur créé .
CREATE OR REPLACE TRIGGER afterStatement
AFTER UPDATE ON CLIENT
DECLARE
NB NUMBER;
BEGIN
SELECT COUNT(*) INTO NB FROM CLIENT;
END;
/
Déclencheur créé.
SQL> UPDATE CLIENT SET nomcli=nomcli ;
21 ligne(s) mise(s) à jour.
CREATE OR REPLACE TRIGGER beforeForEachRow
BEFORE UPDATEON CLIENT
FOR EACH ROW
DECLARE
NB NUMBER;
BEGIN
SELECT COUNT(*) INTO NB FROM CLIENT;
END;
/
Déclencheur créé.
SQL> UPDATE CLIENT SET nomcli = nomcli ;
UPDATE CLIENT SET nomcli = nomcli
--
ERREUR à la ligne 1 :
ORA-04091: la table SCOTT.CLIENT est en mutation ; le déclencheur ou la
fonction ne peut la voir
ORA-06512: à "SCOTT.BEFOREFOREACHROW», ligne 4
ORA-04088: erreur lors de l’exécution du déclencheur
'SCOTT.BEFOREFOREACHROW'
SQL> DROP TRIGGER beforeForEachRow ;
Déclencheur supprimé .

CREATE OR REPLACE TRIGGER afterForEachRow


AFTER UPDATEON CLIENT
FOR EACH ROW
DECLARE
NB NUMBER;
BEGIN
SELECT COUNT(*) INTO NB
FROM CLIENT ;
END;
Déclencheur créé .
SQL> UPDATE CLIENT SET nomcli = nomcli ;
UPDATE CLIENT SET nomcli = nomcli
--
ERREUR à la ligne 1 :
ORA-04091: la table SCOTT.CLIENT est en mutation ; le déclencheur ou la
fonction ne peut la voir
ORA-06512: à "SCOTT.AFTERFOREACHROW", ligne 4
ORA-04088: erreur lors de l’exécution du déclencheur 'SCOTT.AFTERFOREACHROW'

69
XI.5. Contourner le problème des tables en mutation
Il existe plusieurs façons de contourner ce problème :
• Utiliser un STATEMENT trigger. Comme on ne sait pas quelles lignes ont été modifiées,
on est obligé de toutes les traiter. Cette approche présente donc un inconvénient
majeur : elle nous amène à effectuer de nombreux traitements inutiles.
• En ayant des données redondantes. Il suffit que les données servant à la vérification se
trouvent dans une autre table que celle en mutation. Cette méthode a pour
inconvénient la mémoire occupée et la quantité de code à écrire pour maintenir la
cohérence des données. Dans la plupart des cas, cette solution est malgré tout la
meilleure.
Colonnes supplémentaires
Par exemple, si l'on souhaite empêcher un client d'avoir plus de 10 comptes en banque,
une solution est de placer dans la table client une colonne contenant le nombre de comptes.
ALTER TABLE CLIENT ADD nbComptes number ;
UPDATE CLIENT SET nbComptes = 0 ;
Une fois cette table crée, il convient de s'assurer que les données de la colonne
nbComptes contient toujours les bonnes valeurs. On le fait avec plusieurs sous-programmes :
CREATE OR REPLACE TRIGGER metAJourNbComptes
AFTER INSERT OR UPDATE OR DELETE ON COMPTECLIENT
BEGIN
UPDATE CLIENT SET nbComptes =
(
SELECT COUNT(*)
FROM COMPTECLIENT CC
WHERE CC.numCli = numCli
) ;
END;
/
CREATE OR REPLACE TRIGGER verifieNbComptes
BEFORE INSERT ON COMPTECLIENT
FOR EACH ROW
DECLARE
nbComptes NUMBER;
BEGIN
SELECT nbComptes INTO nbComptes
FROM CLIENT
WHERE numCli =:new.numcli;
IF (nbComptes >= 10) THEN
RAISE_APPLICATION_ERROR (-20556,'Ce client a déjà trop de comptes') ;
END IF ;
END;
/
On peut affiner en remplaçant metAJourNbComptes par plusieurs sous-programmes :
CREATE OR REPLACE TRIGGER initialiseNbComptes
BEFORE INSERT ON CLIENT
FOR EACH ROW
BEGIN
: new.nbComptes := 0 ;
END;
/
CREATE OR REPLACE TRIGGER metAJourNbComptes
AFTER INSERT OR UPDATE OR DELETE ON COMPTECLIENT
FOR EACH ROW
BEGIN
IF DELETING OR UPDATING THEN
UPDATE CLIENT SET nbComptes = nbComptes 1
70
WHERE numcli = :old.numcli ;
END IF ;
IF INSERTING OR UPDATING THEN
UPDATE CLIENT SET nbComptes = nbComptes + 1
WHERE numcli = :new.numcli ;
END IF;
END;
/
Tables supplémentaires
Si l'on souhaite par exemple empêcher les circuits dans la table PERSONNE, il est
nécessaire de faire un parcours de graphe. Ce qui nécessite des SELECT dans la table en cours
de mutation. La seule solution est dans ce cas d'avoir une table miroir qui contient les
colonnes clés primaire et étrangères de cette table, et de s'en servir pour détecter les
circuits.
CREATE TABLE MIRRORPERSONNE
(
numpers NUMBERPRIMARY KEY,
pere NUMBER,
mere NUMBER
) ;
Nous allons ensuite procéder de même, en répercutant chaque opération de PERSONNE
sur MIRRORPERSONNE.
CREATE OR REPLACE TRIGGER miseAJourMirrorPersonne
BEFORE UPDATE OR INSERT OR DELETE ON PERSONNE
FOR EACH ROW
BEGIN
IF DELETING OR UPDATING THEN
DELETE FROM MIRRORPERSONNE
WHERE numpers = :old.numpers ;
END IF;
IF INSERTING OR UPDATING THEN
INSERT INTO MIRRORPERSONNE VALUES
( :new.numpers , :new.pere , :new.mere ) ;
END IF ;
END;
/
Une fois cela fait, il suffit de rechercher si une personne insérée est une descendante
d'elle même dans MIRRORPERSONNE.
CREATE OR REPLACE FUNCTION trouveCircuit (current NUMBER, toFind NUMBER)
RETURN BOOLEAN IS
numPere NUMBER;
numMere NUMBER;
BEGIN
IF (current IS NULL) THEN
RETURN FALSE;
END IF;
SELECT pere, mere INTO numPere, numMere
FROM MIRRORPERSONNE
WHERE numPers = current;
RETURN (numPere = toFind OR numMere = toFind OR
trouveCircuit ( numPere , toFind ) OR
trouveCircuit ( numMere , toFind ) ) ;
END;
/
CREATE OR REPLACE TRIGGER verifieCircuit
AFTER UPDATE OR INSERT ON PERSONNE
FOR EACH ROW
71
BEGIN
IF ( trouveCircuit ( : new.numPers , : new.numPers ) ) THEN
RAISE_APPLICATION_ERROR (-20557, 'Circuit dans l''arbre généalogique.');
END IF ;
END;
/

XII. PACKAGES
XII.1. Principe
Un package est un ensemble de sous-programmes et de variables formé par
• Une spécification : Déclaration de variables et de sous-programmes
• Un corps : implémentation des sous-programmes
Tout ce qui se trouve dans la spécification doit se trouver dans le corps, mais la
réciproque est fausse. Un package satisfait les points suivants :
• encapsulation : certains traitements sont masqués, seule la spécification du package est
visible. Cela a pour avantage de simplifier la tâche de celui qui va utiliser le package.
• modularité : il est possible de développer séparément les diverses parties de
l'application. le développement devient ainsi un assemblage de package.
Ces deux aspects fournissent une souplesse certaine au niveau du développement : il
est possible de modifier le corps d'un package sans changer sa spécification, donc sans
modifier le fonctionnement de l'application.

XII.2. Spécification
La syntaxe permettant de créer l'entête est la suivante :
CREATE OR REPLACE PACKAGE nompackage IS
/*
déclarations
*/
END nomPackage ;
/
Par exemple,
CREATE OR REPLACE PACKAGE compteur IS
procedure reset ;
function nextValue return number ;
END compteur ;
/
XII.3. Corps
La syntaxe permettant de créer le corps est la suivante :
CREATE OR REPLACE PACKAGE BODY nompackage IS
/*
implementation
*/
END nomPackage ;
/
Par exemple,
CREATE OR REPLACE PACKAGE BODY compteur IS
cpt NUMBER := 0 ;
PROCEDURE reset IS
BEGIN
cpt := 0 ;
END;
FUNCTION nextValue RETURN NUMBER IS
BEGIN
cpt := cpt + 1 ;
RETURN cpt - 1 ;
72
END;
END compteur ;

/
On peut utiliser un package depuis n'importe quel script PL/SQL :
DECLARE
nb NUMBER;
BEGIN
FOR nb IN 4..20 LOOP
DBMS_OUTPUT.PUT_LINE (COMPTEUR.nextValue()) ;
END LOOP;
COMPTEUR.RESET();
FOR nb IN REVERSE 0..10 LOOP
DBMS_OUTPUT.PUT_LINE (COMPTEUR.nextValue()) ;
END LOOP ;
END;
/

73

S-ar putea să vă placă și