
La notion de package permet d'encapsuler des procédures, des fonctions, des curseurs et des
variables comme une unité dans la base de données. Elle apporte un certain nombre
d'avantages par rapport aux procédures et aux fonctions cataloguées. En effet, les packages
offrent un meilleur moyen de structuration et d'organisation du processus de développement.
Le mécanisme de gestion de privilèges devient plus facile par rapport aux procédures
(fonctions) cataloguées. En effet, l'attribution de privilèges d'utilisation des composantes d'un
package se fait par une seule commande.
Les packages offrent un meilleur mécanisme de gestion de la sécurité. L'utilisateur peut
spécifier au cours de la création d'un package des composantes publiques et des composantes
privées. La séparation des déclarations des composantes d'un package de leur corps permet
une meilleure flexibilité au développeur pour établir rapidement une maquette.
Enfin les performances peuvent être améliorées en utilisant les packages plutôt que les
procédures cataloguées. Le moteur charge en mémoire le package entier quand une de ses
procédures est appelée. Une fois le package en mémoire, le moteur n'a plus besoin d'effectuer
des lectures (I/O disque) pour exécuter les procédures de ce même package.
Création d’un package
La création d'un package se fait en deux étapes :
- Création des spécifications du package
- Création du corps du package
135
Les spécifications d'un package consistent à déclarer les procédures, les fonctions, les
constantes, les variables et les exceptions qui peuvent être accessibles par le public. En
d'autres termes, il s'agit de la déclaration des objets de type PUBLIC du package.
CREATE [OR REPLACE] PACKAGE [schéma.]nom_package
{IS | AS} spécification PL/SQL
spécification PL/SQL ::=
déclaration de variable |
déclaration d'enregistrement |
déclaration de curseur |
déclaration d'exception |
déclaration de table PL/SQL |
déclaration de fonction |
déclaration de procédure.|
Le corps d'un package définit les procédures (fonctions), les curseurs et les exceptions qui
sont déclarés dans les spécifications de la procédure. Il peut également définir d'autres objets
de même type non déclarés dans les spécifications. Ces objets sont alors privés et ne peuvent
en aucun cas être accédés en dehors du corps du package. La commande qui permet de créer
le corps d'une procédure est la suivante :
CREATE [OR REPLACE] PACKAGE BODY [schéma.]nom_package
{IS | AS} corps PL/SQL
Où corps PL/SQL : :=
déclaration de variable |
déclaration d'enregistrement |
corps de curseur |
déclaration d'exception |
déclaration de table PL/SQL |
corps de fonction |
corps de procédure...
Les noms de la spécification et du corps du package doivent être les mêmes. Les objets
déclarés dans les spécifications du package sont rendus publics et peuvent être accédés à
l'intérieur et à l'extérieur du package. Ainsi, les variables, les curseurs et les exceptions
publics peuvent être utilisés par des procédures et des commandes qui n’appartiennent pas
au package, à condition d'avoir le privilège EXECUTE sur ce package. Les objets privés sont
déclarés dans le corps du package et n'auront comme étendue que le corps package. Les
variables d'une procédure ne sont accessibles que par la procédure elle-même. Il est
important de signaler l'étendue (durée de vie) des variables, constantes et curseurs entre les
procédures cataloguées et les packages. Les variables appartenant à une procédure standard
ou du package ont une durée de vie limitée à l'exécution de la procédure. Une fois la
procédure terminée, les variables et les constantes sont perdues.
Par contre, les mêmes objets déclarés au niveau des spécifications d'un package ou de son
corps persistent le long de la session et après le premier appel à ce package. Quand une
session commence, les variables et les curseurs sont initialisés à la valeur nulle, à moins
qu'une initialisation ait été explicitement effectuée sur ces objets. Pour réaliser cette
initialisation explicite, un package peut contenir dans son corps du code exécuté seulement
136
lors du premier appel à ce package. Ce code constitue un bloc séparé par les mots clés
BEGIN et END.
Il est possible de nommer plusieurs procédures de la même façon. Cette possibilité permet de
définir une procédure à plusieurs points d'entrée (nombre d'arguments et type de données
différents).
Modification d’un package
La modification d'un package concerne sa version compilée. En d'autres termes, il est
important de recompiler le package afin que le noyau tienne compte de l'évolution de la base
et que l'on puisse modifier ainsi sa méthode d'accès et son plan d'exécution.
Cette recompilation se fait par la commande suivante :
ALTER PACKAGE [schéma.]package
COMPILE [PACKAGE | BODY];
En pratique, il est recommandé de sauvegarder les sources des packages dans des fichiers
pour les reprendre en vue d'une modification de leur contenu. En cas de modification des
sources l'utilisateur doit recréer le package avec l'option REPLACE pour remplacer l'existant.
Exemple : Recompiler le package ges_vendeur.
ALTER PACKAGE ges_vendeur COMPILE PACKAGE;
Suppression d’un package
La suppression d'un package se fait par la commande DROP comme suit :
DROP PACKAGE [schéma.]package;
Les transactions et verrous dans Oracle 11g
L’un des objectifs d’un SGBD est de mettre à la disposition d'un grand nombre d'utilisateurs
un ensemble cohérent de données. En présence de ce grand nombre d'utilisateurs, une
attention particulière doit être apportée pour garantir la cohérence des données lors de leur
manipulation simultanée par différents utilisateurs. Cette cohérence est assurée à l'aide des
concepts de transaction et d’accès concurrents. Toutes les modifications de données dans
Oracle sont effectuées dans le cadre de transactions. Par défaut, Oracle démarre une
transaction pour chaque instruction individuelle et la valide automatiquement si l’exécution de
l’instruction se termine normalement. Une transaction est caractérisée les critères ACID :
– Atomique : Si une des instructions échoue, toute la transaction échoue.
– Cohérente, car la base de données est dans un état cohérent avant et après la transaction,
c'est-à-dire respectant les règles de structuration énoncées.
– Isolée : Les données sont verrouillées : il n’est pas possible depuis une autre transaction
de visualiser les données en cours de modification dans une transaction.
137
– Durable : Les modifications apportées à la base de données par une transaction sont
validées. Par exemple, une transaction bancaire peut créditer un compte et en débiter un
autre, ces actions devant être validées ensemble.
Une transaction est une unité logique de traitements regroupant un ensemble i élémentaire
(commandes SQL). Ces opérations doivent être soit exécutées entièrement, soit pas du tout,
permettant ainsi à la base de données de passer d'un état cohérent à un nouvel état
cohérent.
Soit les deux commandes suivantes :
INSERT INTO ligne_com
VALUES (100, l, 1001, 10);
et
UPDATE article
SET qtestock = qtestock – 10
WHERE idarticle = 1001;
La première commande enregistre une nouvelle ligne de commande et la seconde met à jour
l'état du stock pour l'article commandé. Pour que la base de données reste dans un état
cohérent, ces deux commandes doivent être exécutées et validées. Si, pour une raison
quelconque, la seconde commande n'a pas pu être traitée, le système doit annuler la
première Lorsque toutes les opérations constituant la transaction sont exécutées et
deviennent effectives, nous disons que la transaction est validée. Les modifications apportées
par les opérations élémentaires deviennent alors définitives. Dans le cas contraire où au
moins une opération n’a pas pu être exécutée pour une raison quelconque (condition non
vérifiée, accès impossible aux données, panne), nous disons que la transaction est annulée.
Les modifications apportées par toutes les opérations élémentaires sont alors annulées et on
revient à l'état qu'avait la base avant la transaction.
Dans le but d'assurer une souplesse dans la gestion des transactions, il est possible de
découper une longue transaction en sous-transactions à l'aide de repères permettant
d'effectuer, en cas de besoin, des annulations partielles de la transaction. Cette notion de
sous-transaction permet d'effectuer un découpage plus fin des unités de traitement.
Contrôle des transactions
Le contrôle des transactions consiste à définir le début et la fin d'une transaction (validation
ou annulation) ainsi que son découpage éventuel en sous-transactions.
Début de transaction : Il n’existe pas de commande permettant de marquer explicitement
le début d'une transaction. Ce début est implicitement défini par la première commande SQL
exécutée ou par la fin d'une transaction précédente. Le début d'une application ou d'une
session SQL constitue automatiquement le début d'une transaction. De même, la fin d'une
transaction (par validation ou par annulation) marque le début d'une nouvelle transaction.
Fin d’une transaction : La fin d’une transaction peut être définie explicitement ou
implicitement. La fin explicite d'une transaction est réalisée à l'aide des deux commandes
138
COMMIT ou ROLLBACK. La première valide les opérations élémentaires de la transaction et
la seconde les annule.
Les événements suivants constituent une fin implicite d'une transaction :
· Exécution d'une commande de définition de données (CREATE, ALTER, RENAME et DROP)
: Routes les opérations exécutées depuis le début de la transaction sont validées.
· Fin normale d'un programme ou d'une session avec déconnexion d'Oracle : La transaction
est validée.
· Fin anormale d’un programme ou d’une session (sortie sans déconnexion d'Oracle) : la
transaction est annulée.
Découpage d’une transaction
Il est possible dans Oracle, d'effectuer un découpage d'une transaction en insérant des points
de repère (en anglais savepoints). À l'aide de ces points de repère, il est possible d'annuler un
sous-ensemble d'opérations d'une transaction à partir d'un point de repère. La création d'un
point de repère se fait à l'aide de la commande suivante :
SAVEPOINT point_repère;
Pour annuler les opérations à partir d'un point de repère, on utilise la ROLLBACK en précisant
le point de repère :
ROLLBACK TO [SAVEPOINT] point_repère;
Verrouillage des données