Base de Donnes Web
Base de Donnes Web
1. Principe de base
1.1. Bases de données et SGBD
Une Base de Données (BD) est un ensemble structuré d'informations mémorisées sur un
support permanent et mises à disposition d'un ensemble d'utilisateurs, informaticiens ou
non.
Un Système de Gestion de Base de Données (SGBD) est un logiciel général qui permet à
l'utilisateur de manipuler les données dans des termes abstraits, sans tenir compte de la
façon dont l'ordinateur les représente.
1.2. Objectifs
Des objectifs principaux ont été fixés aux SGBD dès l’origine de ceux-ci et ce, afin de
résoudre les problèmes causés par le système de fichier classique. Ces objectifs sont les suivants:
Indépendance physique : La façon dont les données sont définies doit être indépendante des
structures de stockage utilisées.
Indépendance logique : Un même ensemble de données peut être vu différemment par des
utilisateurs différents. Toutes ces visions personnelles des données doivent être intégrées dans
une vision globale.
Accès aux données : L’accès aux données se fait par l’intermédiaire d’un Langage de
Manipulation de Données (LMD). Il est crucial que ce langage permette d’obtenir des réponses
aux requêtes en un temps « raisonnable ». Le LMD doit donc être optimisé, minimiser le nombre
d’accès disques, et tout cela de façon totalement transparente pour l’utilisateur.
Administration centralisée des données (intégration) : Toutes les données doivent être
centralisées dans un réservoir unique commun à toutes les applications. En effet, des visions
différentes des données (entre autres) se résolvent plus facilement si les données sont
administrées de façon centralisée.
Non redondance des données : Afin d’éviter les problèmes lors des mises { jour, chaque
donnée ne doit être présente qu’une seule fois dans la base.
4
Cohérence des données : Les données sont soumises à un certain nombre de contraintes
d’intégrité qui définissent un état cohérent de la base. Elles doivent pouvoir être exprimées
simplement et vérifiées automatiquement à chaque insertion, modification ou suppression des
données. Les contraintes d’intégrité sont décrites dans le Langage de Description de Données
(LDD).
Partage des données : Il s’agit de permettre { plusieurs utilisateurs d’accéder aux mêmes
données au même moment de manière transparente. Si ce problème est simple à résoudre
quand il s’agit uniquement d’interrogations, cela ne l’est plus quand il s’agit de modifications
dans un contexte multiutilisateurs car il faut : permettre à deux (ou plus) utilisateurs de modifier
la même donnée « en même temps » et assurer un résultat d’interrogation cohérent pour un
utilisateur consultant une table pendant qu’un autre la modifie.
Sécurité des données : Les données doivent pouvoir être protégées contre les accès non
autorisés. Pour cela, il faut pouvoir associer { chaque utilisateur des droits d’accès aux données.
Résistance aux pannes : Que se passe-t-il si une panne survient au milieu d’une modification, si
certains fichiers contenant les données deviennent illisibles ? Il faut pouvoir récupérer une base
dans un état « sain ». Ainsi, après une panne intervenant au milieu d’une modification deux
solutions sont possibles : soit récupérer les données dans l’état dans lequel elles étaient avant la
modification, soit terminé l’opération interrompue.
Modèle hiérarchique : Une base de données hiérarchique est une forme de système de gestion
de base de données qui lie des enregistrements dans une structure arborescente de façon à ce
que chaque enregistrement n’ait qu’un seul possesseur (par exemple, une paire de chaussures
n’appartient qu’{ une seule personne). Les structures de données hiérarchiques ont été
largement utilisées dans les premiers systèmes de gestion de bases de données. Cependant, à
cause de leurs limitations internes, elles ne peuvent pas souvent être utilisées pour décrire des
structures existantes dans le monde réel. Les liens hiérarchiques entre les différents types de
données peuvent rendre très simple la réponse à certaines questions, mais très difficile la
réponse { d’autres formes de questions. Si le principe de relation « 1 vers N» n’est pas respecté
(par exemple, un malade peut avoir plusieurs médecins et un médecin a, a priori, plusieurs
patients), alors la hiérarchie se transforme en un réseau.
Modèle réseau : Le modèle réseau est en mesure de lever de nombreuses difficultés du modèle
hiérarchique grâce { la possibilité d’établir des liaisons de type n-n, les liens entre objets
pouvant exister sans restriction. Pour retrouver une donnée dans une telle modélisation, il faut
connaître le chemin d’accès (les liens) ce qui rend les programmes dépendants de la structure de
données.
Modèle relationnel : Une base de données relationnelle est une base de données structurée
suivant les principes de l’algèbre relationnelle. Le père des bases de données relationnelles est
Edgar Frank Codd. Chercheur chez IBM à la fin des années 1960, il étudiait alors de nouvelles
méthodes pour gérer de grandes quantités de données car les modèles et les logiciels de
l’époque ne le satisfaisaient pas. Mathématicien de formation, il était persuadé qu’il pourrait
utiliser des branches spécifiques des mathématiques (la théorie des ensembles et la logique des
prédicats du premier ordre) pour résoudre des difficultés telles que la redondance des données,
l’intégrité des données ou l’indépendance de la structure de la base de données avec sa mise en
œuvre physique.
On doutait que les tables puissent être jamais gérées de manière efficace par un ordinateur. Ce
scepticisme n’a cependant pas empêché Codd de poursuivre ses recherches. Un premier
prototype de Système de gestion de bases de données relationnelles (SGBDR) a été construit
dans les laboratoires d’IBM. Depuis les années 80, cette technologie a mûri et a été adoptée par
l’industrie. En 1987, le langage SQL, qui étend l’algèbre relationnelle, a été standardisé.
Modèle objet : La notion de bases de données objet ou relationnel-objet est plus récente et
encore en phase de recherche et de développement. Elle sera très probablement ajoutée au
modèle relationnel.
Pour atteindre certains de ces objectifs, trois niveaux de description des données ont été définis
par la norme ANSI/SPARC.
Le niveau conceptuel : décrit la structure de toutes les données de la base, leurs propriétés (i.e.
les relations qui existent entre elles : leur sémantique inhérente), sans se soucier de
l’implémentation physique ni de la façon dont chaque groupe de travail voudra s’en servir.
Dans le cas des SGBD relationnels, il s’agit d’une vision tabulaire où la sémantique de
l’information est exprimée en utilisant les concepts de relation, attributs et de contraintes
d’intégrité. On appelle cette description le schéma conceptuel.
Le niveau interne ou physique : s’appuie sur un système de gestion de fichiers pour définir la
politique de stockage ainsi que le placement des données. Le niveau physique est donc
responsable du choix de l’organisation physique des fichiers ainsi que de l’utilisation de telle ou
telle méthode d’accès en fonction de la requête. On appelle cette description le schéma interne.
2. Rappel
2.1. Langage SQL
Le langage SQL (Structured Query Language) peut être considéré comme le langage
d’accès normalisé aux bases de données. Il est aujourd’hui supporté par la plupart des produits
commerciaux que ce soit par les systèmes de gestion de bases de données micro tel que “Access“
ou par les produits plus professionnels tels que “Oracle“.
Les instructions du LDD sont : CREATE, ALTER, DROP, AUDIT, NOAUDIT, ANALYZE, RENAME,
TRUNCATE.
Les instructions du LMD sont : INSERT, UPDATE, DELETE, SELECT, EXPLAIN, PLAN, LOCK
TABLE.
Ces éléments doivent être validés par une transaction pour qu’ils soient pris en compte.
Langage de contrôle de données (DCL) : s’occupe de gérer les droits d’accès aux tables.
Langage de contrôle de transaction (TCL) : gère les modifications faites par le LMD, c’est-à-
dire les caractéristiques des transactions et la validation et l’annulation des modifications.
SQL intégré : permet d’utiliser SQL dans un langage de troisième génération (C, Java, PHP, etc.) :
Les instructions du SQL intégré sont : DECLARE, TYPE, DESCRIBE, VAR, CONNECT, PREPARE,
EXECUTE, OPEN, FETCH, CLOSE, WHENEVER.
Identificateurs SQL : utilise des identificateurs pour désigner les objets qu'il manipule :
utilisateurs, tables, colonnes, index, fonctions, etc.
Tables : Les relations d'un schéma relationnel sont stockées sous forme de tables composées de
lignes et de colonnes.
Colonnes : Les données contenues dans une colonne doivent être toutes d'un même type de
données. Ce type est indiqué au moment de la création de la table qui contient la colonne.
Chaque colonne est repérée par un identificateur unique à l'intérieur de chaque table. Deux
colonnes de deux tables différentes peuvent porter le même nom. Il est ainsi fréquent de donner
le même nom à deux colonnes de deux tables différentes lorsqu'elles correspondent à une clé
étrangère à la clé primaire référencée.
Les différents types de données spécifiés par SQL et leur disponibilité sur les différents
SGBD sont :
a. Types alphanumériques
b. Types numériques
c. Types temporels
Longueur maximale prédéterminée, donnée de type binaire, texte long voire formaté,
structure interprétable directement par le SGBDR ou indirectement par add-on externes (image,
son, vidéo...).
Le Langage de Définition des Données est la partie de SQL qui permet de créer une base
de donnée, décrire les tables et autres objets manipulés par les SGBD. Les Commandes sont :
(CREATE) pour créer, (ALTER) pour modifier et (DROP) pour supprimer les éléments du schéma
relationnel tel que la base de données, relations, contraintes, …
ALTER DATABASE
DROP DATABASE
CREATE TABLE
Syntaxe:
• Clé primaire :
CONSTRAINT PK_nomTable PRIMARY KEY (Attribut1, Attribut2,…)
Avec PK_nomTable PRIMARY KEY (Attribut1, Attribut2,…)
• Clé étrangère :
CONSTRAINT FK_nomTable_attributi FOREIGN KEY (Attributi)
REFERENCES nomTablei(Attributi),
• Contrainte de domaine :
CONSTRAINT CK_nomTable_Attributj
CHECK (condition_sur_attributj)
DROP TABLE
ALTER /ADD
ALTER / MODIFY
a. Insertion de ligne
La commande INSERT permet d’insérer une ligne dans une table en spécifiant les valeurs
à insérer. La syntaxe est la suivante :
La liste des noms de colonne est optionnelle. Si elle est omise, la liste des colonnes sera par
défaut la liste de l’ensemble des colonnes de la table dans l’ordre de la création de la table. Si une
liste de colonnes est spécifiée, les colonnes ne figurant pas dans la liste auront la valeur NULL.
b. Modification de ligne
La commande UPDATE permet de modifier les valeurs d’une ou plusieurs colonnes, dans
une ou plusieurs lignes existantes d’une table. La syntaxe est la suivante :
UPDATE nom_table SET attribut= Valeur [WHERE condition];
c. Suppression de ligne
La commande DELETE permet de supprimer des lignes d’une table. La syntaxe est la suivante :
SQL est un langage déclaratif qui permet d’interroger une base de données sans se
soucier de la représentation interne (physique) des données, de leur localisation, des chemins
d’accès ou des algorithmes nécessaires.
La commande SELECT constitue, { elle seule, le langage permettant d’interroger une base
de données. Elle permet de :
Une requête (i.e. une interrogation) est une combinaison d’opérations portant sur des
tables et dont le résultat est lui-même une table dont l’existence est éphémère (le temps de la
requête).
• Comparaison à une valeur (<, <=, =, >=, >, <>). quantifiés (ALL, SOME,
ANY)
• Comparaison à une fourchette ([NOT] BETWEEN), comparaison partielle
([NOT] LIKE)
• Opérateurs logiques: AND, OR, NOT
• Conditions d’existence: nom-col IS [NOT] NULL, [NOT] EXISTS (sous-
requête)
• Conditions d’ensemble: nom-col [NOT] IN (liste-de-valeur ou sous-
requête)
GROUP BY permet de regrouper les données dans la table selon les colonnes
sélectionnées. Peut s’utiliser avec des fonctions d’agrégation: count, sum, avg, max,
min,... dans la clause SELECT
HAVING spécifie les conditions de rétention des regroupements de lignes
ORDER BY permet de trier les données dans la table selon les colonnes sélectionnées en
ordre ascendant (ASC) ou descendant (DESC)
3. Les Vues
3.1. Définition
Une vue est une table contenant des données calculées sur celle d'une autre table, mais
n’occupant pas d’espace disque pour les données. Les données d'une vue sont tout le temps à
jour. Si vous modifiez les données d'une des tables sur lesquelles est calculée la vue, alors les
modifications sont automatiquement répercutées sur la vue.
Une vue peut être considérée comme une requête enregistrée. Ainsi vous pouvez
réutiliser une instruction sans avoir à la redéfinir.
Si certaines colonnes du SELECT sont des expressions, il faut renommer ces colonnes
dans le SELECT, ou spécifier les noms de colonne de la vue.
Une fois créée, une vue s'utilise comme une table. Il n'y a pas de duplication des données.
Le CHECK OPTION permet de vérifier que la mise à jour ou l'insertion faite à travers la
vue ne produisent que des lignes qui font partie de la sélection de la vue.
Intérêt
Langage procédural plus portable.
Permet d’intégrer du code dans des outils classiques (par exemple, un script SQL*Plus, un
programme en C précompilé par Pro*C, peuvent contenir des blocs de sous-programmes
en PL/SQL).
Traitement de transactions.
Construction de procédures ou fonctions stockées qui améliorent le mode client-serveur
par stockage de celles régulièrement utilisées au niveau du serveur.
Construction de triggers qui renforcent la sécurité (intégrité) des données.
Améliore la performance : les procédures et fonctions stockées sont compilées et peuvent
être communes à plusieurs programmes. Il en découle également un moindre trafic
réseau.
La maintenance et le test des programmes est facilitée (intégration complète dans Oracle
Server)
Utilisation
Les morceaux de programme écrits en PL/SQL peuvent être utilisés de deux manières :
Bloc PL/SQL anonyme : ni nommé, ni enregistré dans la base de données, constitué de code
PL/SQL inclus en général l{ où l’on peut mettre des commandes SQL. Un tel bloc est le plus
souvent utilisé de manière interactive (via SQL*Plus, un précompilateur,…) et sert { appeler
des procédures (ou fonctions) stockées ou à ouvrir des curseurs variables.
Procédure (ou fonction ou « package ») : code nommé, enregistré dans le dictionnaire des
données, pouvant être appelé et utilisé par plusieurs applications.
Le moteur PL/SQL qui traite les unités de programme écrites en PL/SQL fait partie de
plusieurs produits d’Oracle, dont Oracle Server, et les outils Oracle Forms, Oracle Reports, Oracle
Graphics de Developper/2000 (famille d’outils pour le développement d’applications clients-
serveur).
La syntaxe est :
14
DECLARE
/* declaration des types, variables et constantes */
/* declaration des procédures et fonctions */
/* declaration des curseurs */
/* declaration des exceptions */
BEGIN
/* instructions a executer */
EXCEPTION
/* section de gestion des erreurs */
END
/
2. Affichage
Pour afficher le contenu d'une variable, les procédures DBMS_OUPUT.PUT() et
DBMS_OUPUT.PUT_LINE() prennent en argument une valeur à afficher ou une variable dont la
valeur est à afficher. Par défaut, les fonctions d'affichage sont désactivées. Il convient, à moins
que vous ne vouliez rien voir s'afficher, de les activer avec la commande SQL+ de oracle par :
SET SERVEROUTPUT ON.
3. Les types
Types classiques
Remarque : une variable non initialisée prend la valeur NULL, ce qui peut conduire à des
erreurs. Il vaut donc mieux initialiser les variables dès leur définition.
Exemple :
Types simples :
BOOLEAN : prend les valeurs TRUE, FALSE, NULL.
BINARY_INTEGER : entier signé de type binaire à utiliser dans le cas de calcul.
NATURAL : sous-type de BINARY_INTEGER (positif ou nul).
POSITIVE : sous-type de BINARY_INTEGER (positif).
nom_variable nom_table.nom_colonne%TYPE
nom_record nom_table%ROWTYPE
Par exemple, on déclare une variable NOM VARCHAR2(20) pour recevoir les valeurs de la
colonne NOM_ETU de type VARCHAR2(20) de la table ETUDIANT :
NOM ETUDIANT.NOM_ETU%TYPE
Et pour une variable var_etu de type RECORD (définit dans la section structures) destinée à
recevoir les n-uplets de la table ETUDIANT :
var_etu ETUDIANT%ROWTYPE
4. Variables
Une variable se déclare de la sorte :
L'initiation est optionnelle. Nous utiliserons les mêmes types primitifs que dans les tables. Par
exemple:
DECLARE
c_var varchar2 (15) := ' Hello World ! ' ;
BEGIN
DBMS_OUTPUT.PUT_LINE( c_var ) ;
END;
/
Les types tableau doivent être définis explicitement par une déclaration de la forme
Par exemple, créons un type tableau de nombres indicé de 1 à 10, que nous appellerons
numberTab
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é tab de type numberTab,
DECLARE
TYPE numberTab IS VARRAY (10) OF NUMBER;
tab numberTab ;
BEGIN
/* instructions */
END;
/
La création d'un type tableau met à disposition un constructeur du même nom que le
type créé. 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;
tab numberTab ;
BEGIN
tab := numberTab ( ) ;
/* utilisation du tableau */
END;
/
Une fois cette allocation faite, il devient presque possible d'utiliser le tableau...
Dimensionnement d'un tableau
DECLARE
TYPE numberTab IS VARRAY (10) OF NUMBER;
tab numberTab ;
BEGIN
tab := numberTab ( ) ;
tab.EXTEND( 4 ) ;
/* utilisation du tableau */
END;
/
Dans cet exemple, tab.EXTEND(4) permet par la suite d'utiliser les éléments du tableau t(1),
t(2), t(3) et t(4). Il n'est pas possible "d'étendre" un tableau à une taille supérieure à celle
spécifie lors de la création du type tableau associé.
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.
Effectuons, par exemple, une permutation circulaire vers la droite des éléments du tableau t.
SET SERVEROUTPUT ON
DECLARE
TYPE numberTab IS VARRAY (10) OF NUMBER;
tab numberTab ;
i number ;
k number ;
BEGIN
tab := numberTab ( ) ;
tab .EXTEND( 1 0 ) ;
FOR i IN 1 . . 1 0 LOOP
tab ( i ) := i ;
END LOOP;
k := tab ( 1 0 ) ;
tab ( 1 ) := k ;
FOR i IN 1 . . 1 0 LOOP
DBMSOUTPUT.PUT_LINE( tab ( i ) ) ;
END LOOP;
END;
/
5.2. Tableau dynamique :
Exemple : ...............................................................................................
TYPE tab IS TABLE OF INTEGER ;
var_tab tab ;
var_tab(1) := 20 ;
Une structure est un type regroupant plusieurs types. Une variable de type structuré
contient plusieurs variables, ces variables s'appellent aussi 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 structure 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.
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,
SET SERVEROUTPUT ON
DECLARE
TYPE point IS RECORD
(
abscisse NUMBER,
ordonnee NUMBER
);
p point ;
BEGIN
p . abscisse := 1 ;
p . ordonnee := 3 ;
Le script ci-dessus crée le type point, puis crée une variable P de type point, et enfin affecte aux
champs abscisse et ordonnée du point p les valeurs 1 et 3.
6. Structures de contrôle
6.1. Traitements conditionnels
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
Voire:
IF /* condition 1 */ THEN
/* instructions 1 */
ELSIF /* condition 2 */ THEN
/* instructions 2 */
ELSE
/* instructions 3 */
END IF
Les conditions sont les mêmes qu'en SQL. Le switch du langage C s'implémente en PL/SQL de la
façon suivante :
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
L'utilisation de la commande LOOP fournit un traitement itératif basé sur des choix
logiques. La construction de base des boucles « LOOP » est montrée dans l'exemple suivant :
LOOP
/* instructions */
END LOOP
Voire
<<nom>>
LOOP
/* instructions */
END LOOP nom;
Pour sortir d'une boucle de ce genre, il faut une commande EXIT ou GOTO basée sur une
condition du traitement. En cas de levée d'exception définie par l'utilisateur, la boucle LOOP
s'achève aussi.
LOOP
/* instructions */
EXIT WHEN /* condition */
END LOOP
Une boucle peut être nommée comme cela a été montré dans l'exemple en utilisant une
étiquette telle que <<nom>> juste avant l'instruction LOOP. Bien que ce ne soit pas obligatoire,
l'étiquetage permet de garder une meilleure trace de l'imbrication des boucles.
b. Boucles WHILE
La boucle WHILE vérifie l'état d'une expression PL/SQL qui doit s'évaluer à TRUE, FALSE
ou NULL au début de chaque cycle de traitement.
WHILE (condition) LOOP
/* instructions */
END LOOP;
Les itérations de boucles peuvent être contrôlées avec des boucles FOR numériques. Ce
mécanisme permet au développeur d'établir un intervalle d'entiers pour lesquels la boucle va
être itérée.
Le variable indice varie de min à max avec un pas de 1. Si REVERSE est précisé, indice
varie de max à min avec un pas de -1.
7. Procédures et fonctions
Une procédure (non stockée) ne peut s’utiliser dans un bloc anonyme que si elle a été
déclarée dans la partie déclaration de ce bloc (ou d’un bloc PL/SQL l’englobant). Sa déclaration
peut comporter des arguments dont on déclare le nom, le mode et le type.
Les curseurs sont définis dans la zone des variables de sous-programmes PL/SQL en
utilisant l'instruction CURSOR nome IS, comme montré dans l'exemple suivant :
L'instruction SQL peut être n'importe quelle requête valide. Après l'initialisation d'un
curseur, les actions d'un curseur peuvent être contrôlées avec les instructions OPEN, FETCH et
CLOSE.
Pour utiliser un curseur afin de manipuler des données, il faut utiliser l'instruction OPEN
nom_curseur pour exécuter la requête et identifier toutes les lignes qui satisfont le critère de
sélection. Les extractions ultérieures de lignes sont réalisées avec l'instruction FETCH. Lorsque
toutes les données sont traitées, l'instruction CLOSE clôt toute activité associée avec le curseur
ouvert. Ce qui suit est un exemple de contrôle de curseur :
OPEN nom_curseur;
...
FETCH nom_curseur INTO ligne_info;
...
/* traitement de la ligne extraite */
...
CLOSE nom_curseur;
Ce code ouvre le curseur nom_curseur et traite les lignes extraites. Après l'extraction et
le traitement de toute l'information, le curseur est fermé. Le traitement des lignes extraites est
typiquement contrôlé par des itérations de boucles comme discuté plus loin.
%NOTFOUND
%FOUND
%ROWCOUNT
%ISOPEN
Tous les attributs de curseur s'évaluent à TRUE, FALSE ou NULL, en fonction de la
situation.
L'attribut %NOTFOUND s'évalue à FALSE quand une ligne est extraite, TRUE si le dernier
FETCH n'a pas renvoyé une valeur et NULL si le curseur SELECT n'a pas renvoyé de données.
L'attribut %FOUND est l'opposé logique de %NOTFOUND par rapport à TRUE et FALSE,
mais s'évalue néanmoins à NULL si le curseur ne renvoie pas de données.
%ROWCOUNT peut être utilisé pour déterminer combien de rangées ont été sélectionnées
à un moment donné dans le FETCH. Cet attribut est incrémenté après la sélection réussie d'une
ligne. De plus, %ROWCOUNT est à zéro quand le curseur est ouvert pour la première fois.
Le dernier attribut, %ISOPEN, est ou bien TRUE ou bien FALSE, suivant que le curseur
associé est ouvert ou non. Avant que le curseur ne soit ouvert et après qu'il soit fermé,
%ISOPEN vaut FALSE. Dans les autres cas, cet attribut s'évalue à TRUE.
On peut spécifier des paramètres pour les curseurs de la même manière que pour des
sous-programmes.
L'exemple suivant illustre la syntaxe de déclaration de curseurs avec des paramètres :
Le mode des paramètres est toujours IN, mais les types de données peuvent être n'importe
quels types de données valides. Un paramètre de curseur ne peut être référencé que pendant la
requête déclarée. La flexibilité au sein des paramètres de curseurs permet au développeur de
passer différents nombres de paramètres à un curseur en utilisant le mécanisme des paramètres
par défaut. Ceci est illustré dans l'exemple ci-dessous :
CURSOR c_line_item
(order_num INTEGER DEFAULT 100,
line_num INTEGER DEFAULT 1) IS ...
En utilisant la déclaration INTEGER DEFAULT, on peut passer tous, un, ou aucun des
paramètres de ce curseur en fonction du code appelant.
Quand une erreur se produit, une exception est levée : l’exécution normale du programme
est arrêtée et le contrôle est transféré au gestionnaire d’exception (partie spécifique du bloc
PL/SQL ou du sous-programme concerné). Les exceptions prédéfinies sont levées
automatiquement. Les exceptions définies par l’utilisateur doivent être levées explicitement par
un ordre RAISE.
Après exécution des ordres du gestionnaire d’exception, le contrôle est redonné au bloc
qui englobait le sous-programme arrêté lors de la levée de l’exception ou, { défaut, {
l’environnement du programme.
Cela évite de répéter plusieurs fois le même test d’erreur au cours d’un programme.
Cela augmente la fiabilité en évitant les oublis de tests d’erreur.
Cela améliore la lisibilité du programme.
Pour traiter les erreurs nom nommées, on peut utiliser la clause WHEN OTHERS THEN…
dans le gestionnaire d’exception avec les fonctions SQLCODE et SQLERRM. On peut aussi
associer une erreur Oracle { un nom d’exception donné par l’utilisateur.
nom_exception EXCEPTION ;
RAISE nom_exception ;
EXCEPTION
WHEN nom_exception1 THEN code_exception1 ;
WHEN nom_exception2 THEN code_exception2 ;
………
WHEN OTHERS THEN code_dernière_exception ;
END ;
Remarque : WHEN OTHERS (toujours placé { la fin) dans le gestionnaire d’exception permet
d’intercepter toute exception. Ici, il permet d’afficher le code et le message d’erreur ORACLE.
Oracle permet de traiter des erreurs définies en code PL/SQL par l’utilisateur : un numéro
d’erreur précisé par l’utilisateur et un message sont retournés { l’application. Celle-ci peut
traiter l’erreur en fonction de son numéro et du message. C’est la procédure
RAISE_APPLICATION_ERROR (du package DBMS_STANDARD) qui délivre le message.
La procédure RAISE_APPLICATION_ERROR est souvent utilisée par les gestionnaires
d’exceptions ou dans la logique du programme. Un programme ne peut appeler cette procédure
qu’{ l’exécution d’un sous-programme stocké. Cette procédure termine l’exécution de l’action en
cours, annule les effets de cette action et retourne un code d’erreur et un message d’erreur.
RAISE_APPLICATION_ERROR(numéro_erreur,’texte’[,{TRUE|FALSE}])
numéro d’erreur est un nombre entre –20000 et –20999 (valeurs de codes d’erreur
Oracle réservées pour l’utilisateur)
texte est un message d’au plus 2 Koctets
optionnel, TRUE indique que l’erreur est placée sur la pile des erreurs précédentes,
sinon l’erreur remplace les précédentes (FALSE est l’option par défaut).
10.1. Procédures.
Syntaxe de liste_argument :
IN : Paramètre d'entrée
OUT : Paramètre de sortie
IN OUT : Paramètre d'entrée/Sortie
10.2. Fonctions
Pour supprimer :
Invocation
En PL/SQL, une procédure stockée (procédure ou fonction) s'invoque tout simplement avec son
nom. Mais on doit utiliser le mot-clé CALL ou EXECUTE.
EXECUTE nom_proc
11. Package
Un package (paquetage) est l’encapsulation d’objets de programmation PL/SQL dans une
même unité logique de traitement tels : types, constantes, variables, procédures et fonctions,
curseurs, exceptions.
Il comporte:
Modifier le corps sans recompiler la spécification, ni changer les programmes qui font
appel aux objets du package.
Définir des variables globales et des curseurs communs à toutes les
procédures/fonctions du package.
Gérer plus efficacement les privilèges à accorder.
De meilleures performances ; tout le package est chargé en mémoire lors de sa première
utilisation.
Syntaxe de création :
12. Triggers
Un déclencheur (trigger) est un ensemble d’actions déclenchées automatiquement par le
SGBD chaque fois qu’un événement défini se produit. Cet ensemble est enregistré dans la base et
non dans des programmes d’application.
Un trigger Oracle est une procédure stockée associée à une table et qui est exécutée
chaque fois qu’une modification précisée dans le trigger affecte la table.
Type d'actions :
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.
Lors que 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é à chaque fois qu'une instruction est lancée.
Création
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 :
Si nous ajoutons un client dont le nom est toto alors nous récupérons ce nom grâce à
la variable :new.nom
Dans le cas de suppression ou modification, les anciennes valeurs sont dans la
variable :old.nom
Modification
Tableau 1 : Client
NumCli Nom Prénom DateNaiss Rue CP Ville
1 Hilmi Samir 1984- 02-12 Massira 100023 Rabat
2 Alami Kamel 1988-12-14 100024 Rabat
3 Saidi Ali Nasser 100025 Kenitra
Tableau 2 : Produit
NumProd Design PU NumFour
10 Ordinateur 1100 1
20 Imprimante 2045,25 3
1. Créez la vue CLIENT_RABAT à partir de la table CLIENT ne contenant que les clients
habitant à la ville de Rabat Toutes les colonnes sont conservée et portent le même nom que les
colonnes de la table. Interroger la vue (DESC et SELECT).
2. Créer la vue PRODUIT_1 (NP_1, NumFour_1, PrixUnit_1, Desig_1) à partir de la table
PRODUIT ne contenant que les produits du fournisseur dont la raison sociale est « SOS
Computer »
3. Insérer avec INSERT trois nouveaux produits dans la vue PRODUIT_1 (exemple Caméra,
Scanner et papier). Tels que caméra et scanner appartiens au fournisseur dont la raison sociale
est « SOS Computer » et papier à un autre fournisseur.
a. Vérifier le contenu de la vue et celui la table PRODUIT. Conclure ?
b. Supprimer ensuite les enregistrements ajoutés dans la table PRODUIT (par
l’intermédiaire de la vue PRODUIT_1). Conclure ?
Exercice 1 :
Ecrivez un programme affectant les valeurs 1 et 2 à deux variables a et b, puis permutant les valeurs de
ces deux variables.
Exercice 2 :
Ecrivez un programme plaçant la valeur 10 dans une variable a, puis affichant la factorielle de a.
Exercice 3 :
Ecrivez un programme plaçant les valeurs 48 et 84 dans deux variables a et b puis affichant le pgcd de
a et b.
Exercice 4 :
Exercice 5 :
1. Créez une structure « RECORD » client reprenant les informations relatives à un client
2. Placez dans ce RECORD les informations liées au client né le « 1988-12-14 »
Exercice 6 :
1. Créez une Fonction PRIX_TTC qui calcule le prix TTC des ordinateurs commandé par
chaque client.
2. Créez une Procédure Cli_prod qui affiche le nom de client suivi de la désignation de produit
qu’il a commandé.
UNIVERSITE IBN TOFAIL Année universitaire : 2014/2015
Faculté des sciences Filière : SMI
Département d’informatique Semestre : 6
Kenitra
Exercice 1 :
Ecrire une fonction récursive retournant bn, avec n entier positif ou nul.
Exercice 2 :
Ecrire une fonction demi-frères prenant deux numéros de personnes en paramètre et retournant
vrai si et seulement si ces deux personnes ont un parent en commun.
Exercice 3 :
Ecrire une fonction cousins prenant deux numéros de personnes en paramètre et retournant vrai si
et seulement si ces deux individus sont cousins.
Exercice 4 :
Ecrire une procédure récursive affichant le nom de la personne dont le numéro est passe en
paramètre et se rappelant récursivement sur le père de cette personne.
Exercice 5 :
En utilisant la table PERSONNE, écrivez une fonction affichant toute la descendance d'une personne.
Vous devez utilisez un curseur.
Exercice 6 :
1. Le Code Postale dans lequel habite le personne doit être 01, 07, 26, 38, 42, 69, 73, ou 74 ;
2. Le nom du Père doit être le même que celui du personne.