299

Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Embed Size (px)

Citation preview

Page 1: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées
Page 2: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Ce livre s’adresse à tout informaticien désireux de maîtriser la gestion d’une base de données Oracle. Il reprend les concepts, définitions et règles du modèle relationnel et détaille son utilisation dans le cadre des outils proposés en standard avec Oracle Server 10g, c’est-à-dire SQL, SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées afin de pouvoir utiliser toute la puissance du serveur de bases de données Oracle 10g ainsi que les nouveautés apportées par cette version : l’interface iSQLPlus, l’outil de conception d’applications Web HTMLDB, la notion de flashback table et les expressions régulières. Des exemples nombreux et précis aident le lecteur à maîtriser ces langages de référence dans le monde des bases de données relationnelles. Retrouvez le site de l´auteur Jérôme GABILLAUD : www.apsql.com. "

Ce livre numérique a été conçu et est diffusé dans le respect des droits d’auteur. Toutes les marques citées ont été déposées par leur éditeur respectif. La loi du 11 Mars 1957 n’autorisant aux termes des alinéas 2 et 3 de l’article 41, d’une part, que les “copies ou reproductions strictement réservées à l’usage privé du copiste et non destinées à une utilisation collective”, et, d’autre part, que les analyses et les courtes citations dans un but d’exemple et d’illustration, “toute représentation ou reproduction intégrale, ou partielle, faite sans le consentement de l’auteur ou de ses ayants droit ou ayant cause, est illicite” (alinéa 1er de l’article 40). Cette représentation ou reproduction, par quelque procédé que ce soit, constituerait donc une contrefaçon sanctionnée par les articles 425 et suivants du Code Pénal. Copyright Editions ENI

Oracle 10g SQL, PL/SQL, SQL*Plus

Jérôme GABILLAUD

Résumé

L'auteur

Ingénieur en Informatique pour l'Industrie, consultant, Jérôme Gabillaud est également responsable pédagogique dans un grand centre de formation informatique. Spécialiste des systèmes d'accès aux données Microsoft ou Oracle, il est déjà auteur de nombreux ouvrages sur ce sujet, reconnus pour leurs qualités techniques et pédagogiques.

- 1 -© ENI Editions - All rigths reserved

Page 3: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Introduction

Oracle 10g est un puissant Système de Gestion de Bases de Données Relationnelles proposant, en plus du moteur de la base, de nombreux outils à l’utilisateur, au développeur et à l’administrateur.

Ces outils ont un langage commun : le SQL.

Oracle permet de gérer les données d’une application en respectant une logique, devenue standard, le modèle relationnel. Les fondements de ce modèle ont été établis au début des années 70, par E.F. CODD et restent une référence pour la gestion des données.

La logique d’extraction des données d’une base conforme au modèle relationnel, constitue l’algèbre relationnelle. Elle permet aux utilisateurs une approche indépendante du système physique pour arriver à un résultat.

Le SQL est un langage de requêtes descriptif, standard pour toutes les bases de données qui suivent le modèle relationnel. Ce langage permet toutes les opérations sur les données dans tous les cas d’utilisation de la base.

Avec Oracle, on peut enfin associer au SQL un langage procédural, le PL/SQL, qui ajoute de nombreuses possibilités dans la manipulation des données.

Depuis la version 8i, le SGBD Oracle propose, en option, une nouvelle méthode de gestion des informations dans l’entreprise à travers l’implémentation du modèle objet ­ relationnel. L’objectif de cette approche est de simplifier la modélisation des données en permettant le stockage et la manipulation de nouveaux types d’informations. Ces objets métiers, propres à chaque secteur d’activité ou à chaque entreprise doivent permettre une modélisation plus efficace.

La mise en œuvre de ce modèle à travers les extensions du langage SQL autorise une migration souple entre le modèle relationnel pur des versions précédentes et ce nouveau modèle objet ­ relationnel. Le présent ouvrage s’intéresse à l’approche relationnelle classique.

- 1 -© ENI Editions - All rigths reserved

Page 4: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

La gestion des données

Dans toutes les applications de gestion, il faut stocker des données afin de les réutiliser à volonté sous différentes formes. La plupart des systèmes d’exploitation (MS/DOS, UNIX, VMS, GCOS...) fournissent des outils permettant ce stockage. Ces logiciels gèrent des fichiers selon des principes différents.

1. Généralités sur les fichiers

Un fichier informatique est un ensemble d’informations de même nature (texte, code exécutable, données...), portant un nom et situé sur un support physique (disque dur, disquette, bande, CD­Rom...).

Un fichier peut avoir différentes fonctions :

fichier programme : contient du code exécutable par le système d’exploitation.

fichier texte : contient des caractères ASCII.

bibliothèque de fonctions : contient du code exécutable pouvant être utilisé par un programme.

fichier périphérique : permet l’adressage des périphériques (UNIX).

fichier de données : permet le stockage d’informations d’une application. etc.

Les fichiers de données se distinguent par leur utilité au sein de l’application : le type de fichier. Ce type permettra de choisir à la fois le support physique du fichier et son organisation.

Les fichiers permanents contiennent les données de base de l’application. Leurs enregistrements sont, généralement, composés de nombreuses rubriques et sont de taille importante. La durée de vie de ces enregistrements est longue. Quelques exemples de fichiers permanents : les fichiers de clients, les catalogues d’articles, les fiches salariés.

Les fichiers de mouvement contiennent des données se référant aux fichiers permanents, en apportant des informations supplémentaires, en général ponctuelles. Les enregistrements sont composés principalement des codes identifiant les enregistrements des fichiers de base. Le nombre d’enregistrements de ces fichiers peut être important mais leur durée de vie est courte. On peut citer dans ce type, le fichier commandes d’une gestion commerciale qui stocke la quantité d’articles commandés par un client, ou les fiches de temps d’une gestion de salariés qui stockent le nombre d’heures travaillées par un salarié sur un poste.

Les fichiers de travail sont créés en général par des applications. Ils contiennent toutes les informations des fichiers permanents et de mouvement regroupées dans des enregistrements composés. Leur durée de vie est la même que celle du traitement. Ces fichiers occupent, en général, beaucoup de place. Ce type de fichier comporte, par exemple, les fichiers d’édition, les résultats de requêtes.

Les fichiers historiques contiennent des données archivées. Elles proviennent, après calcul ou épuration, des fichiers permanents et des fichiers de mouvement, pour des enregistrements inactifs, ou à mettre en statistique.

2. Organisations classiques de fichiers

L’analyste pourra choisir l’organisation de fichiers à adopter en fonction du type de fichier, du support, de l’application et, bien sûr, des contraintes du cahier des charges !

Les principaux choix d’organisation de fichiers sont l’organisation séquentielle, le séquentiel indexé, les bases de données navigationnelles et évidemment les bases de données relationnelles.

Le principe de cette organisation est de gérer les enregistrements comme des suites d’octets structurées (par des caractères délimiteurs ou des tailles fixes).

L’avantage réside dans la simplicité d’utilisation, la standardisation des structures et dans l’optimisation de l’espace de stockage.

Par contre, les fichiers sont indépendants les uns des autres dans l’application et les lectures ne peuvent se faire que séquentiellement (octet après octet).

Types de fichiers de données

Séquentiel

- 1 -© ENI Editions - All rigths reserved

Page 5: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

C’est une amélioration de l’organisation séquentielle, par l’ajout d’un fichier de clés (ou d’index), lié au fichier séquentiel.

Ce fichier d’index contient des critères de recherche triés (index) et l’adresse de la donnée correspondante dans le fichier séquentiel.

En plus des avantages du système séquentiel (simplicité, standardisation), on peut donc retrouver rapidement un enregistrement en fonction de la clé.

Le principal inconvénient reste l’indépendance des fichiers dans l’application, d’où la nécessité de beaucoup de programmation pour gérer l’intégrité des données. On peut également noter un gaspillage de place dû à la redondance des données (notamment les clés).

Ce sont des collections de fichiers, logiquement appareillés entre eux. Ces bases ont été créées sur des systèmes propriétaires afin de compenser la faiblesse des organisations précédentes, en ce qui concerne la traduction du dictionnaire des données de l’analyse.

Les avantages de ces bases sont nombreux, notamment la sécurité d’accès avec connexion d’utilisateurs à la base protégée par mot de passe ; le respect, au niveau des structures même, de l’intégrité de données ; de nouvelles possibilités de lecture de données grâce à des liens directs entre enregistrements de fichiers différents (lectures chaînées).

De gros inconvénients découlent de ces systèmes. Parmi ceux­ci on peut citer la complexité de maintenance et d’utilisation, la "gourmandise" en espace disque, mémoire et CPU, et enfin la spécificité de ces bases par rapport au système d’exploitation.

Séquentiel indexé

Bases navigationnelles

- 2 - © ENI Editions - All rigths reserved

Page 6: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Le modèle relationnel

Une base de données relationnelle est une collection de données mises en relation dans des tables logiques ; une table étant un ensemble de lignes et de colonnes.

Les Systèmes de Gestion de Bases de Données Relationnelles (SGBDR ou RDBMS en anglais) gèrent indépendamment le niveau logique (objets ou entités) et le niveau physique (fichiers).

Le succès des SGBDR provient notamment de cette caractéristique. En effet, la gestion par l’utilisateur du niveau logique uniquement, donne une grande simplicité dans la gestion des données, même pour des utilisateurs non informaticiens.

1. Concepts et définitions

Le modèle relationnel repose sur des concepts de base simples (domaine, relation, attribut), auxquels s’appliquent des règles précises.

La mise en œuvre de la base est facilitée par un langage assertionnel (non procédural) simple, basé sur une logique ensembliste.

a. Domaine

C’est un ensemble de valeurs caractérisées par un nom.

C’est le nombre d’éléments d’un domaine.

Exemple

Le dictionnaire des données de l’analyse d’une gestion commerciale peut comporter, entre autres, des spécifications sur la gestion des états de commande ou des numéros d’ordre à afficher. Le modèle relationnel les traduira de la manière suivante :

États des commandes = "EC","LI", "FA", "SO";cardinal 4 Numéros d’ordre = n | 1<=n<=9999;cardinal 9999

b. Produit cartésien

Le produit cartésien P entre plusieurs domaines D1, D2,..., Dn noté P = D1 X D2 X ... X Dn est l’ensemble des n­uplets (tuples) (d1, d2, ..., dn) où chaque di est un élément du domaine Di.

Exemple

Si on veut gérer deux domaines (codes et taux), on pourra obtenir des doublets composés d’un code et d’un taux.

Codes = 1,2,3,4 Taux de TVA = 0,5.5,19.6 Codes X Taux de TVA =(1,0),(1,5.5),(1,19.6), (2,0),(2,5.5),(2,19.6),(3,0),(3,5.5),(3,19.6), (4,0),(4,5.5),(4,19.6)

c. Relation

Une relation définie sur les domaines D1, D2,... , Dn est un sous­ensemble du produit cartésien de ces domaines caractérisé par un nom.

C’est une colonne d’une relation caractérisée par un nom.

C’est le nombre d’attributs d’une relation.

Cardinal

Attribut

Degré

- 1 -© ENI Editions - All rigths reserved

Page 7: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Exemple

Pour associer un seul taux par code, seuls trois doublets doivent être concernés.

Relation TVA = (1,0),(2,5.5),(3,19.6)

Elle se fait sous forme de tableau (table), en extension :

ou en compréhension :

TVA (CODE:codes, VALEUR:Taux de TVA) ou TVA (CODE, VALEUR)

2. Principales règles

Le modèle relationnel gère donc un objet principal, la relation, associée aux concepts de domaine et d’attribut.

Des règles s’appliquent à cette relation afin de respecter les contraintes liées à l’analyse.

Quelques­unes de ces règles sont :

Toute valeur prise par un attribut doit appartenir au domaine sur lequel il est défini.

Tous les éléments d’une relation doivent être distincts.

Attribut ou ensemble d’attributs permettant de caractériser de manière unique chaque élément de la relation.

Identifiant minimum d’une relation.

Autres identifiants de la relation.

Cette règle impose qu’un attribut ou ensemble d’attributs d’une relation apparaisse comme clé primaire dans une autre relation.

Attribut ou ensemble d’attributs vérifiant la règle d’intégrité référentielle.

Exemple

L’analyse d’une gestion commerciale nous impose de gérer des clients ayant des caractéristiques (Nom, adresse) et des commandes que passent ces clients.

On pourra proposer le modèle suivant :

Représentation

Cohérence

Unicité

Identifiant

Clé primaire

Clés secondaires

Intégrité référentielle

Clé étrangère

- 2 - © ENI Editions - All rigths reserved

Page 8: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

CLIENTS (NUMEROCLI,NOMCLI,ADRESSECLI) NUMEROCLI identifiant clé primaire de CLIENTS (NOMCLI,ADRESSECLI) identifiant clé secondaire de CLIENTS COMMANDES (NUMEROCDE,DATECDE,NUMEROCLI,ETATCDE) NUMEROCDE identifiant clé primaire de COMMANDES NUMEROCLI clé étrangère de COMMANDES, référençant NUMEROCLI de CLIENTS

Dans le modèle relationnel, la notion de nullité est admise. C’est une valeur représentant une information inconnue ou inapplicable dans une colonne.

Elle est notée _ , ∧ ou NULL.

Toute valeur participant à une clé primaire doit être non NULL.

Exemple

Dans la relation article, on admet que le prix ou le code TVA peuvent être inconnus, mais la référence de l’article (clé primaire) doit être renseignée.

Valeur nulle

Contrainte d’entité

- 3 -© ENI Editions - All rigths reserved

Page 9: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

L’algèbre relationnelle

C’est une méthode d’extraction permettant la manipulation des tables et des colonnes. Son principe repose sur la création de nouvelles tables (tables résultantes) à partir des tables existantes, ces nouvelles tables devenant des objets utilisables immédiatement.

Les opérateurs de l’algèbre relationnelle permettant de créer les tables résultantes sont basés sur la théorie des ensembles.

1. Opérateurs

a. Union

L’union entre deux relations de même structure (degré et domaines) donne une table résultante de même structure ayant comme éléments l’ensemble des éléments distincts des deux relations initiales.

Notation : Rx = R1 ∪ R2

Exemples

Soient les tables CLIOUEST et CLICENTRE :

Clients des deux régions :

CLIENTS=CLIOUEST ∪∪∪∪ CLICENTRE

b. Intersection

L’intersection entre deux relations de même structure (degré et domaines) donne une table résultante de même structure ayant comme éléments l’ensemble des éléments communs aux deux relations initiales.

Notation : Rx = R1 ∩ R2

Exemple

Clients communs aux deux régions :

CLICOMMUN=CLIOUEST ∩ CLICENTRE

c. Différence

- 1 -© ENI Editions - All rigths reserved

Page 10: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

La différence entre deux relations de même structure (degré et domaines) donne une table résultante de même structure ayant comme éléments l’ensemble des éléments de la première relation qui ne sont pas dans la deuxième.

Notation : Rx = R1 ­ R2

Exemple

Clients gérés uniquement par la région OUEST :

CLIOUESTSEUL=CLIOUEST - CLICENTRE

d. Restriction

La restriction selon une condition produit, à partir d’une relation, une relation de même schéma n’ayant que les éléments de la relation initiale qui répondent à la condition.

Notation : Rx = σ (condition) R1

La condition s’exprime sous la forme :

[NON] [(] attribut opérateur valeur [)] [ET/OUcondition]

opérateur un opérateur de comparaison : =, <>, >, <, >=, <=

valeur une constante ou un autre attribut.

Exemples

Clients de NANTES :

CLI44=σ(ADRESSE="NANTES")CLIOUEST

Articles de la famille AB :

ART1=σ(REFART>="AB" ET REFART<"AC")ARTICLES

Tapis "pas chers" :

ART2=σ(PRIX<=1000)ART1

e. Projection

La projection d’une relation sur un groupe d’attributs donne une relation résultante ayant comme schéma uniquement ces attributs, et comme éléments les n­uplets distincts composés par les valeurs associées de ces attributs.

- 2 - © ENI Editions - All rigths reserved

Page 11: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Notation : Rx = π R (A1, A2,.. An).

Exemples

Commandes et états de commande :

CDE= π COMMANDES(NUMEROCDE,NUMEROCLI,ETATCDE)

Clients ayant des commandes :

CLICDE1= π COMMANDES(NUMEROCLI)

Clients et états de commande :

CLIDE2= π COMMANDES(NUMEROCLI,ETATCDE)

f. Produit cartésien

Le produit cartésien entre deux relations produit une relation ayant comme schéma tous les attributs des deux relations existantes et comme éléments l’association de chaque ligne de la première table avec chaque ligne de la deuxième.

Notation : Rx = S1 X S2

Exemple

Soient les tables :

INVENTAIRE = DEPOT X ART2

- 3 -© ENI Editions - All rigths reserved

Page 12: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

g. Jointures

La jointure entre deux relations selon une condition est produite par la restriction sur le produit cartésien.

Notation : Rx = S1 JOIN (condition) S2

Exemple

Soient les tables :

LIGCDEEC = CDEEC JOIN (CDEEC.NUMEROCDE = LIGNESCDE.NOCDE) LIGNESCDE

La condition est une comparaison entre deux attributs.

La condition porte sur l’égalité entre deux attributs.

Équi­jointure entre les attributs portant le même nom.

h. Calculs élémentaires

Projection sur une relation associée à un calcul portant sur chaque ligne pour créer un ou plusieurs nouveaux attributs.

Notation : Rx = π S (A1,...,N1 = expression calculée...)

L’expression calculée peut être :

une opération arithmétique,

Theta­jointure

Equi­jointure

Jointure naturelle

- 4 - © ENI Editions - All rigths reserved

Page 13: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

une fonction mathématique,

une fonction portant sur une chaîne.

Exemple

On veut obtenir le montant d’une ligne de commande (Prix * Quantité).

LIGCDEVALO = π LIGCDE(NOCDE,NOLIG,REFART, VALOLIG=QTECDE*PRIXHT)

i. Calcul d’agrégats

Projection sur une relation associée à un ou des calculs statistiques portant sur un attribut pour tous les éléments de la relation ou du regroupement lié à la projection afin de créer un ou plusieurs nouveaux attributs.

Notation : Rx = π S (A1,...,N1= fonction statistique (Ax),...)

Les fonctions statistiques sont :

COUNT (*) nombre de lignes.

COUNT (attribut) nombre de valeurs non nulles.

SUM (attribut) somme des valeurs non nulles.

AVG (attribut) moyenne des valeurs non nulles.

MAX (attribut) valeur maximum (non nulle).

MIN (attribut) valeur minimum (non nulle).

Exemples

Nombre total de clients dans la table.

NBCLI=π CLIENTS(N=COUNT(*))

Total des montants de la ligne par commande :

CDEVALO=πLIGCDEVALO(NOCDE,TOTCDE=SUM(VALOLIG))

Prix les plus élevés, les moins élevés et moyenne des prix par catégorie d’articles :

STATART=π ARTICLES(CATEGORIE,PLUSCHER=MAX(PRIX),

MOINSCHER=MIN(PRIX),MOYENNE=AVG(PRIX))

- 5 -© ENI Editions - All rigths reserved

Page 14: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

2. Étapes de résolution d’un problème

À partir d’une base de données connue (schémas, domaines, relations, éléments), la résolution d’un problème se fait en trois étapes.

a. Analyser le besoin

Transcrire sous forme de relation résultante des besoins exprimés par le prescripteur.

Déterminer les attributs et les relations à utiliser.

Exprimer les calculs élémentaires et d’agrégats pour créer les attributs inexistants.

b. Établir la "vue"

La vue est une relation intermédiaire contenant tous les attributs permettant de réaliser l’extraction, avec leurs relations d’origine, leurs classes d’utilité, et les opérations à appliquer.

Classe a : attribut participant à la relation résultante.

Classe b : attribut participant à un calcul.

Classe c : attribut participant à une restriction.

Classe d : attribut participant à une jointure.

c. Ordonnancer et exprimer les opérations

D’une façon générale, et sauf exception, l’ordonnancement des opérations peut s’exprimer de la façon suivante :

Relations concernées.

Restrictions (pour éliminer les lignes inutiles).

Jointures, Produits cartésiens, Unions, Intersections, Différences (pour associer les lignes restantes).

Calculs élémentaires (pour créer les nouvelles colonnes).

Calculs d’agrégats (pour les colonnes statistiques).

Jointure entre la table obtenue en et la table initiale en (pour ajouter les colonnes statistiques aux autres).

Répéter les étapes du pour les autres regroupements.

Restrictions par rapport aux attributs calculés.

Projections pour éliminer les doublons.

Projection finale pour éliminer les attributs inutiles dans la table résultante.

Exemple

Soit la base de données composée des tables suivantes :

CLIENTS (NOCLI,NOMCLI,ADRESSE) ARTICLES (REFART,DESIGNATION,PRIXHT) COMMANDES (NOCDE,NOCLI,DATECDE,ETATCDE) LIGNESCDE (NOCDE,NOLIG,REFART,QTECDE)

On veut obtenir l’édition de la confirmation de la commande N°1301.

Maquette du document :

Classes d’attribut

- 6 - © ENI Editions - All rigths reserved

Page 15: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

À l’analyse de la maquette et des tables initiales, on déduit que :

date du jour : information pouvant être placée lors de la mise en page. N° de commande = NOCDE de COMMANDES Date de la commande = DATECDE Nom du client = NOMCLI de CLIENTS Adresse du client = ADRESSE de CLIENTS Référence = REFART de LIGNESCDE Désignation = DESIGNATION de ARTICLES Qté commandée = QTECDE de LIGNESCDE Prix HT = PRIXHT de ARTICLES Montant HT = zone à calculer Total HT = zone à calculer

Pour établir le document, il faudrait donc la table suivante :

CONFCDE (NOCDE,DATECDE,NOMCLI,ADRESSE,REFART, DESIGNATION,PRIXHT,QTECDE,MTHT,TOTHT)

avec MTHT = PRIXHT*QTECDE par ligne de commande et TOTHT = SUM(MTHT) pour la commande.

Restriction sur le numéro de commande :

T1=σ(NOCDE=1301) COMMANDES

Vue

Opérations

- 7 -© ENI Editions - All rigths reserved

Page 16: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

T2=σ(NOCDE=1301) LIGNESCDE

Jointure naturelle COMMANDES et LIGNESCDE :

T3=T1 JOIN (T1.NOCDE=T2.NOCDE) T2

Jointure naturelle COMMANDES et CLIENTS :

T4=T3 JOIN (T3.NOCLI=CLIENTS.NOCLI) CLIENTS

Jointure naturelle LIGNESCDE et ARTICLES :

T5=T4 JOIN (T4.REFART=ARTICLES.REFART) ARTICLES

Projection de calcul élémentaire de MTHT et élimination des colonnes inutiles :

T6=πT5(NOCDE,DATCDE,NOMCLI,ADRESSE,REFART, DESIGNATION,PRIXHT,QTECDE,MTHT=PRIXHT*QTECDE)

Projection de calcul d’agrégat pour TOTHT :

T7=πT6(NOCDE,TOTHT=SUM(MTHT))

Jointure à effectuer pour avoir toutes les colonnes dans la table résultante :

CONFCDE=T6 JOIN (T7.NOCDE=T6.NOCDE) T7

- 8 - © ENI Editions - All rigths reserved

Page 17: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Généralités

Le SQL (Structured Query Language) est un langage de requête utilisé pour la manipulation des bases de données relationnelles.

Il a été créé au milieu des années 70 par IBM et commercialisé par ORACLE en 1979.

L’intérêt du SQL réside dans les caractéristiques suivantes :

Il implémente le modèle relationnel, et les principaux organismes de normalisation le décrivent :

l’ANSI (American National Standards Institute) dans les documents ANSI 9075­1:1999, ANSI 9075­2:1999 et ANSI 9075­5:1999. Il est possible d’obtenir plus de détails sur les documents qui définissent la norme en se rendant sur le site web de l’ANSI (http://webstore.ansi.org/ansidocstore/ default.asp) ou sur le site web de NCITS (National Comittee for Information Technology Standards qui reprend une partie des standards ANSI dont le sql (http://www.cssinfo.com/ncitsgate.html).

l’ISO (International Organisation for Standardization) dans les documents ISO/IEC 9075­1:1999, ISO/IEC 9075­2:1999 et ISO/IEC 9075­5:1999. Il est possible d’obtenir une copie des documents de normalisation sur le site web de l’ISO : http://www.iso.ch/cate/cat.html.

Du fait de cette normalisation, la plupart des éditeurs de SGBDR, intègrent le SQL à leurs produits (INFORMIX, DB2, MS SQL Server, SYBASE...).

Les données, requêtes et applications sont donc assez facilement portables d’une base à une autre.

Le SQL est un langage de requête qui permet à l’utilisateur de demander un résultat sans se préoccuper des moyens techniques pour trouver ce résultat. Un composant du moteur de la base (l’optimizer) se charge de cette tâche.

Les instructions sont écrites dans un langage courant (l’anglais !).

Le SQL manipule aussi bien des ensembles d’enregistrements qu’un seul enregistrement, et permet l’utilisation du résultat dans une autre commande. On n’a donc pas besoin de structures de contrôle comme dans les langages de programmation courants (langages de 3ème génération).

Le SQL peut être utilisé à tous les niveaux dans la gestion d’une base de données :

administration système,

administration de la base,

développement et application,

gestion de données simple.

Tous les utilisateurs de la base ont donc un langage commun.

Ce langage permet d’autre part d’effectuer toutes les opérations :

interrogation des données,

ajout, suppression, modification de données,

gestion des objets (structures),

gestion de la sécurité d’accès aux données.

Normalisation

Standard

Non Procédural

Universel

- 1 -© ENI Editions - All rigths reserved

Page 18: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

1. Composants de la base logique : objets SQL

Une base de données relationnelle est composée d’entités logiques ou physiques manipulables par le langage SQL. Ces entités sont appelées objets SQL.

Le premier est la base de données qui regroupe l’ensemble des autres objets.

On peut regrouper ces objets en différentes catégories en fonction de leur utilité.

a. La gestion des données

table

Ensemble de lignes (row) et de colonnes (column).

index

Colonne ou ensemble de colonnes permettant l’accélération des recherches.

view

Requête pouvant être manipulée comme une table (table virtuelle).

synonym

Nom alternatif pour une table ou une view.

sequence

Générateur de série de nombres.

snapshots

Table contenant le résultat d’une requête faite sur une table gérée dans une base distante.

database links

Lien avec des bases distantes.

b. Le stockage physique

cluster

Regroupement physique de tables ayant des colonnes communes.

tablespace

Regroupement logique de fichiers.

directory

Représentation dans la base de données d’un répertoire du système d’exploitation hôte.

c. Le stockage d’instructions

schema

Ensemble des objets de la base logique appartenant à un même utilisateur.

procedure

- 2 - © ENI Editions - All rigths reserved

Page 19: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Ensemble de code procédural nommé.

function

Ensemble de code procédural nommé retournant une valeur.

database trigger

Ensemble de code procédural associé à une table.

packages

Collection d’objets (procédure, fonction...) stockés ensemble.

library

Représentation d’une collection de procédures externes à Oracle, stockées dans des bibliothèques partagées du système hôte.

d. La gestion des utilisateurs

profile

Ensemble nommé de limites système.

role

Ensemble de privilèges pouvant être attribués à des utilisateurs.

user

Utilisateur pouvant se connecter et accéder aux ressources de la base.

Les objets créés par les utilisateurs du SGBDR Oracle doivent être nommés.

e. Dénomination des objets

Elle doit respecter les règles suivantes :

1 à 30 caractères, sauf database (8) et database links (128).

Pas de distinction majuscule­minuscule.

Commencent par une lettre.

Caractères alphanumériques plus _ $ et # (plus @ et . pour les database links).

Ne doit pas être un mot réservé.

Doit être unique, à l’intérieur du SCHEMA d’un utilisateur, même pour des types d’objets différents.

Les noms utilisés doivent être significatifs, sans être trop longs.

Il est recommandé d’utiliser des noms identiques pour désigner les mêmes entités dans des objets différents de la base de données (nom de colonne).

Si les noms d’objets sont donnés sans guillemets, Oracle ne tient pas compte de la casse utilisée (les noms sont stockés en majuscules à la création des objets et lors des références ultérieures, Oracle opère automatiquement une

Conventions

- 3 -© ENI Editions - All rigths reserved

Page 20: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

conversion en majuscules).

Les noms d’objets peuvent toutefois être cités entre guillemets doubles. Dans ce cas, Oracle utilise la casse donnée entre guillemets pour référencer l’objet. Il est déconseillé d’utiliser cette possibilité, du fait de la lourdeur d’écriture et des risques d’erreur de syntaxe qu’elle engendre.

2. Catégories d’instructions

Les instructions SQL sont regroupées en catégories en fonction de leur utilité et des entités manipulées.

a. DDL (Data Definition Language)

Il permet de gérer les "structures" des objets :

Créer, modifier, supprimer des objets.

Autoriser ou interdire l’accès aux données.

Activer, désactiver l’audit.

Commenter le dictionnaire des données.

Les instructions du DDL sont : CREATE, ALTER, DROP, GRANT, REVOKE, AUDIT, NOAUDIT, ANALYZE, RENAME, TRUNCATE.

b. DML (Data Manipulation Language)

Il permet la gestion des données des objets existants :

Ajout, suppression, modification des lignes.

Visualisation du contenu des tables.

Verrouillage des tables.

Les instructions du DML sont : INSERT, UPDATE, DELETE, SELECT, EXPLAIN PLAN, LOCK TABLE.

c. Transaction Control language

Il gère les modifications faites par le DML :

Caractéristiques des transactions.

Validation, annulation des modifications.

Les instructions du Transaction Control sont : COMMIT, SAVEPOINT, ROLLBACK, SET TRANSACTION.

d. Session Control language

Il permet la gestion d’une session utilisateur :

Modification des caractéristiques de session.

Activation, désactivation des privilèges utilisateurs.

Les instructions du Session Control sont : ALTER SESSION, SET ROLE.

- 4 - © ENI Editions - All rigths reserved

Page 21: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

e. Embedded SQL

Il permet d’intégrer le DDL, le DML et le Transaction Control à un langage de programmation :

Déclarations d’objets ou d’instructions.

Exécutions d’instructions.

Gestions des variables et des cursors.

Traitement des erreurs.

Les instructions du Embedded SQL sont : DECLARE, TYPE, DESCRIBE, VAR, CONNECT, PREPARE, EXECUTE, OPEN, FETCH, CLOSE, WHENEVER.

- 5 -© ENI Editions - All rigths reserved

Page 22: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Description des objets

Dans l’utilisation d’une base de données, les premiers objets à manipuler sont les tables qui "contiennent" les données et les index qui permettent de meilleures performances aux requêtes.

Ces deux objets doivent être créés avant de commencer à manipuler les données elles­mêmes.

1. Les types de données

CHAR(n)

Chaîne de caractères de longueur fixe : n octets complétés à droite par des espaces (n <= 2000).

VARCHAR2(n)

Chaîne de caractères de longueur variable : n octets au maximum (n <=4000)

NCHAR (n)

Chaîne de caractères de longueur fixe : n octets complétés à droite par des espaces (n <=2000). Les caractères sont codés suivant le jeu de caractères national actif.

NVARCHAR2 (n)

Chaîne de caractères de longueur variable : n octets au maximum (n <=4000). Les caractères sont codés suivant le jeu de caractères national actif.

NUMBER (p,s)

Numérique avec une précision de p chiffres dont s décimales avec (1 <= p <= 38 et ­84 <= s <= +127)

DATE

Date comprise entre 1er janvier 4712 avant JC et le 31 décembre 9999 après JC.

TIMESTAMP (p)

Données de type Date (Année, mois, jour, heure, minute et seconde) dans laquelle il est possible de préciser, à l’aide de la précision p, le nombre de chiffres significatifs pour les fractions de secondes. Par défaut ce nombre est 6.

TIMESTAMP(p) WITH TIME ZONE

Données de type TIMESTAMP avec le décalage horaire.

TIMESTAMP(p) WITH LOCAL TIME ZONE

Données de type TIMESTAMP WITH TIME ZONE qui sont stockées sur le serveur en tenant compte de la plage horaire du serveur, mais ces données sont affichées sur le poste client en tenant compte de la zone horaire définie au niveau de la session.

BLOB

Données binaires non structurées (4 Go maximum).

CLOB

Chaîne de caractères de longueur variable (4 Go maximum). Ne peut contenir que des caractères codés sur 1 octet.

NCLOB

Chaîne de caractères de longueur variable (4 Go maximum). Prend en charge les jeux de caractères de longueur variable.

- 1 -© ENI Editions - All rigths reserved

Page 23: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

BFILE

Données binaires stockées dans des fichiers extérieurs à la base de données (4 Go maximum).

Types assurant la compatibilité avec les versions antérieures :

LONG

Chaîne de caractères à longueur variable (2 Go au maximum).

RAW(n)

Données binaires de longueur variable (n octets maximum ; n<=2000) contenu non interprété par Oracle.

LONG RAW (n)

Données binaires de longueur variable (4 Go maximum) contenu non interprété par Oracle.

2. Création d’une table

Une table est un ensemble de lignes et de colonnes. La création consiste à définir (en fonction de l’analyse) le nom de ces colonnes, leur format d’utilisation (type), une valeur par défaut à la création de la ligne (default), les règles de gestion s’appliquant à la colonne (CONSTRAINT). Si une règle de gestion concerne plusieurs colonnes de la ligne, on définit une contrainte de table. Il est possible de définir jusqu’à 1000 colonnes pour chaque table.

Syntaxe

CREATE TABLE nom (nomcolonne type [DEFAULT expr] [[CONSTRAINT nom contrainte-de-colonne...],... [,CONSTRAINT nom contrainte-de-table...]);

a. Contraintes de colonne

NULL/NOT NULL

Autorise (NULL) ou interdit (NOT NULL) l’insertion de valeur NULL pour cet attribut.

PRIMARY KEY

Désigne l’attribut comme clé primaire de la table. Cette contrainte ne peut apparaître qu’une seule fois dans l’instruction.

UNIQUE

Désigne l’attribut comme clé secondaire de la table. Dans le cas de contrainte UNIQUE portant sur une seule colonne, l’attribut peut prendre la valeur NULL. Cette contrainte peut apparaître plusieurs fois dans l’instruction.

REFERENCEStable [(colonne)] [ON DELETE CASCADE]

Contrainte d’intégrité référentielle pour l’attribut dans la table détail en cours de définition. Les valeurs prises par cet attribut doivent exister dans l’attribut colonne qui possède une contrainte PRIMARY KEY dans la table maître.

CHECK(condition)

Vérifie lors de l’insertion de lignes que l’attribut réalise la condition (pour la syntaxe de la condition, voir Manipulation des données).

Attention, il n’est pas possible dans une contrainte CHECK de faire référence à la fonction SYSDATE ou bien CURRENT_DATE pour comparer la valeur d’une colonne de type date avec le résultat de l’exécution de cette fonction. Il est par contre tout à fait possible, si on le souhaite, de comparer à l’aide d’une contrainte CHECK, les valeurs de 2 colonnes de type date.

Si l’on souhaite comparer la valeur d’une colonne de type date avec la date courante, il est nécessaire de passer par la mise en place d’un déclencheur de base de données. Une autre possibilité consiste à créer une colonne de type

- 2 - © ENI Editions - All rigths reserved

Page 24: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

date avec une valeur par défaut égale à la date du jour plus une contrainte CHECK qui compare les valeurs présentent dans les deux colonnes.

b. Contraintes de table (portant sur plusieurs colonnes)

PRIMARY KEY (colonne,...)

Désigne la concaténation des attributs cités comme clé primaire de la table. Cette contrainte ne peut apparaître qu’une seule fois dans l’instruction.

UNIQUE(colonne,...)

Désigne la concaténation des attributs cités comme clé secondaire de la table. Dans ce cas de contrainte UNIQUE portant sur des colonnes concaténées, au moins une des colonnes participant à cette clé secondaire doit permettre de distinguer la ligne. Cette contrainte peut apparaître plusieurs fois dans l’instruction.

FOREIGN KEY (colonne, ...) REFERENCES table [(colonne, ...)] [ON DELETE CASCADE | SET NULL]

Contrainte d’intégrité référentielle pour l’ensemble des attributs dans la table détail en cours de définition. Les valeurs prises par ces attributs doivent exister dans l’attribut colonne qui possède une contrainte PRIMARY KEY ou UNIQUE dans la table maître table.

CHECK(condition)

Cette contrainte permet d’exprimer une condition qui doit exister entre plusieurs attributs de la ligne (pour la syntaxe de la condition, voir Manipulation des données).

Les contraintes de tables portent sur plusieurs colonnes de la table sur laquelle elles sont définies. Il n’est pas possible de définir une contrainte d’intégrité utilisant des colonnes provenant de deux ou plusieurs tables. Ce

type de contrainte sera mis en œuvre par l’intermédiaire de déclencheurs de base de données (triggers) dont la définition est abordée plus loin dans cet ouvrage.

c. Complément sur les contraintes

ON DELETE CASCADE

Demande la suppression des lignes dépendantes dans la table en cours de définition, si la ligne contenant la clé primaire correspondante dans la table maître est supprimée. Si cette option n’est pas indiquée, la suppression sera impossible dans la table maître s’il existe des lignes référençant cette valeur de clé primaire.

ON DELETE SET NULL

Demande la mise à NULL des colonnes constituant la clé étrangère qui font référence à la ligne supprimée. Si cette option n’est pas indiquée, la suppression sera impossible dans la table maître s’il existe des lignes référençant cette valeur de clé primaire.

[NOT] DEFERRABLE

Repousse ou non (NOT) la vérification de la contrainte au moment de la validation de la transaction.

d. Dénomination des contraintes

Les contraintes peuvent être nommées afin d’être plus facilement manipulées ultérieurement (activation, suppression). Dans le cas où aucun nom n’est affecté explicitement à une contrainte, Oracle génère automatiquement un nom de la forme SYS_Cn (n est un nombre entier unique).

Lors de l’affectation explicite d’un nom à une contrainte, il est pratique d’utiliser la convention de dénomination suivante :

Table_Colonne_TypeDeContrainte

Table : nom de la table sur laquelle est définie la contrainte.

- 3 -© ENI Editions - All rigths reserved

Page 25: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Colonne : nom de la ou des colonne(s) sur laquelle (lesquelles) est (sont) définie(s) la contrainte.

TypeDeContrainte : mnémonique associé au type de contrainte :

PK Clé primaire

UQ Unique

NN Not Null

CK Check

RF Références

FK Clé étrangère.

Exemples

Création d’une table ARTICLES avec comme seule contrainte la clé primaire REFART :

SQL> create table ARTICLES( 2 REFART char(4) primary key, 3 DESIGNATION varchar2(30), 4 PRIX number(8,2), 5 CODETVA number(1), 6 CATEGORIE char(10), 7 QTESTK number(5) 8 ); Table créée. SQL>

Dans ce cas, DESIGNATION, PRIX et QTESTK peuvent être NULL : PRIX et QTESTK peuvent être négatifs !

Création d’une table CLIENTS avec traduction des contraintes sur les colonnes :

SQL> create table CLIENTS( 2 NOCLI number(4) 3 constraint CLIENTS_PK primary key 4 constraint CLIENTS_NOCLI_CK check (NOCLI>0), 5 NOMCLI varchar2(30) 6 constraint CLIENTS_NOMCLI_NN not null, 7 ADRCLI varchar2(60), 8 CODE_POSTAL number(5) 9 constraint CLIENTS_CODE_POSTAL_CK 10 check(CODE_POSTAL between 1000 and 99999), 11 VILLE char(30) 12 ); Table créée. SQL>

Le NOCLI et le NOMCLI sont obligatoires ;

Le NOCLI doit être strictement positif ;

Le CODE_POSTAL doit être dans l’intervalle indiqué.

Création de la table des commandes en utilisant une syntaxe de type contrainte de table pour définir les contraintes d’intégrité.

SQL> create table COMMANDES( 2 NOCDE number(6), 3 NOCLI number(4), 4 DATECDE date, 5 ETATCDE char(2), 6 constraint PK_COMMANDES primary key (NOCDE), 7 constraint FK_COMMANDES_CLIENTS foreign key(NOCLI)

- 4 - © ENI Editions - All rigths reserved

Page 26: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

8 references CLIENTS(NOCLI), 9 constraint CK_COMMANDES_ETAT check (ETATCDE in (’EC’,’LI’,’SO’)) 10 ); Table créée. SQL>

Création d’une table LIGCDES avec des contraintes de référence sur des colonnes et une contrainte de table pour la clé primaire.

SQL> create table LIGCDES( 2 NOCDE number(6) 3 constraint FK_LIGCDES_COMMANDES 4 references COMMANDES(NOCDE), 5 NOLIG number(2) 6 constraint CK_LIGCDES_NOLIG check (NOLIG>0), 7 REFART char(4) 8 constraint FK_LIGCDES_ARTICLES 9 references ARTICLES(REFART), 10 QTECDE number(5), 11 constraint PK_LIGCDES primary key(NOCDE,NOLIG) 12 ); Table créée. SQL>

Quel que soit le mode de définition des contraintes (niveau colonne ou niveau table), le résultat est le même. Seules les contraintes d’intégrité portant sur plusieurs colonnes de la même table doivent être définies en

utilisant une syntaxe contrainte de table.

3. Suppression d’une table

Supprimer une table revient à éliminer sa structure et toutes les données qu’elle contient ; les index associés sont également supprimés ; les vues construites directement ou indirectement sur cette table sont désactivées automatiquement par Oracle.

Si la clé primaire de la table est référencée dans d’autres tables par des contraintes REFERENCES ou FOREIGN KEY, la clause CASCADE CONSTRAINTS permet de supprimer ces contraintes d’intégrité référentielle dans les tables "enfants".

La clause PURGE, permet de supprimer la table et de libérer l’espace physique occupée par cette table. En l’absence de cette clause, la table est supprimée logiquement mais pas physiquement. Il est alors possible d’utilisée l’instruction FLASHBACK TABLE pour retrouver la table et ses données au moment de la suppression.

Avec ce principe de fonctionnement, Oracle permet de ne plus rendre définitif une action de suppression de table et facilite ainsi la restauration des tables supprimées de façon abusive.

Syntaxe

DROP TABLE nom [CASCADE CONSTRAINTS] [PURGE];

Exemples

Suppression d’une table CLIENTS dont la colonne NOCLI est clé étrangère dans la table COMMANDES :

SQL>drop table CLIENTS; drop table CLIENTS * ERREUR a la ligne 1: ORA-02266: table a des cles primaires/uniques referencees par des cles etrangeres SQL>drop table CLIENTS cascade constraints; Table supprimée.

Suppression de la table des clients avec demande de libération de l’espace physique.

- 5 -© ENI Editions - All rigths reserved

Page 27: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

4. Modification d’une table

Il est possible de modifier la structure d’une table à plusieurs niveaux :

ajout de colonnes (nom, type, valeur par défaut, contrainte NOT NULL),

ajout de contraintes de colonne (contrainte NOT NULL uniquement),

ajout de contraintes de table,

redéfinition d’une colonne (type, valeur par défaut),

activation, désactivation de contraintes de colonne ou de table,

suppression de contraintes de colonne ou de table,

changement du nom de la table.

a. Ajout ou modification de colonnes

Syntaxe

ALTER TABLE nom ADD/MODIFY ([colonne type [contrainte], ...])

Exemple

SQL> describe CLIENTS Name Null? Type --------------------------- ---------- -------------- NOCLI NOT NULL NUMBER(4) NOMCLI NOT NULL VARCHAR2(30) ADRCLI VARCHAR2(60) CODE_POSTAL NUMBER(5) VILLE CHAR(30) SQL> alter table CLIENTS add (TEL char(14)); Table modifiée. SQL> alter table CLIENTS modify (ADRCLI char(30)); Table modifiée. SQL> describe CLIENTS Name Null? Type ------------------------------ --------- ------------ NOCLI NOT NULL NUMBER(4) NOMCLI NOT NULL VARCHAR2(30)

- 6 - © ENI Editions - All rigths reserved

Page 28: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

ADRCLI CHAR(30) CODE_POSTAL NUMBER(5) VILLE CHAR(30) TEL CHAR(14) SQL>

b. Ajout d’une contrainte de table

Syntaxe

ALTER TABLE nom_table ADD[CONSTRAINT nom] contrainte

La syntaxe de déclaration de contrainte est identique à celle vue lors de la création de la table.

Exemple

L’exemple suivant permet d’ajouter une contrainte de validation à la table ARTICLES.

SQL> alter table ARTICLES 2 add constraint ARTICLES_PRIX_CK check (PRIX >= 0) ; Table modifiée. SQL>

Il est également possible de définir une contrainte de non nullité par l’intermédiaire de la commande ALTER TABLE.

Si des données sont déjà présentes dans la table au moment où la contrainte d’intégrité est ajoutée, alors toutes les lignes d’information doivent vérifier la contrainte. Dans le cas contraire, la contrainte n’est pas posée sur la table.

La clause EXCEPTION INTO TABLE nom_table permet de connaître le rowid (l’identifiant de la ligne pour Oracle) des lignes qui violent la contrainte d’intégrité que l’on tente de poser ou de réactiver. Il est ainsi possible de résoudre facilement le problème.

La table qui va recevoir les références des lignes qui empêchent la création de la contrainte d’intégrité peut être créée par l’intermédiaire du script utlexcpt.sql (utilisation du rowid physique) ou utlexpt1.sql (utilisation du rowid universel) situé dans le répertoire ORACLE_HOME\rdbms\admin.

Création de la table des exceptions :

Positionnez les références des lignes posant problème dans la table des exceptions.

Tentative d’ajout d’une contrainte d’unicité sur l’adresse des clients :

Il faut maintenant utiliser les rowids pour connaître les lignes qui empêchent l’ajout de la contrainte.

Liste des numéros clients qui possèdent la même adresse :

- 7 -© ENI Editions - All rigths reserved

Page 29: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

L’ajout de contrainte sur des tables existantes est une méthode pratique car associée à la création de table, elle permet de produire des scripts de création de tables sans fixer un ordre de création des tables pour tenir compte des contraintes de clé étrangère et de clé primaire.

Structure d’un script de création de table

c. Suppression d’une contrainte

Syntaxe

ALTER TABLE nom_TABLE DROPPRIMARY KEY/UNIQUE (colonne)/CONSTRAINT nom

Exemple

SQL> alter table ARTICLES 2 drop constraint ARTICLES_PRIX_CK; Table modifiée. SQL>

d. Activation, désactivation d’une contrainte

La commande ALTER TABLE permet également d’activer et de désactiver les contraintes d’intégrité. Cette opération peut être intéressante lors d’un import massif de données afin, par exemple, de limiter le temps nécessaire à cette importation.

Syntaxe

ALTER TABLE nom_table ENABLE VALIDATE/ENABLE NOVALIDATE/DISABLE nom_contrainte

- 8 - © ENI Editions - All rigths reserved

Page 30: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

ENABLE VALIDATE

Active la contrainte si l’ensemble des lignes déjà présentes dans la table la respecte.

ENABLE NOVALIDATE

Active la contrainte pour les manipulations de données suivantes.

DISABLE

Désactive la contrainte.

Il est également possible de travailler avec les contraintes de clé primaire et d’unicité en donnant simplement la définition de la contrainte.

Exemple

Désactivation de la contrainte sur la colonne CODE_POSTAL de la table CLIENTS. Insertion dans cette table d’une valeur incompatible avec la contrainte désactivée. Tentative de réactivation de la contrainte avec vérification par rapport aux données présentes dans la table.

SQL> alter table CLIENTS 2 disable constraint CLIENTS_CODE_POSTAL_CK; Table modifiée. SQL> insert into CLIENTS (NOCLI, NOMCLI, CODE_POSTAL, VILLE) 2 values (150, ’MARTIN Jean’, 999, ’MURUOA’) ; 1 ligne créée. SQL> alter table CLIENTS 2 enable validate constraint CLIENTS_CODE_POSTAL_CK; alter table CLIENTS * ERREUR à la ligne 1: ORA-02293: impossible ajouter contrainte de vérification [CLIENTS_CODE_POSTAL_CK] - valeurs non conf. trouvées SQL>

e. Modification d’une contrainte

Il n’est pas possible de modifier la définition d’une contrainte. Par contre, il est tout à fait possible de modifier l’état d’une contrainte.

Syntaxe

ALTER TABLE nom_table MODIFY CONSTRAINT nom_contrainte etat_contrainte;

Les états possibles pour la contrainte sont :

DEFERRABLE

La validation de la contrainte peut être reportée à la fin de la transaction.

NOT DEFERRABLE

La contrainte est vérifiée à la fin de chaque instruction du DML. Cette option est activée par défaut.

INITIALLY IMMEDIATE

Pour chaque nouvelle transaction, le fonctionnement par défaut consiste à vérifier la contrainte à la fin de chaque

- 9 -© ENI Editions - All rigths reserved

Page 31: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

ordre du DML. Cette option est sélectionnée par défaut.

INITIALLY DEFERRED

Implique que la contrainte est en mode DEFERRABLE et précise que par défaut cette contrainte est vérifiée uniquement à la fin de la transaction.

RELY ou NORELY

Permet de préciser si lors de l’activation d’une contrainte, elle doit être vérifiée sur les données déjà présentes dans la table. Par défaut c’est le mode NORELY qui est choisi. Ce mode stipule que la contrainte doit être vérifiée par toutes les lignes lors de son activation. Le mode RELY permet quant à lui de réactiver une contrainte sans s’assurer au préalable que les informations contenues dans la table vérifient la contrainte.

USING INDEX

Permet de préciser les paramètres des index utilisés pour mettre en place les contraintes de clés primaire et d’unicité.

Exemple

Modification de la contrainte de référence entre les tables LIGNESCDE et COMMANDES.

f. Suppression de colonnes

Il est possible de supprimer une colonne en utilisant la clause DROP COLUMN de l’instruction ALTER TABLE. Cette opération permet de récupérer l’espace disque occupé par chaque colonne supprimée.

Syntaxe

ALTER TABLE nom_table DROP COLUMN nom_colonne;

ou

ALTER TABLE nom_table DROP (nom_colonne, nom_colonne[,...]);

Exemple

Suppression de la colonne TEL dans la table CLIENTS.

Une suppression de colonne dans une table existante et possédant de nombreuses lignes peut s’avérer une opération très longue. Il peut parfois être plus opportun de rendre la colonne inutilisable à l’aide de la clause SET UNUSED. Cette option ne permet pas de libérer l’espace disque occupé par la colonne, mais elle permet de planifier l’opération de suppression de la colonne à un moment où la charge de travail pour le serveur est moindre.

Syntaxe

ALTER TABLE nom_table SET UNUSED (nom_colonne[,...]); ALTER TABLE nom_table DROP UNUSED COLUMNS [CHECKPOINT nombre_lignes];

Exemple

Rendre inutilisable la colonne TEL de la table CLIENT. Dans un premier temps, la colonne est masquée comme inutilisée.

- 10 - © ENI Editions - All rigths reserved

Page 32: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Dans un deuxième temps, il faut supprimer toutes les colonnes inutilisées de la table CLIENT. Lors de cette opération, on demande au système de réaliser un point de synchronisation (CHECKPOINT) toutes les 200 suppressions. Cette précaution évite de saturer le cache­buffer de données avec les données en cours de suppression et permet de réaliser très souvent des écritures disque.

Pour connaître les tables qui contiennent des colonnes inutilisées, il faut interroger la vue du dictionnaire de données intitulée DBA_UNUSED_COL_ TABS.

g. Changement de nom d’une table

L’instruction RENAME permet de renommer une table mais également les vues, les séquences et les synonymes privés.

Les synonymes publics ne peuvent être renommés et doivent être supprimés puis recréés.

Syntaxe

RENAME ancien_nom TO nouveau_nom;

Exemple

Renommer la table ARTICLES en table PRODUITS.

5. Restauration d’une table

L’instruction FLASHBACK TABLE permet de restaurer de façon automatique une table modifiée de façon accidentelle. Le laps de temps pendant lequel il est possible de revenir à la version précédente de la table est fonction de l’espace d’annulation réservé par la base.

Il n’est pas possible d’inclure cette opération dans une transaction.

Oracle ne peut pas exécuter l’instruction FLASHBACK TABLE si une modification de structure a eu lieu sur la table.

Cette instruction permet d’annuler la suppression d’une table effectuée avec l’instruction DROP TABLE.

Syntaxe

FLASHBACK TABLE nomTable TO BEFORE DROP;

- 11 -© ENI Editions - All rigths reserved

Page 33: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Exemple

Dans l’exemple suivant, la table ligcdes est supprimée par mégarde et restaurée grâce à l’action de l’instruction FLASHBACK TABLE.

L’instruction FLASHBACK TABLE permet d’annuler les modifications effectuées par les instructions INSERT, UPDATE ou DELETE sur une table. Il est même possible de restaurer les données d’une ou de plusieurs tables jusqu’à une date et heure précises.

Pour pouvoir bénéficier de cette fonctionnalité, la table doit être configurée de façon à prendre en charge un historique sur les modifications. Il est possible de lever cette option soit lors de la création de la table, en utilisant la clause enable row movement, ou bien lors d’une modification de la table.

Syntaxe

CREATE TABLE nomtable (....) ENABLE ROW MOVEMENT; ALTER TABLE nomtable ENABLE ROW MOVEMENT; FLASHBACK TABLE nomTable TO_TIMESTAMP(dateHeure, formatDateHeure);

Exemple

Activer la prise en charge de l’historique des mouvements sur la table des clients.

Dans l’exemple suivant, les clients dont le nom commencent par E ont été supprimés par mégarde. La transaction est maintenant validée et les données modifiées sont visibles de tous les utilisateurs.

- 12 - © ENI Editions - All rigths reserved

Page 34: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Heureusement, l’utilisateur a noté l’heure à laquelle cette opération malencontreuse a été exécutée. Il est alors possible de restaurer les données supprimées sans pour autant faire une restauration complète de la base de données.

Il existe également au niveau de la base de données l’instruction FLASHBACK DATABASE.

6. Gestion des index

Les index ont pour but l’amélioration des performances des requêtes. Ils sont utilisés implicitement par l’optimiseur de requêtes ORACLE, et sont mis à jour automatiquement avec les lignes.

On crée des index, de manière générale, sur toutes les clés étrangères et sur les critères de recherche courants.

Les index concernant les clés primaires et secondaires (index UNIQUE) sont créés automatiquement au CREATE TABLE avec comme nom, le nom de la contrainte. Pour les autres index, il faut utiliser le CREATE INDEX.

La mise en place des contraintes de clés primaires et d’unicité passe par la création implicite d’un index.

a. Création d’un index

Syntaxe

CREATE INDEX nom ON table (colonne [DESC] [, ...]);

Exemples

Création d’un index sur les clés étrangères REFART de la table LIGNESCDE.

SQL>create index FK_LIGART on LIGNESCDE (REFART); Index créé.

- 13 -© ENI Editions - All rigths reserved

Page 35: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Création d’un index sur la table CLIDIVERS sur les colonnes NOM et ADRESSE (critère de recherche) concaténées.

SQL>create index IK_CLID on CLIDIVERS (NOMCLIENT, ADRESSE); Index créé.

b. Suppression d’un index

Syntaxe

DROP INDEX nom ;

Il existe des index de différents types qui possèdent une incidence directe sur l’organisation physique des données et ces choix relèvent de l’administration.

- 14 - © ENI Editions - All rigths reserved

Page 36: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Manipulation des données

Les instructions du DML permettent l’ajout, la suppression, la modification et la visualisation des lignes dans les tables existantes.

1. Les instructions

Les instructions SQL manipulent des expressions. Ces expressions font référence à des noms d’objets de la base, à des constantes, comportent des appels à des fonctions standardisées et composent ces éléments avec des opérateurs.

Des expressions logiques (conditions) permettent également de définir la portée des instructions.

a. Expressions

Les termes des expressions peuvent être :

constantes caractères

exemple : ’chaîne de caractères’ ; ’Ecole Nantaise d’’Informatique’.

constantes littérales date (format dépendant de la langue configurée pour l’instance)

exemple : ’15­JAN­94’

constantes numériques

exemple : 10 ; ­123.459 ; ­1.26e+6

noms d’attribut de table

exemple : CLIENTS.NOCLI, ARTICLES.DESIGNATION

fonctions

exemple : SQRT(81) ; REPLACE(’IAGADIGI’, ’I’, ’OU’);SYSDATE

pseudo­colonnes

exemple : nomsequence.NEXTVAL ; ROWID.

b. Opérateurs

arithmétiques + ­ / * ( )

exemple : 1.15 * PRIX ; (2 * MTLIG)/5 ; SYSDATE +15

sur les chaînes de caractères : concaténation ||

exemple : ’Monsieur’|| NOM

c. Conditions

Les conditions mettent en jeu des expressions, des opérateurs de comparaison et des opérateurs logiques.

La valeur des expressions logiques peut être VRAI, FAUX ou INCONNU. Une comparaison sera évaluée comme

Opérateurs de comparaison

- 1 -© ENI Editions - All rigths reserved

Page 37: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

INCONNU si au moins un de ses termes est NULL.

Comparaison simple

expression1 =,!=,<>, <,<=, >, >= expression2

Appartenance à un ensemble de valeurs

expression1 IN (expression2,...)

VRAI si expression1 apparaît au moins une fois dans la liste (expression2,...).

Appartenance à un intervalle de valeurs

expression1 BETWEEN expression2 AND expression3

VRAI si expression1 se situe entre les bornes expression2 et expression3, bornes comprises.

Comparaison par rapport à un format de chaîne de caractères

expression1 LIKE ’format’

Le format peut inclure les méta­caractères :

"%" pour désigner une suite de 0 à n caractères

"_" pour désigner un et un seul caractère.

Une expression INCONNU est traitée comme une expression de valeur FAUX.

Négation d’une expression logique

NOT expression

Combinaison d’expressions logiques

expression1 AND / OR expression2

d. Fonctions

Il existe deux types de fonctions :

Les fonctions scalaires (scalar function) qui portent sur une seule ligne : la fonction est exécutée et retourne un résultat pour chaque ligne de la requête.

Les fonctions sur un regroupement de lignes (group function) : la fonction est exécutée une fois et retourne un résultat pour un ensemble de lignes de la requête. Ces fonctions sont appelées fonctions d’agrégat.

Si une fonction est appelée avec un argument NULL, la valeur retournée est NULL. Cette règle s’applique à toutes les fonctions à l’exception de CONCAT, NVL et REPLACE.

Notation des arguments des fonctions :

n expression numérique.

d expression date.

Opérateurs logiques

- 2 - © ENI Editions - All rigths reserved

Page 38: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

c expression caractère.

b expression logique.

ABS (n)

valeur absolue de n.

CEIL (n)

premier entier supérieur ou égal à n.

COS (n)

cosinus.

COSH (n)

cosinus hyperbolique.

EXP (n)

e puissance n (e=2,71828183...).

FLOOR (n)

1er entier <=n.

LN (n)

logarithme népérien de n.

LOG (m,n)

logarithme de n base m.

MOD (n1,n2)

reste de n1/n2.

POWER (n1,n2)

n1 exposant n2.

ROUND (n1,[n2])

n1 arrondi à n2 positions décimales.

SIGN (n)

­1 si n<0; 0 si n=0; +1 si n>0.

SIN (n)

sinus de n.

SINH (n)

sinus hyperbolique de n.

SQRT (n)

Fonctions scalaires mathématiques

- 3 -© ENI Editions - All rigths reserved

Page 39: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

racine carrée de n.

TAN (n)

tangente de n.

TANH (n)

tangente hyperbolique de n.

TRUNC (n1,[n2])

n1 tronqué à n2 positions décimales.

La plupart des fonctions numériques retournent une valeur avec 38 chiffres significatifs. Cependant les fonctions COS, COSH, EXP, LN, LOG, SIN, SINH, SQRT, TAN et TANH retournent une valeur avec seulement 36 chiffres

significatifs.

ASCII (c)

code ASCII du 1er caractère de c.

ASCIISTR (c)

la chaîne de caractères passée en paramètre est convertie au format de la table ASCII de la base.

CHR (n)

caractère ASCII du code n.

CONCAT (c1, c2)

concaténation de c1 et c2.

INITCAP (c)

renvoie c avec la première lettre de chaque mot en majuscule et les autres en minuscules.

INSTR (c1,c2[,n1[n2]])

position de la nème occurrence (défaut 1ère) de c2 dans c1 à partir de la position n1 (1 par défaut).

INSTRB (c1,c2,n1[,n2])

identique à INSTR avec n1 et n2 en octets.

LENGTH (c)

nombre de caractères de c.

LENGTHB (c)

identique à LENGTH retourne le nombre d’octets.

LOWER (c)

renvoie c en minuscules.

LPAD (c1,n[,c2])

Fonctions scalaires chaînes de caractères

- 4 - © ENI Editions - All rigths reserved

Page 40: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

renvoie c1 sur une longueur n complété à gauche avec c2 (par défaut ’ ’).

LTRIM (c1[,c2])

renvoie c1 avec suppression à gauche de tous les c2 (par défaut ’ ’).

NLS_INITCAP (c,’param’)

identique à INITCAP en tenant compte de param (code de pays).

NLS_LOWER (c,’param’)

identique à LOWER en tenant compte de param (code de pays).

NLSSORT (c)

code du caractère c dans la table NLS.

NLS_UPPER (c,’param’)

identique à UPPER en tenant compte de param (code de pays).

REPLACE (c1,c2,c3)

remplace dans c1 tous les c2 par c3 (c3 peut être nul).

RPAD (c1,n[,c2])

renvoie c1 sur une longueur n complété à droite avec c2 (par défaut ’ ’).

RTRIM (c1[,c2])

renvoie c1 avec suppression à droite de tous les c2 (par défaut ’ ’).

SOUNDEX (c)

représentation phonétique de c.

SUBSTR (c,n1[,n2])

renvoie une chaîne formée par n2 caractères de c à partir de la position n1.

SUBSTRB (c,n1[,n2])

identique à SUBSTR avec n1 et n2 en octets.

TRANSLATE (c1,c2,c3)

remplace dans c1 tous les c2 par c3 (c3 ne peut pas être nul).

TRIM (LEADING |TRAILING|BOTH c1 | c1 FROM c2 )

le caractère c1 est supprimé de la chaîne c2 soit en tête de chaîne (LEADING), soit en fin de chaîne (TRAILING), soit les deux (BOTH ou aucun mot clé).

UNISTR (c)

la chaîne de caractères passée en paramètre est convertie au format unicode.

UPPER(c)

renvoie c en majuscules.

- 5 -© ENI Editions - All rigths reserved

Page 41: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

ADD_MONTHS (d,n)

date d plus n mois.

COMPOSE (c)

la chaîne de caractères passée en paramètre est convertie en format UNICODE.

CURRENT_DATE

pour connaître la date et l’heure actuelle en prenant en compte le paramétrage de la zone horaire (TIME_ZONE) de la session.

CURRENT_TIMESTAMP

pour connaître la date et l’heure relative à la plage horaire de la session. Cette fonction retourne une valeur de type timestamp with time zone.

DBTIMEZONE

pour connaître la zone horaire en vigueur sur la base de données.

DECOMPOSE (c)

cette fonction est valide uniquement pour les chaînes au format unicode et elle retourne une chaîne contenant les différents caractères saisis.

EXTRACT (format FROM d)

extrait un élément (jour, mois, année, heure, minute, seconde...) depuis un élément de type date ou bien un intervalle de temps calculé à l’aide des fonctions NUMTODSINTERVAL ou NUMTOYMINTERVAL.

FROM_TZ (t, zone_horaire)

convertit une valeur de type TIMESTAMP en valeur de type TIMESTAMP WITH TIME ZONE.

LAST_DAY (d)

date du dernier jour du mois de d.

LOCALTIMESTAMP

pour connaître la date et heure courante par rapport à la zone horaire de la session. Cette fonction retourne une valeur de type timestamp.

MONTHS_BETWEEN (d1,d2)

différence entre les deux dates.

NEW_TIME (d,z1,z2)

la date d de la zone z1 est convertie en date de la zone z2.

NEXT_DAY (d,j)

date du prochain jour j à partir de d.

NUMTODSINTERVAL (n,format)

convertit le nombre n passé en paramètre au format date. Le second argument représente l’unité dans laquelle n est exprimé. Les valeurs possibles sont ’DATE’, ’HOUR’, ’MINUTE’ et ’SECOND’.

NUMTOYMINTERVAL (n, format)

Fonctions scalaires dates

- 6 - © ENI Editions - All rigths reserved

Page 42: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

convertit le nombre n passé en paramètre au format mois, année. Le format indiqué en second paramètre permet de préciser si le premier paramètre représente des mois (’MONTH’) ou des années (’YEAR’).

ROUND (d, format)

arrondit la date d à la date de début de l’élément donné en format le plus proche (Année, Mois, Jour, Heure...).

SESSIONTIMEZONE

pour connaître la zone horaire active dans la session actuelle.

SYSDATE

date système.

SYS_EXTRACT_UTC (d)

convertit une date et heure d’une zone horaire spécifique en date et heure au format UTC (Universal Time Coordinated) c’est­à­dire à l’heure de Greenwich.

SYSTIMESTAMP

pour connaître la date et l’heure, y compris les fractions de secondes, en s’appuyant sur la zone horaire configurée sur le serveur de base de données.

TRUNC (d, format)

tronque la date d au début de l’élément donné en format (Année, Mois, Jour, Heure...).

TZ_OFFSET (zone|format)

permet de connaître la zone horaire correspondant à la zone passée en paramètre.

Les formats de dates sont utilisés par les fonctions de conversion (TO_CHAR, TO_DATE) et les fonctions qui manipulent les dates (TRUNC, ROUND). On trouve ci­dessous un tableau récapitulatif des principaux indicateurs de format de dates qui peuvent être utilisés.

­ / ’ . ; : ’texte’ Éléments de séparation présents dans le résultat.

D Numéro du jour dans la semaine (1 à 7). Cet indicateur est à utiliser uniquement avec la fonction TO_DATE.

DAY Nom du jour de la semaine sur 9 caractères.

DD Numéro du jour dans le mois(1 à 31).

DDD Numéro du jour dans l’année (1 à 366).

DY Nom abrégé du jour de la semaine.

HH, HH12 Heure du jour (1 à 12).

HH24 Heure du jour (0 à 23).

­ / ’ . ; : ’texte’ Éléments de séparation présents dans le résultat.

IW Numéro de la semaine dans l’année (1 à 53) basé sur la norme ISO.

MI Minute (0 à 59).

- 7 -© ENI Editions - All rigths reserved

Page 43: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

La gestion des dates est nettement facilitée par le package TIMESERIES. Ce package standard Oracle est installé sous le schéma ORDSYS.

BIN_TO_NUM (expr[, ...])

conversion d’un ensemble de nombres binaires en son équivalent décimal.

CHARTOROWID (char)

conversion de chaîne de caractères de forme ’nobloc.nolig.nofich’ en type ROWID. Cette pseudo­colonne représente l’adresse physique de la ligne dans la base Oracle.

CONVERT (char[,dest[,dest[,source]])

conversion de types.

HEXTORAW (char)

conversion d’une valeur hexadécimale contenue dans une chaîne de caractères en une expression binaire de type RAW.

RAWTOHEX (raw), RAWTONHEX (raw)

fonction inverse de la précédente.

ROWIDTOCHAR(rowid), ROWIDTONCHAR (rowid)

fonction inverse de CHARTOROWID.

source ou destination

US7ASCII (défaut), WE8DEC (Dec Europe), WE8JHP (HP Europe), F7DEC (français DEC), WE8EBDCIC500 (IBM Europe Code page 500), WE8PC850 (IBM PC Code page 850), WE8ISO8859P1 (ISO8859­1 Europe 8 bits).

MM Numéro du mois sur 2 caractères (1 à 12).

MON Nom abrégé du mois.

MONTH Nom du mois sur 9 caractères.

Q Numéro du trimestre (1 à 4).

RM Numéro du mois en chiffre romain (I à XII).

SS Secondes (0 à 59).

SSSS Nombre de secondes depuis minuit (0 à 86399).

WW Numéro de la semaine dans l’année. La semaine n°1 commence le premier jour de l’année et dure 7 jours.

W Numéro de la semaine dans le mois (1 à 5). La première semaine du mois commence le premier jour du mois et se termine le septième jour.

YYYY

YYY

YY

Y

Année sur 4, 3, 2 ou 1 chiffre(s).

Fonctions scalaires de conversion

- 8 - © ENI Editions - All rigths reserved

Page 44: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

TO_CHAR (caractère)

conversion d’une chaîne de caractères au format NCHAR, NVARCHAR2, CLOB ou NCLOB dans la table de caractères utilisée dans la base de données.

TO_CHAR (n,[format[,’param’]])

conversion numérique en caractères.

format : chaîne de caractères représentant le format numérique (les éléments possibles de cette chaîne de caractères sont présentés dans le tableau des formats de date vu précédemment).

param : convention de pays.

TO_CHAR (d, format)

conversion d’une date en chaîne de caractères.

TO_CLOB (chaîne)

conversion d’une chaîne de caractères ou de type LOB au format CLOB.

TO_DATE (char, format)

fonction inverse de TO_CHAR (caractère en date).

TO_DSINTERVAL (chaîne)

conversion d’une chaîne de caractères en données de type intervalle Jour/Seconde.

TO_NCHAR (c)

conversion d’une chaîne de caractères au format NCHAR.

TO_NCHAR (d,format)

conversion d’une date au format NCHAR.

TO_NCHAR (n)

conversion d’un nombre en chaîne de caractères de type NCHAR.

TO_NCLOB (c)

conversion d’une chaîne de caractères en élément de type NCLOB.

TO_NUMBER (char)

conversion d’une chaîne de caractères en numérique.

TO_TIMESTAMP (c[,format])

conversion d’une chaîne de caractères en élément de type TIMESTAMP en s’appuyant sur le format de la date indiqué en second paramètre.

TO_TIMESTAMP_TZ (c[,format])

conversion d’une chaîne de caractères en élément de type TIMESTAMP WITH TIME ZONE en s’appuyant sur le format de la date indiqué en second paramètre.

TO_YMINTERVAL (chaîne)

conversion d’une chaîne de caractères en données de type intervalle Mois/Année.

- 9 -© ENI Editions - All rigths reserved

Page 45: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Exemple d’utilisation de fonctions de conversion

Dans l’exemple ci­dessous, la fonction SYSDATE permet de connaître la date et l’heure actuelle puis ces informations sont affichées proprement à l’aide de la fonction de conversion de TO_CHAR. Pour convertir la date en chaîne de caractères, on utilise un format de conversion dont les indicateurs sont donnés dans le tableau précédent.

NULLIF (expr1, expr2)

Compare expr1 et expr2. Si les deux expressions sont égales, alors la valeur NULL est retournée, sinon expr1 est retournée. Il n’est pas possible de préciser la valeur NULL dans expr1.

BITAND (arg1, arg2)

effectue une opération ET entre les deux arguments bit par bit.

COALESCE (expr,[, ...])

retourne la première expression non nulle passée en paramètre.

DECODE (colonne, valeur 1, resul1 [,valeur2, resul2 ...],[défaut])

si colonne a la valeur valeur 1, la forme sera resul1.

DUMP (exp[,format[,départ[longueur]]])

les formats possibles sont :

8 (le résultat est exprimé en octal),

10 (le résultat est exprimé en décimal),

16 (le résultat est exprimé en hexadécimal),

17 (le résultat est exprimé en caractères).

Les options départ et longueur permettent de préciser la partie de la chaîne à traiter.

GREATEST (exp[,exp...])

renvoie la plus grande des expressions.

LEAST (exp[,exp......])

renvoie la dernière des expressions.

NVL (exp1, exp2)

si expression1 est NULL renvoie expression2.

NVL2 (exp1, exp2, exp3)

Fonctions de comparaisons

Fonctions scalaires diverses

- 10 - © ENI Editions - All rigths reserved

Page 46: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

si expression1 est NULL, alors la fonction NVL2 retourne expression2, sinon c’est expression3 qui est retournée. Les expressions 2 et 3 peuvent être de n’importe quel type de données à l’exception du type LONG.

UID

numéro identificateur de l’utilisateur.

USER

nom de l’utilisateur.

USERENV (opt)

renvoie des caractéristiques de l’environnement.opt : ENTRY id ; SESSION id ; TERMINAL ; LANGUAGE.

VSIZE (exp)

nombre d’octets stockés pour exp.

WIDTH_BUCKET (expr, mini, maxi, n)

construit n intervalles équivalents sur la plage mini à maxi puis indique dans quel intervalle se trouve chaque expression.

2. Création de lignes

L’ajout d’une ligne à la table est réalisé si les contraintes sont respectées. Si les noms des colonnes à valoriser ne sont pas cités, une expression doit être donnée pour chaque colonne dans l’ordre des définitions de colonne faites lors de la création de la table. Aucune colonne ne peut être omise.

Syntaxe

INSERT INTO table [(colonne ,...)] VALUES (expression ,...) ;

Exemples

Création d’un client (les colonnes non citées sont à NULL).

SQL> insert into CLIENTS (NOCLI, NOMCLI) 2 values (37, ’Ets LAROCHE’); 1 ligne créée. SQL>

Valorisation de toutes les colonnes pour un article :

SQL> insert into ARTICLES 2 values (’AB03’, ’Carpettes’, 150, 2, ’IMPORT’, 80); 1 ligne créée. SQL>

Valorisation d’une ligne de commande, avec saisie de variable par SQLPLUS (première colonne, voir chapitre SQL*Plus) et expression pour le calcul de la quantité (dernière colonne) :

SQL> insert into LIGCDES 2 values (&NumCde, 1, ’AB10’, 2+6); Entrez une valeur pour numcde: 1 ancien 2: values (&NumCde, 1, ’AB10’, 2+6) nouveau 2: values (1, 1, ’AB10’, 2+6) 1 ligne créée. SQL>

- 11 -© ENI Editions - All rigths reserved

Page 47: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Pour insérer une valeur NULL dans une colonne, il faut remplir toutes les colonnes pour lesquelles on possède une valeur, à l’aide de la syntaxe indiquée dans l’exemple ci­dessus (les autres colonnes auront la valeur NULL).

Pour utiliser la valeur par défaut d’une colonne lors de l’insertion, il est possible d’utiliser le mot clé DEFAULT.

L’instruction INSERT permet d’ajouter une ou plusieurs lignes dans la table de destination.

Si l’insertion d’une ligne d’informations est le fonctionnement le plus fréquent, il est également possible d’ajouter plusieurs lignes dans la table. Ces lignes insérées de façon massive sont extraites de la base de données par une requête de type SELECT.

Ce processus facilite le transfert de données d’une table à une autre.

Syntaxe

INSERT INTO table[(colonne, ...)] SELECT colonne,... . FROM table ...;

Exemple

Extraction de la liste des clients qui habitent Nantes vers une nouvelle table.

3. Suppression de lignes

L’instruction DELETE supprime toutes les lignes d’une table. Si la clause WHERE est utilisée, seules les lignes pour lesquelles la condition est vraie sont supprimées.

Syntaxe

DELETE FROM table [WHERE condition] ;

Instruction DELETE

- 12 - © ENI Editions - All rigths reserved

Page 48: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Exemples

Suppression d’un article facture :

SQL>delete from ARTICLES where REFART = ’ZZZZ’; 1 ligne supprimée.

Tentative de suppression d’articles valant entre 153 et 306 euros. Certains de ces articles sont référencés dans d’autres tables, d’où l’erreur :

SQL> delete from ARTICLES 2 where PRIX >153 and PRIX <306; delete from ARTICLES * ERREUR à la ligne 1 : ORA-02292: violation de contrainte (JGABILLAUD.FK_LIGCDES_ARTICLES) d’intégrité - enregistrement fils existant SQL>

Suppression des lignes référençant les articles :

SQL> delete from LIGCDES; 1 ligne supprimée. SQL>

Suppression des articles valant entre 153 et 306 euros (AB10, AB22) :

SQL> delete from ARTICLES 2 where PRIX between 153 and 306; 2 ligne(s) supprimée(s). SQL>

Suppression des articles dont la désignation commence par "Ca" (AA00;AB03) :

SQL>delete from ARTICLES where DESIGNATION like ’Ca%’; 2 ligne(s) supprimée(s).

Suppression des articles dont la quantité en stock n’est pas valorisée :

SQL>delete from ARTICLES where QTESTK is null; 2 ligne(s) supprimée(s).

L’instruction TRUNCATE permet de supprimer toutes les lignes d’une table et de reprendre les conditions de stockage adoptées lors de la création de la table.

Syntaxe

TRUNCATE TABLE table

Exemple

Suppression des produits.

Instruction TRUNCATE

- 13 -© ENI Editions - All rigths reserved

Page 49: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

4. Modification de lignes

L’instruction UPDATE permet de remplacer, dans une table, la valeur des colonnes spécifiées par des expressions. Si aucune clause WHERE n’est spécifiée, la mise à jour est réalisée pour toutes les lignes de la table. Dans le cas contraire, seules les lignes pour lesquelles la condition spécifiée dans la clause WHERE est vérifiée sont mises à jour.

Syntaxe

UPDATE table SET colonne = expression, ... [WHERE condition];

Exemples

Mise à jour de la quantité en stock à 15 pour l’article AB10 :

SQL>update ARTICLES set QTESTK=15 where REFART=’AB10’; 1 ligne mise à jour.

Augmentation de 10% du prix pour les articles dont la référence commence par AB :

SQL> update ARTICLES 2 set PRIX=PRIX*1.1 3 where REFART like ’AB%’; 4 ligne(s) mise(s) à jour.

Passage de la désignation en majuscules et élimination des espaces en fin de référence pour tous les articles :

SQL>update ARTICLES set DESIGNATION=UPPER(DESIGNATION), REFART=rtrim (REFART); 8 ligne(s) mise(s) à jour.

5. Extraction des données

L’instruction SELECT permet d’afficher les données d’une table, vue ou synonyme.

Syntaxe

SELECT * | expression, ... FROM table [WHERE condition];

* signifie toutes les colonnes.

Exemple

Visualisation de toute la table ARTICLES :

SQL> select * from ARTICLES ;

Table initiale :

SQL> select * from ARTICLES ; REFA DESIGNATION PRIX CODETVA CATEGORIE QTESTK ------------------ ---------- -------- ---------- ----------- AB22 Tapis Persan 1250,1 2 IMPORT 5 CD50 Chaine HiFi 735,4 2 IMPORT 7 ZZZZ Article bidon DIVERS 25 AA00 CAdeau 0 DIVERS 8 AB03 Carpette 150 2 SOLDES 116 AB Tapis 2 DIVERS 2 ZZ01 Lot de tapis 500 2 DIVERS 0 AB10 Tapis de Chine 1500 2 IMPORT 10 8 ligne(s) sélectionnée(s). SQL>

Références ayant moins de 20 unités en stock :

- 14 - © ENI Editions - All rigths reserved

Page 50: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

SQL> select REFART from ARTICLES where QTESTK < 20 ; REFA ---- AB22 CD50 AA00 AB ZZ01 AB10 6 ligne(s) sélectionnée(s). SQL>

6. Contrôle des transactions

Une transaction est un ensemble d’instructions du DML (INSERT, UPDATE, DELETE) exécutées entre deux commandes CONNECT, COMMIT et ROLLBACK.

La transaction permet de s’assurer que l’ensemble des instructions inclus dans celle­ci sera réalisé dans sa totalité ou pas du tout.

Une seule transaction est active à un instant donné. Cette transaction se termine lors de l’utilisation de l’instruction COMMIT ou ROLLBACK. Une nouvelle transaction débute lors de la première instruction DML suivante.

Chaque transaction permet également d’assurer la cohérence des données vues par chaque utilisateur connecté au SGBDR. En effet toutes les modifications faites sur les données au cours d’une transaction se font par rapport à l’état de ces données au début de la transaction. Les modifications apportées sur les données au cours d’une transaction exécutée par un utilisateur ne seront visibles des autres utilisateurs qu’après la validation (COMMIT) de cette transaction.

a. Validation de la transaction

Les modifications de lignes depuis le dernier COMMIT ou CONNECT deviennent définitives.

Il est également possible de mettre fin à une transaction en succès simplement en exécutant une instruction du DDL, comme par exemple une commande CREATE, ALTER ou DROP. En effet, les instructions du DDL ne peuvent pas participer à la transaction. La transaction en cours est donc finie avec succès, puis l’instruction DDL est exécutée et une nouvelle transaction débute. Cette nouvelle transaction concernera les instructions DML qui suivent. Cette validation de transaction est faite de façon implicite et peut être la source d’erreur dans la compréhension du mécanisme des transactions.

Syntaxe

COMMIT;

b. Annulation des modifications

Les modifications de lignes faites depuis le dernier COMMIT, CONNECT ou le SAVEPOINT mentionné sont annulées.

Si le ROLLBACK indique un SAVEPOINT, la transaction en cours est toujours active après l’exécution de l’instruction.

Syntaxe

ROLLBACK [TO savepoint];

c. Déclaration d’un point de contrôle

Un point de contrôle permet de mémoriser un état des données au cours de la transaction. La pose d’un SAVEPOINT permet d’annuler les modifications faites après la pose de celui­ci.

La transaction en cours est toujours active après la pose du SAVEPOINT.

Syntaxe

SAVEPOINT savepoint;

Exemple

- 15 -© ENI Editions - All rigths reserved

Page 51: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

SQL> savepoint s1; Savepoint créé. SQL> select nocli, rtrim(nomcli), ville from clients; NOCLI RTRIM(NOMCLI) VILLE ---------- --------------------------- ------------------------------ 15 DUPONT S.A. NANTES 20 Etb LABICHE NANTES 35 DUBOIS Jean NANTES 36 Bernard S.A. PARIS 37 Ets LAROCHE 138 DUBOIS Jean TOURS 152 LAROCHE LE MANS 7 ligne(s) sélectionnée(s). SQL> delete from clients where nocli>35; 4 ligne(s) supprimée(s). SQL> select nocli, rtrim(nomcli), ville from clients; NOCLI RTRIM(NOMCLI) VILLE ---------- ------------------------------ ---------------------------- 15 DUPONT S.A. NANTES 20 Etb LABICHE NANTES 35 DUBOIS Jean NANTES SQL> savepoint s2; Savepoint créé. SQL> insert into clients (nocli, nomcli, ville) 2 values (111,’DURAND’,’RENNES’); 1 ligne créée. SQL> select nocli, rtrim(nomcli), ville from clients; NOCLI RTRIM(NOMCLI) VILLE ---------- ------------------------------ ---------------------------- 15 DUPONT S.A. NANTES 20 Etb LABICHE NANTES 35 DUBOIS Jean NANTES 111 DURAND RENNES SQL> rollback to s2; Annulation (rollback) effectuée. SQL> select nocli, rtrim(nomcli), ville from clients; NOCLI RTRIM(NOMCLI) VILLE ---------- ------------------------------ ----------------------------- 15 DUPONT S.A. NANTES 20 Etb LABICHE NANTES 35 DUBOIS Jean NANTES SQL> rollback to s1; Annulation (rollback) effectuée. SQL> select nocli, rtrim(nomcli), ville from clients; NOCLI RTRIM(NOMCLI) VILLE ---------- ------------------------------ ------------------------------ 15 DUPONT S.A. NANTES

- 16 - © ENI Editions - All rigths reserved

Page 52: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

20 Etb LABICHE NANTES 35 DUBOIS Jean NANTES 36 Bernard S.A. PARIS 37 Ets LAROCHE 138 DUBOIS Jean TOURS 152 LAROCHE LE MANS 7 ligne(s) sélectionnée(s). SQL> commit; Validation effectuée. SQL>

d. Accès simultané aux données

Lors de l’accès aux mêmes données (tables) à partir de plusieurs transactions, Oracle garantit la cohérence des données dans la transaction par rapport à la lecture initiale. Tant qu’une transaction n’est pas validée par une instruction COMMIT, les modifications faites sur les données à l’intérieur de la transaction sont invisibles des autres utilisateurs.

Exemple

Deux sessions (session 1 et session 2) sont ouvertes sous le même nom d’utilisateur.

Session 1 : insertion d’une ligne dans la table COMMANDES. La ligne insérée est visible dans la transaction.

SQL>select NOCDE, NOCLI, DATECDE, ETATCDE from COMMANDES ; NOCDE NOCLI DATECDE ET ------------------------------------- 1301 15 20/11/98 EC 1210 15 12/11/98 SO 1250 35 14/11/98 EC 1230 35 14/11/98 EC SQL>insert into COMMANDES (NOCDE, NOCLI, DATECDE, ETATCDE) 2 values (2000, 35, SYSDATE, ’EC’) ; 1 ligne créée. SQL>select NOCDE, NOCLI, DATECDE, ETATCDE from COMMANDES ; NOCDE NOCLI DATECDE ET ------------------------------------ 1301 15 20/11/98 EC 1210 15 12/11/98 SO 1250 35 14/11/98 EC 1230 35 14/11/98 EC 2000 35 22/11/98 EC SQL>

Session 2 : Pas de COMMIT dans la session 1 après l’insertion. La ligne insérée n’est pas visible dans la session 2. Insertion d’une ligne dans la table COMMANDES.

SQL>select NOCDE, NOCLI, DATECDE, ETATCDE from COMMANDES ; NOCDE NOCLI DATECDE ET ------------------------------------- 1301 15 20/11/98 EC 1210 15 12/11/98 SO 1250 35 14/11/98 EC 1230 35 14/11/98 EC SQL>insert into COMMANDES (NOCDE, NOCLI, DATECDE, ETATCDE) 2 values (2001, 15, SYSDATE, ’EC’) ; 1 ligne créée.

- 17 -© ENI Editions - All rigths reserved

Page 53: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

SQL>select NOCDE, NOCLI, DATECDE, ETATCDE from COMMANDES ; NOCDE NOCLI DATECDE ET ------------------------------------- 1301 15 20/11/98 EC 1210 15 12/11/98 SO 1250 35 14/11/98 EC 1230 35 14/11/98 EC 2001 15 22/11/98 EC SQL>

Session 1 : COMMIT

SQL>select NOCDE, NOCLI, DATECDE, ETATCDE from COMMANDES ; NOCDE NOCLI DATECDE ET ------------------------------------- 1301 15 20/11/98 EC 1210 15 12/11/98 SO 1250 35 14/11/98 EC 1230 35<+> 14/11/98 EC 2000 35 22/11/98 EC SQL>commit ; Validation effectuée. SQL>select NOCDE, NOCLI, DATECDE, ETATCDE from COMMANDES ; NOCDE NOCLI DATECDE ET ------------------------------------- 1301 15 20/11/98 EC 1210 15 12/11/98 SO 1250 35 14/11/98 EC 1230 35 14/11/98 EC 2000 35 22/11/98 EC SQL>

Session 2 : La ligne insérée à l’étape 1 dans la transaction est maintenant visible dans la session 2.

SQL>select NOCDE, NOCLI, DATECDE, ETATCDE from COMMANDES ; NOCDE NOCLI DATECDE ET ------------------------------------- 1301 15 20/11/98 EC 1210 15 12/11/98 SO 1250 35 14/11/98 EC 1230 35 14/11/98 EC 2000 35 22/11/98 EC 2001 15 22/11/98 EC 6 ligne(s) sélectionnée(s). SQL>commit ; Validation effectuée. SQL>select NOCDE, NOCLI, DATECDE, ETATCDE from COMMANDES ; NOCDE NOCLI DATECDE ET -------------------------------------- 1301 15 20/11/98 EC 1210 15 12/11/98 SO 1250 35 14/11/98 EC 1230 35 14/11/98 EC 2000 35 22/11/98 EC 2001 15 22/11/98 EC 6 ligne(s) sélectionnée(s). SQL>

- 18 - © ENI Editions - All rigths reserved

Page 54: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

e. Vérification des contraintes en fin de transaction

Dans certains cas, il peut être nécessaire de vérifier les contraintes d’intégrité en fin de transaction. Pour pouvoir profiter de cette fonctionnalité, il est nécessaire de préciser, lors de la mise en place de la contrainte d’intégrité, que sa vérification est différée en fin de transaction (INITIALLY DEFERRED), ou bien si, au contraire, il est possible de demander dans certains cas la validation de la contrainte en fin de transaction (DEFERRABLE). Par défaut, les contraintes d’intégrité sont vérifiées dès la mise en place des valeurs dans les tables et il n’est pas possible de déplacer cette vérification en fin de transaction.

La syntaxe exacte de mise en place de ces états de contrainte est expliquée dans le titre Création d’une table ­ Complément sur les contraintes.

Ainsi, dans l’exemple présenté ci­après, il est nécessaire de posséder un abonnement pour pouvoir être membre et chaque abonnement doit être possédé par un et un seul membre.

La mise en place de cette liaison 1­1 entre les 2 tables va s’effectuer en mettant en place une contrainte de référence entre les 2 tables. Chaque occurrence d’abonnement référence une et une seule occurrence de membre et chaque occurrence de membre fait référence à une et une seule occurrence d’abonnement.

Pour cet exemple, il est nécessaire d’ajouter, au cours de la même transaction, un membre et son abonnement puis de demander la vérification des contraintes de référence lors de la validation de la transaction.

Création des tables avec les contraintes de clé primaire

Mise en place des contraintes de clé étrangère

Insertion de données

- 19 -© ENI Editions - All rigths reserved

Page 55: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

- 20 - © ENI Editions - All rigths reserved

Page 56: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Traduction de l’algèbre relationnelle

La méthode de l’algèbre relationnelle permet de résoudre des extractions de données en créant des tables intermédiaires par l’utilisation d’opérateurs (UNION, RESTRICTION, JOINTURE, etc.). Cette méthode peut être traduite en SQL grâce à l’instruction SELECT qui permet toutes les opérations par ses différentes clauses (WHERE, GROUP BY, UNION, etc.), et par les instructions CREATE et INSERT qui permettent la gestion des tables intermédiaires.

1. Opérations

a. Restriction

La restriction permet de n’obtenir que les lignes répondant à une condition.

L’opération σ s (cond) se traduit par :

SELECT * FROM S WHERE cond ;

Exemple

Restriction sur le numéro de commande dans la table CDE = σ COMMANDES (NOCDE = 100) :

SQL> select * from COMMANDES where NOCDE = 100 ; NOCDE NOCLI DATECDE ET -------------------------------------- 100 15 18/11/98 EC SQL>

b. Calculs élémentaires

Le calcul élémentaire permet d’obtenir des colonnes calculées pour chaque ligne. L’opération π S (col, ..., nvcol = exp) se traduit par :

SELECT col, ..., expression FROM S ;

Exemple

Calcul de la valeur de stock π ARTICLES(REFART, DESIGNATION, VALSTK = (PRIXHT * QTESTK)) :

SQL> select REFART, DESIGNATION, (PRIX * QTESTK) from ARTICLES ; REFA DESIGNATION (PRIX*QTESTK) ---- --------------------------- --------------------- AB22 Tapis Persan 6250,5 CD50 Chaine HiFi 5147,8 ZZZZ Article bidon AA00 CAdeau 0 AB03 Carpette 17400 AB Tapis ZZ01 Lot de tapis 0 AB10 Tapis de Chine 15000 8 ligne(s) sélectionnée(s). SQL>

c. Projection

La projection a pour but d’éliminer les colonnes inutiles. Elle se fait en SQL en ne citant que les colonnes voulues dans le SELECT.

- 1 -© ENI Editions - All rigths reserved

Page 57: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Exemple

Simplification de la table CLI = π CLIENTS (NOCLI, NOMCLI) :

SQL> SELECT NOCLI, NOMCLI from CLIENTS;

Les projections de regroupement peuvent s’effectuer à l’aide de deux syntaxes :

SELECT DISTINCT * | liste de colonnes FROM table ;

ou

SELECT liste de colonnes FROM table GROUP BY liste de colonnes ;

La première syntaxe (DISTINCT) permet de n’afficher qu’une occurence de ligne dans le cas où la requête ramène plusieurs lignes identiques. La deuxième syntaxe (GROUP BY) est utilisée lorsque l’on souhaite réaliser une projection de groupe avec le calcul d’agrégats sur les lignes regroupées.

Le mot clé DISTINCT permet uniquement d’effectuer l’affichage de valeurs distinctes, tandis que le mot clé GROUP BY effectue en premier lieu un regroupement. Cette opération de regroupement rend possible les calculs d’agrégats mais demande bien sûr un peu plus de temps au niveau du processeur du serveur.

Exemples

Affichage d’une ligne par nom client :

SQL> select NOMCLI from CLIENTS ; NOMCLI ------------------------------ DUPONT S.A. Etb LABICHE DUBOIS Jean BERNARD S.A. DUBOIS Jean LAROCHE 6 ligne(s) sélectionnée(s). SQL> select distinct NOMCLI from CLIENTS ; NOMCLI ------------------------------ BERNARD S.A. DUBOIS Jean DUPONT S.A. Etb LABICHE LAROCHE SQL> select NOMCLI from CLIENTS group by NOMCLI; NOMCLI . ------------------------------ BERNARD S.A. DUBOIS Jean DUPONT S.A. Etb LABICHE LAROCHE SQL>

Regroupement par NOM et VILLE.

SQL> select NOMCLI, VILLE from CLIENTS group by NOMCLI, VILLE; NOMCLI VILLE ----------------------------------------- BERNARD S.A. PARIS DUBOIS Jean NANTES DUBOIS Jean TOURS DUPONT S.A. NANTES

- 2 - © ENI Editions - All rigths reserved

Page 58: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Etb LABICHE NANTES LAROCHE LE MANS 6 ligne(s) sélectionnée(s). SQL>

d. Calculs d’agrégats

Les projections de calcul d’agrégats permettent des calculs statistiques sur des regroupements introduits par GROUP BY.

L’opération π S (col, ..., nvcol = calcul statistique) se traduit par :

SELECT liste de colonnes, fonction groupe FROM S GROUP BY liste colonnes ;

La liste de colonnes projetées (derrière le SELECT) doit être identique à la liste de colonnes de regroupement (derrière le GROUP BY).

Les noms des colonnes peuvent apparaître dans des calculs élémentaires ; dans ce cas le regroupement doit porter sur les mêmes expressions.

e. Fonctions de GROUPE

coln

colonne numérique.

colonne

colonne de tout type.

AVG (coln)

moyenne des valeurs de colonne.

COUNT (coln)

pour chaque regroupement, nombre de lignes regroupées où colonne est non NULL.

COUNT (*)

pour chaque regroupement, nombre de lignes regroupées.

MAX (coln)

valeur maximum de la colonne pour chaque regroupement.

MIN (coln)

valeur minimum de la colonne pour chaque regroupement.

STDDEV (coln)

écart type des valeurs de colonne pour chaque regroupement.

SUM (coln)

somme des valeurs de colonne pour chaque regroupement.

VARIANCE (coln)

variance des valeurs de colonne pour chaque regroupement.

- 3 -© ENI Editions - All rigths reserved

Page 59: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

CORR (col1, col2)

coefficient de corrélation entre les 2 colonnes.

COVAR_POP (col1, col2)

covariance d’une population.

COVAR_SAMP (col1, col2)

covariance d’un échantillon.

CUME_DIST (col, pourcentage)

distribution cumulative.

DENSE_RANK (col)

numéro d’ordre d’une ligne dans un ensemble ordonné de lignes.

FIRST(col) LAST (col)

retourne la première (dernière) ligne ordonnée par rapport à un critère tri (DENSE_RANK par exemple).

GROUP_ID

distingue les groupes dupliqués apparus suite à l’application de la clause GROUP BY.

GROUPING (expr)

permet d’identifier lorsque les colonnes contiennent la valeur null suite à l’application d’une commande ROLLUP ou CUBE.

GROUPING_ID (expr)

comme pour la fonction GROUPING, permet d’identifier si la ligne est ou non le résultat d’une commande ROLLUP ou CUBE.

PERCENTILE_CONT (expr)

distribution inverse continue.

PERCENTILE_DISC (expr)

distribution inverse discrète.

PERCENT_RANK (expr)

similaire à CUME_DIST.

RANK (expr)

calcul le rang d’une valeur dans un groupe de valeurs.

REGR_ (expr)

calcul de la régression linéaire.

STDDEV_POP (expr)

écart type d’une population.

STDDEV_SAMP (expr)

- 4 - © ENI Editions - All rigths reserved

Page 60: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

écart type d’un échantillon.

VAR_POP (expr)

variance d’une population.

VAR_SAMP (expr)

variance d’un échantillon.

Dans le cas où le calcul d’agrégats porte sur une colonne particulière, les valeurs NULL de cette colonne ne sont pas prises en compte pour les calculs.

Oracle dispose de quelques autres fonctions de calculs d’agrégats qui sont spécialisées dans le calcul statistique.

Exemples

Nombre de clients par ville. L’attribut ville ayant été défini de type CHAR(30), il faut éliminer les éventuels espaces à droite pour que le regroupement se fasse bien sur les caractères significatifs de la valeur de la colonne.

SQL> select rtrim(VILLE), count(*) from CLIENTS group by rtrim(VILLE); RTRIM(VILLE) COUNT(*) -------------------------------------------- LE MANS 1 NANTES 3 PARIS 1 TOURS 1 SQL>

Prix le plus élevé et moyenne des quantités en stock par famille d’articles (deux premiers caractères de la référence) :

SQL> select * from articles; REFA DESIGNATION PRIX CODETVA CATEGORIE QTESTK --- ---------------------------- -------- ------- ---------- ---------- AB22 Taps Persan 1375,11 2 IMPORT 5 CD50 Chaine HiFi 2 IMPORT 7 CD21 Platine laser 500 2 IMPORT 20 ZZZZ Article bidon DIVERS 25 AA00 Cadeau 0 DIVERS 8 AB03 Carpette 165 2 SOLDES 116 AB Tapis 2 DIVERS 2 ZZ01 Lot de tapis 500 2 DIVERS 0 AB10 Tapis de chine 1650 2 IMPORT 10 9 ligne(s) sélectionnée(s). SQL> select substr(refart,1,2), max(prix), avg(qtestk) 2 from articles 3 group by substr(refart,1,2); SU MAX(PRIX) AVG(QTESTK) -- ---------- ----------- AA 8 AB 1650 33,25 CD 500 13,5 ZZ 500 12,5 SQL>

- 5 -© ENI Editions - All rigths reserved

Page 61: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

f. Fonctions analytiques

Les fonctions analytiques permettent d’extraire des résultats à partir d’un regroupement de lignes effectué à l’aide de l’instruction GROUP BY. Ces fonctions se différencient des fonctions d’agrégat car au lieu de retourner une seule valeur pour chaque groupe de valeurs, elles retournent plusieurs lignes de résultats pour chaque groupe. Ces lignes de résultat sont appelées fenêtres (windows). Pour chaque ligne analysée une fenêtre glissante est définie. La taille de la fenêtre détermine le nombre de lignes à prendre en compte pour le calcul de la ligne actuelle.

AVG

Moyenne.

CORR

Coefficient de corrélation.

COVAR_POP

Covariance d’une population.

COVAR_SAMP

Covariance d’un échantillon.

COUNT

Comptage.

CUME_DIST

Distribution cumulative.

DENSE_RANK

Calcul le rang d’une ligne dans un groupe ordonné de lignes.

FIRST

Permet d’obtenir la première ligne depuis un jeu de résultats trié.

LAST

Permet d’obtenir la dernière ligne depuis un jeu de résultats trié.

FIRST_VALUE

Première valeur d’un ensemble de résultats triés.

LAST_VALUE

Dernière valeur d’un ensemble de résultats triés.

LAG

Permet d’accéder à plus d’une ligne de façon simultanée.

LEAD

Fonction similaire à LAG.

MAX

Plus grand élément.

- 6 - © ENI Editions - All rigths reserved

Page 62: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

MIN

Plus petit élément.

NTILE

Permet de diviser une ligne de résultat en petits groupes parfaitement identifiés par leur numéro d’ordre.

PERCENT_RANK

Distribution cumulative.

PERCENTILE_CONT

Distribution inverse continue.

PERCENTILE_DISC

Distribution inverse discrète.

RANK

Rang d’une valeur au sein d’un groupe.

RATIO_TO_REPORT

Calcul le rapport entre une valeur et la somme d’un ensemble de valeurs.

REGR

Régression linéaire.

ROW_NUMBER

Permet de générer un numéro unique pour chaque ligne.

STDDEV

Ecart type.

STDDEV_POP

Ecart type sur une population.

STDDEV_SAMP

Ecart type sur un échantillon.

SUM

Somme.

VAR_POP

Variance d’une population.

VAR_SAMP

Variance d’un échantillon.

VARIANCE

Variance.

- 7 -© ENI Editions - All rigths reserved

Page 63: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Dans l’exemple ci­après, la requête permet de lister tous les articles dont la référence commence par AB et d’afficher en face de chacun d’eux la référence de l’article le moins cher.

SQL> select refart, prix, 2 FIRST_VALUE(refart) 3 OVER(order by prix asc rows unbounded preceding) as moins_cher 4 from articles 5 where upper(substr(refart,1,2))=’AB’; REFA PRIX MOIN ---- ---------- ---- AB03 150 AB03 AB22 1250,1 AB03 AB10 1500 AB03 AB AB03 SQL>

g. Restrictions sur agrégat

Lorsque l’on souhaite restreindre le nombre de lignes renvoyées par une requête comportant un calcul d’agrégats, il est possible d’utiliser la clause HAVING. La syntaxe est alors :

SELECT liste de colonnes, fonctions groupe FROM S GROUP BY liste de colonnes HAVING condition ;

La condition peut alors contenir une fonction statistique. Les expressions utilisées dans la clause HAVING peuvent faire référence à des critères de regroupement ou des calculs d’agrégats.

Exemple

Affichage des informations statistiques des familles d’articles dont le prix minimum est supérieur à 300 euros.

SQL> select substr(REFART, 1, 2), max(PRIX), min(PRIX) 2 from ARTICLES group by substr(REFART, 1, 2) 3 having min(PRIX) 300; SU MAX(PRIX) MIN(PRIX) -- --------- --------- CD 735,4 735,4 ZZ 500 500 SQL>

h. Produit cartésien

Le produit cartésien permet d’obtenir l’association de chaque ligne d’une table avec chaque ligne d’autres tables.

L’opération S X T se traduit par :

SELECT liste de colonnes FROM S, T ;

Si des colonnes portent le même nom dans les deux tables, on préfixe le nom de la colonne par le nom de la table.

Le nom complet de la colonne est alors : nomtable.nomcolonne.

Exemple

Création et valorisation d’une table DEPOTS. Simulation de l’affectation de chaque article à chaque dépôt :

SQL>create table DEPOTS (CODE char(2) primary key, ADRESSE varchar2(60)); Table créée. SQL>insert into DEPOTS values (’NA’, ’24 rue Crébillon 44000 NANTES’); 1 ligne créée. SQL>insert into DEPOTS values (’PA’, ’PARIS’); 1 ligne créée. SQL>insert into DEPOTS values (’BO’ , ’BORDEAUX’);

- 8 - © ENI Editions - All rigths reserved

Page 64: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

1 ligne créée. SQL>commit; Validation effectuée. SQL>select CODE,REFART from DEPOTS,ARTICLES; CO REFART ---------------- NA AB03 PA AB03 BO AB03 NA AB10 PA AB10 BO AB10 NA AB22 PA AB22 BO AB22 NA CD50 PA CD50 BO CD50 NA ZZZZ PA ZZZZ BO ZZZZ NA AA00 PA AA00 BO AA00 NA AB PA AB BO AB NA ZZ01 PA ZZ01 BO ZZ01 24 ligne(s) sélectionnée(s).

i. Jointures

La jointure est une restriction sur le produit cartésien afin de lier chaque ligne d’une table avec des lignes d’une autre table en respectant une condition.

L’opération S JOIN (cond) T se traduit par :

SELECT liste de colonnes FROM S, T WHERE cond ;

Exemple

Jointure naturelle entre COMMANDES et CLIENTS :

SQL> select NOCDE, COMMANDES.NOCLI, NOMCLI 2 from CLIENTS, COMMANDES 3 WHERE CLIENTS.NOCLI = COMMANDES.NOCLI ; NOCDE NOCLI NOMCLI --------- --------- ------------------------------ 1301 15 DUPONT S.A. 1210 15 DUPONT S.A. 1250 35 DUBOIS Jean 1230 35 DUBOIS Jean SQL>

Depuis la version 9i, Oracle supporte les jointures exprimées dans une syntaxe compatible avec la norme ANSI. Bien que cette façon d’écrire soit normalisée, elle est souvent moins utilisée que la syntaxe présentée précédemment car les informations sont moins lisibles. Néanmoins les générateurs de requêtes utilisent cette syntaxe normalisée.

SELECT liste de colonnes FROM table [NATURAL] INNER JOIN table ON condition_jointure|USING (colonne) WHERE conditions;

- 9 -© ENI Editions - All rigths reserved

Page 65: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

SQL> select nocde, commandes.nocli, nomcli 2 from clients inner join commandes on 3 clients.nocli=commandes.nocli; NOCDE NOCLI NOMCLI ---------- ---------- ------------------------------ 100 15 DUPONT S.A. 1301 15 DUPONT S.A. 1210 15 DUPONT S.A. 1250 35 DUBOIS Jean 1230 35 DUBOIS Jean SQL>

L’avantage de la syntaxe normalisée est par contre très net lors de la mise en place des jointures naturelles entre les tables, car il n’est alors plus nécessaire de citer la condition de jointure.

SQL> select nocde, nocli, nomcli 2 from clients natural inner join commandes; NOCDE NOCLI NOMCLI ---------- ---------- ------------------------------ 100 15 DUPONT S.A. 1301 15 DUPONT S.A. 1210 15 DUPONT S.A. 1250 35 DUBOIS Jean 1230 35 DUBOIS Jean SQL>

j. Jointures externes

La jointure externe (outer join) est une extension de la jointure, qui permet d’obtenir en plus des lignes répondant à la condition, les lignes de l’une des tables qui n’y répondent pas. Il suffit d’ajouter l’opérateur (+) dans la condition, derrière la colonne de la table dont les lignes ne peuvent apparaître dans le résultat.

Exemple

Liste des clients avec éventuellement leurs commandes.

SQL> select NOCDE, COMMANDES.NOCLI, NOMCLI 2 from CLIENTS, COMMANDES 3 WHERE CLIENTS.NOCLI = COMMANDES.NOCLI (+) ; NOCDE NOCLI NOMCLI --------- --------- ------------------------------ 1301 15 DUPONT S.A. 1210 15 DUPONT S.A. Etb LABICHE 1250 35 DUBOIS Jean 1230 35 DUBOIS Jean BERNARD S.A. DUBOIS Jean LAROCHE 8 ligne(s) sélectionnée(s). SQL>

k. Union, intersection, différence

Ces opérateurs permettent d’obtenir dans une requête des lignes provenant de requêtes distinctes mais de même forme (même nombre de colonnes, même type dans le même ordre).

Les opérations S ∪/∩/­ T se traduisent par :

SELECT liste colonnes FROM S UNION/UNION ALL /INTERSECT/MINUS SELECT liste colonnes FROM T ;

- 10 - © ENI Editions - All rigths reserved

Page 66: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

L’opérateur UNION ALL permet de retrouver toutes les lignes issues des requêtes sans élimination des doublons.

Il est possible de faire l’union, l’intersection ou la différence entre des données issues de plusieurs requêtes SELECT, mais toutes les requêtes doivent posséder la même liste de colonnes (type et longueur) et ces

colonnes doivent toujours être définies dans le même ordre.

Exemple

Regroupements des lignes de CLIENTS et CLIDIVERS :

SQL> select NOCLI, NOMCLI from CLIENTS 2 UNION 3 select NOCLI, NOMCLI from CLIDIVERS ; NOCLI NOMCLI --------- ------------------------------ 15 DUPONT S.A. 20 Etb LABICHE 35 DUBOIS Jean 36 BERNARD S.A. 123 DUPOND and Co 138 DUBOIS Jean 152 LAROCHE 556 DUBOIS Jean 567 OEYSTER Ltd 9 ligne(s) sélectionnée(s). SQL> select NOMCLI from CLIENTS 2 UNION 3 select NOMCLI from CLIDIVERS ; NOMCLI ------------------------------ BERNARD S.A. DUBOIS Jean DUPOND and Co DUPONT S.A. Etb LABICHE LAROCHE OEYSTER Ltd 7 ligne(s) sélectionnée(s). SQL>

2. Traitement du résultat

Le résultat des requêtes précédentes peut servir à plusieurs usages :

affichage trié ou non,

valorisation d’une table intermédiaire,

création d’un fichier externe à la base.

a. Le tri

Pour obtenir un résultat trié, on utilise la clause ORDER BY en fin de commande SELECT.

Par défaut, le tri est croissant et l’ordre est déterminé par les paramètres nationaux de l’environnement de l’utilisateur (paramètre NLS_SORT). Le tri décroissant est obtenu à l’aide de l’option DESC de la clause ORDER BY. Il est possible pour l’utilisateur, s’il en possède le privilège, de modifier le paramètre NLS_SORT en cours de session.

- 11 -© ENI Editions - All rigths reserved

Page 67: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

L’ordre de tri peut également être spécifié en indiquant dans la clause ORDER BY le numéro d’ordre correspondant dans la clause SELECT à la colonne servant au tri.

Syntaxe

SELECT ..... ORDER BY exp [Desc][, ...] ;

Exemple

Affichage des articles triés par famille et prix décroissant.

SQL> select REFART, PRIX from ARTICLES 2 ORDER BY substr(REFART, 1, 2), PRIX desc ; REFA PRIX ---- --------------- 0 0 AB AB10 1500 AB22 1250,1 AB03 150 CD50 735,4 ZZZZ ZZ01 500 8 ligne(s) sélectionnée(s). SQL> select PRIX, substr(REFART, 1, 2) from ARTICLES 2 ORDER BY 2, 1 desc ; PRIX SU --------- -- 0 AA AB 1500 AB 1250,1 AB 150 AB 735,4 CD ZZ 500 ZZ 8 ligne(s) sélectionnée(s). SQL>

b. La sauvegarde

Il est possible de sauvegarder le résultat d’une requête dans une table, afin de pouvoir l’utiliser dans une autre requête.

Deux méthodes sont utilisables :

créer la table puis y insérer des lignes résultant de la requête,

créer la table à partir de la requête.

Syntaxes

CREATE TABLE nom (colonne type [DEFAULT expr] [contrainte], ...) ;

INSERT INTO nom [(colonne, colonne,...)] SELECT ...;

Par SQL

Première méthode

- 12 - © ENI Editions - All rigths reserved

Page 68: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Cette méthode permet de choisir les types de colonnes, les valeurs par défaut, et de mettre en place des contrôles en utilisant les contraintes.

Exemple

Création d’une table simplifiée à partir de la table CLIENTS :

SQL> create table CLI (NOCLI char(4), NOMCLI char(10)); Table créée. SQL> SQL> insert into CLI 2 select to_char(NOCLI, ’009’), substr(NOMCLI, 1, 10) 3 from CLIENTS where VILLE like ’PARIS%’; 1 ligne créée. SQL> select * from CLI; NOCL NOMCLI ---- ---------- 036 BERNARD S. SQL> drop table CLI ; Table supprimée. SQL>

Syntaxe

CREATE TABLE nom [(colonne, colonne, ....)] AS SELECT ...;

Par cette méthode plus rapide, les noms et les types des colonnes de la nouvelle table sont dérivés de ceux des colonnes projetées dans le SELECT.

Exemple

Sauvegarde de la restriction "Clients de Loire­Atlantique" dans une table CLI44 :

SQL> create table CLI44 as 2 select NOCLI, NOMCLI from CLIENTS 3 where CODE_POSTAL between 44000 and 44999 ; Table créée. SQL> select * from CLI44; NOCLI NOMCLI --------- ------------------------------ 15 DUPONT S.A. 20 Etb LABICHE 35 DUBOIS Jean SQL> desc CLI44 Name Null? Type ------------------------- -------- -------------- NOCLI NUMBER(4) NOMCLI NOT NULL VARCHAR2(30) SQL> drop table CLI44 ; Table supprimée. SQL>

Sauvegarde du résultat de la requête dans un fichier ASCII.

Deuxième méthode

Par SQLPLUS

- 13 -© ENI Editions - All rigths reserved

Page 69: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Syntaxe

SPOOL nom_fichier

Exemple

Création d’un fichier séquentiel ASCII fic.lst contenant les données de la table CLIENTS.

SQL>SET HEADING OFF SQL>SPOOL fic SQL>select * from CLIENTS; SQL>SPOOL OFF

En plus des tables permanentes, Oracle offre la possibilité de créer des tables temporaires pour stocker des informations le temps d’une session ou d’une transaction. Les données stockées dans une table temporaire créée avec l’ordre CREATE GLOBAL TEMPORARY TABLE, sont accessibles uniquement depuis la session qui a créé les données. En fait chaque session ne voit que ses propres données et une instruction TRUNCATE TABLE sur une table temporaire permet simplement de supprimer toutes les données issues de la session qui lance l’ordre TRUNCATE.

La spécificité de cette table temporaire réside dans le fait que les données insérées dans cette table ne restent présentes que le temps de la transaction. La table, quant à elle, reste bien sûr en place et il est possible de l’utiliser dans les autres transactions. Si l’on souhaite que les données insérées dans cette table soit stockées de façon plus persistante, il faut utiliser la clause ON COMMIT PRESERVE ROWS lors de la création de la table temporaire globale. Ainsi, les informations insérées dans cette table seront visibles à travers toutes les transactions pendant la durée de la session de l’utilisateur Oracle qui a inséré les informations dans la table.

Syntaxe

CREATE GLOBAL TEMPORARY TABLE table (nom_colonne type,...)[ON COMMIT PRESERVE ROWS];

Exemple

Création d’une table temporaire globale destinée à recevoir les numéro et nom de certains clients.

Des données sont ajoutées à la table temporaire. Ces données sont le résultat d’une commande de type SELECT, qui permet de connaître le numéro et le nom des clients de chaque commande.

Depuis la même session, on interroge la table temporaire pour connaître son contenu :

Les tables temporaires

- 14 - © ENI Editions - All rigths reserved

Page 70: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Depuis une autre session, on interroge la même table temporaire pour connaître son contenu :

La création de la même table avec l’option ON COMMIT PRESERVE ROWS :

c. Énumérer toutes les possibilités d’un calcul d’agrégats

Un calcul d’agrégats porte toujours sur le regroupement indiqué par la clause GROUP BY. Il est parfois nécessaire d’effectuer un regroupement plus large afin de connaître d’autres valeurs. Par exemple, on souhaite connaître le montant de chaque commande et le montant de toutes les commandes passées par un client. Pour mener à bien ces calculs en une seule étape, il faut utiliser les mots clés ROLLUP et CUBE.

ROLLUP

permet de faire des regroupements de plus en plus généraux.

CUBE

permet de réaliser le calcul demandé sur tous les regroupements possibles.

Syntaxe

SELECT liste_colonne, calcul_agregat FROM table GROUP BY ROLLUP|CUBE (liste_colonne)

Le fonctionnement de ces deux mots clés va être expliqué au travers des exemples suivants.

- 15 -© ENI Editions - All rigths reserved

Page 71: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Exemple

Dans l’exemple ci­dessous, ROLLUP permet de calculer le total pour chaque client ainsi que le montant total des commandes tous clients confondus :

En utilisant l’expression DECODE, il est possible d’obtenir une présentation plus soignée.

L’instruction CUBE permet quant à elle d’explorer toutes les combinaisons possibles.

3. MERGE

Cette instruction permet de fusionner, en une seule requête, une opération de mise à jour (INSERT, UPDATE, DELETE) sur une table.

- 16 - © ENI Editions - All rigths reserved

Page 72: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Les informations, qui servent de base à l’exécution de l’ordre DML, peuvent provenir d’une ou de plusieurs tables.

Toutefois, la même ligne d’informations ne peut pas participer en tant que source et destination de l’instruction MERGE.

Cette fonction s’avère très intéressante lorsque l’on souhaite mettre à jour les données d’une table de façon conditionnelle. Par exemple dans la table des employés, on souhaite mettre à jour le salaire (+4%) des employés de plus de 40 ans et supprimer ceux de plus de 65 ans (retraite).

Le contenu de la table employé est le suivant :

Comme une ligne ne peut pas être à la fois source et destination de la commande MERGE, la première étape va consister à créer une table temporaire qui va contenir les numéros d’employés et leur âge.

Enfin les données de la table des employés sont mises à jour.

Le nouveau contenu de la table des employés est alors :

- 17 -© ENI Editions - All rigths reserved

Page 73: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

L’utilisation de cette instruction permet d’éviter l’exécution de nombreuses requêtes telles que INSERT, UPDATE ou bien DELETE.

Il n’est pas possible de mettre plusieurs fois à jour une ligne au cours d’une seule instruction MERGE.

Syntaxe

MERGE hint INTO nomTable USING nomTable ON ( condition ) [WHEN MATCHED THEN UPDATE SET nomColonne=valeur [WHERE condition] [DELETE WHERE condition] ] [WHEN NOT MATCHED THEN INSERT (nomColonne, ...) values (valeur, ...) [WHERE condition]];

INTO

permet de spécifier la table cible de l’instruction MERGE et donc des opérations INSERT, UPDATE et DELETE.

USING

permet de spécifier comment les données qui participent à cette instruction sont sélectionnées ; il s’agit d’une requête de type SELECT.

ON

permet de faire une jointure entre les informations déjà présentes dans la table cible et celles issues de la requête de sélection des informations. En fonction de cette jointure, l’action sera soit une mise à jour (WHEN MATCHED) ou bien une insertion (WHEN NOT MATCHED).

WHEN MATCHED

permet de définir l’action de mise à jour à effectuer ou bien éventuellement de suppression.

WHEN NOT MATCHED

permet de définir une insertion à réaliser sur la table cible.

- 18 - © ENI Editions - All rigths reserved

Page 74: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

SQL avancé

Le SQL permet l’utilisation d’autres objets que les tables et les index, afin de gérer les données ou de manipuler des requêtes.

La puissance de l’instruction SELECT permet d’autre part, de combiner les différentes clauses en une seule commande, et également d’imbriquer les requêtes.

Enfin, le SQL permet dans un environnement multi­utilisateur, de verrouiller les tables afin de préserver l’intégrité des données.

1. Les objets

a. Les objets View (vue)

Les vues sont des tables virtuelles "contenant" le résultat d’un SELECT.

L’un des intérêts de l’utilisation des vues vient du fait que la vue ne stocke pas les données, mais fait référence à une ou plusieurs tables d’origine à travers une requête SELECT, requête qui est exécutée chaque fois que la vue est référencée. De ce fait, toute modification de données dans les tables d’origine est immédiatement visible dans la vue dès que celle­ci est à nouveau exécutée.

Les cas d’utilisation des vues sont multiples :

Cacher aux utilisateurs certaines colonnes ou certaines lignes en mettant à leur disposition des vues de projection ou de restriction. Ceci permet de fournir un niveau de sécurité supplémentaire.

Simplifier l’utilisation de tables comportant beaucoup de colonnes, beaucoup de lignes, ou des noms complexes, en créant des vues avec des structures plus simples et des noms plus explicites.

"Sauvegarder" des requêtes fréquemment utilisées sous un nom.

Simplifier la saisie des instructions SQL pour les utilisateurs en masquant les jointures fréquemment utilisées.

Les vues, une fois créées, sont utilisables comme des tables dans les instructions DML, INSERT, SELECT, UPDATE, DELETE. Toutefois les mises à jour ne sont pas possibles si la vue comporte :

des instructions ensemblistes (UNION, INTERSECT, MINUS),

des fonctions de groupe,

des clauses GROUP BY, CONNECT BY, START WITH.

Une vue définie par une jointure supporte les instructions INSERT, UPDATE, DELETE si elle référence dans sa définition une table dont la (les) colonne(s) clé primaire apparaît (apparaissent) dans la liste des colonnes projetées de la jointure et si les instructions INSERT, UPDATE, DELETE portent sur cette table.

Syntaxe

CREATE [OR REPLACE] [FORCE | NO FORCE] VIEW nom [(colonnes, .....)] AS SELECT ..... [WITH CHECK OPTION | WITH READ ONLY];

OR REPLACE

permet le remplacement de la description par la nouvelle requête si la vue existe déjà. En effet, la définition d’une vue ne peut être modifiée partiellement.

FORCE | NO FORCE

Création

- 1 -© ENI Editions - All rigths reserved

Page 75: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

permet de forcer/d’empêcher la création de la vue si un des éléments sous­jacents (table ou vue) n’est pas défini.

READ ONLY

interdit toute insertion, modification, suppression de données à travers la vue.

WITH CHECK OPTION

vérifie, lors de l’insertion ou de la modification de lignes dans la vue, que les lignes insérées ou modifiées sont visualisables dans cette vue.

Syntaxe

ALTER VIEW nom COMPILE ;

La compilation de la vue permet de valider la requête qui lui est associée et de détecter au plus tôt d’éventuelles références incorrectes dans celle­ci. Ceci est en particulier utile après modification de la structure d’une des tables sous­jacentes de la vue. Si la compilation de la vue provoque une erreur, tous les autres objets de la base dépendant de cette vue deviennent invalides.

Exemple

Vue retournant les clients du département 44. L’option WITH CHECK OPTION empêche toute insertion de client n’appartenant pas à ce département.

SQL> create or replace view V_CLI44 as 2 select NOCLI, NOMCLI, CODE_POSTAL, VILLE from CLIENTS 3 where CODE_POSTAL between 44000 and 44999 4 with check option; Vue créée. SQL> select NOCLI, substr(NOMCLI,1,12), CODE_POSTAL, 2 substr(VILLE,1,12) from V_CLI44; NOCLI SUBSTR(NOMCL CODE_POSTAL SUBSTR(VILLE ----- ------------ ----------- ------------- 15 DUPONT S.A. 44000 NANTES 20 Etb LABICHE 44100 NANTES 35 DUBOIS Jean 44300 NANTES SQL> insert into V_CLI44 values (255, ’ALAMBERT S.A.’, 22000, ’ST BRIEUC’) ; insert into V_CLI44 values (255, ’ALAMBERT S.A.’, 22000, ’ST BRIEUC’) * ERREUR à la ligne 1: ORA-01402: vue WITH CHECK OPTION - violation de clause WHERE SQL> insert into V_CLI44 values (176, ’Ets GAZONAV’, 44500, ’ST NAZAIRE’) ; 1 ligne créée. SQL> select NOCLI, substr(NOMCLI,1,12), CODE_POSTAL, 2 substr(VILLE,1,12) from V_CLI44; NOCLI SUBSTR(NOMCL CODE_POSTAL SUBSTR(VILLE ------ ----------- ----------- ------------ 15 DUPONT S.A. 44000 NANTES 20 Etb LABICHE 44100 NANTES 35 DUBOIS Jean 44300 NANTES 176 Ets GAZONAV 44500 ST NAZAIRE SQL> select NOCLI, substr(NOMCLI,1,12), CODE_POSTAL, 2 substr(VILLE,1,12) from CLIENTS; NOCLI SUBSTR(NOMCL CODE_POSTAL SUBSTR(VILLE

Compilation

- 2 - © ENI Editions - All rigths reserved

Page 76: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

----- ------------ ----------- ------------ 15 DUPONT S.A. 44000 NANTES 20 Etb LABICHE 44100 NANTES 35 DUBOIS Jean 44300 NANTES 36 BERNARD S.A. PARIS 138 DUBOIS Jean TOURS 152 LAROCHE LE MANS 176 Ets GAZONAV 44500 ST NAZAIRE 7 ligne(s) sélectionnée(s). SQL>

La vue V_CLICMD sauvegarde la jointure CLIENTS/ COMMANDES. La vue V_CLICMD44 permet de faire une restriction sur les clients du département 44. La vue V_CLICMD est ensuite rendue invalide suite à la suppression d’une table référencée dans sa clause SELECT. La vue V_CLICMD44 est automatiquement invalidée.

SQL> create or replace view V_CLICMD (NOCLIENT, NOM, COMMANDE, 2 CP) as select CLIENTS.NOCLI, NOMCLI, NOCDE, 3 CODE_POSTAL from CLIENTS, COMMANDES 4 where CLIENTS.NOCLI = COMMANDES.NOCLI ; Vue créée. SQL> select * from V_CLICMD order by NOCLIENT ; NOCLIENT NOM COMMANDE CP ---------- ----------------------- ---------- --------- 15 DUPONT S.A. 1301 44000 15 DUPONT S.A. 1210 44000 35 DUBOIS Jean 1250 44300 35 DUBOIS Jean 1230 44300 SQL> create or replace view V_CLICMD44 as 2 select * from V_CLICMD 3 where CP between 44000 and 44999 ; Vue créée. SQL> select * from V_CLICMD44 order by NOCLIENT; NOCLIENT NOM COMMANDE CP --------- ----------------------- -------- ----------- 15 DUPONT S.A. 1301 44000 15 DUPONT S.A. 1210 44000 35 DUBOIS Jean 1250 44300 35 DUBOIS Jean 1230 44300 SQL> drop table COMMANDES cascade constraints ; Table supprimée. SQL> alter view V_CLICMD compile ; Attention: Vue modifiée avec erreurs de compilation. SQL> select * from V_CLICMD44 order by NOCLIENT ; select * from V_CLICMD44 order by NOCLIENT * ERREUR à la ligne 1: ORA-04063: view "GILLES.V_CLICMD44" a des erreurs SQL>

Insertion dans une vue basée sur une jointure.

SQL> create or replace view V_CMDCLI (NOCDE, DATECDE, NOCLIENT, 2 NOMCLI) as select NOCDE, DATECDE, COMMANDES.NOCLI, 3 NOMCLI from CLIENTS, COMMANDES 4 where CLIENTS.NOCLI = COMMANDES.NOCLI ;

- 3 -© ENI Editions - All rigths reserved

Page 77: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Vue créée. SQL> select * from V_CMDCLI order by NOCLIENT ; aucune ligne sélectionnée SQL> insert into V_CMDCLI (NOCDE, DATECDE, NOCLIENT) 2 values (1501, SYSDATE, 176 ); 1 ligne créée. SQL> select * from V_CMDCLI order by NOCLIENT ; NOCDE DATECDE NOCLIENT NOMCLI --------- -------- --------- -------------- 1501 20/11/98 176 Ets GAZONAV SQL>

Syntaxe

DROP VIEW nom ;

Les objets qui référencent la vue supprimée deviennent invalides.

Il est possible de définir une vue directement à l’intérieur d’une requête sans qu’il soit nécessaire de passer par une commande CREATE VIEW. Cette possibilité est intéressante car elle permet de définir simplement une vue dont l’utilisation est limitée.

Exemple

La vue définie en ligne permet de connaître le montant de chaque commande. Elle est référencée dans la requête par l’alias de table LCDE. La requête affiche les informations relatives à chaque client.

b. Les objets Schema

Un schéma est un ensemble de tables, vues et privilèges regroupés sous un même nom (celui de l’utilisateur).

L’utilisation explicite d’un schéma avec l’instruction CREATE SCHEMA AUTHORIZATION permet d’étendre la notion de transaction aux instructions DDL de création de table, de vue et d’affectation de privilège GRANT.

Si l’une des instructions DDL spécifiées dans le CREATE SCHEMA AUTHORIZATION échoue, l’ensemble des instructions est annulé.

Le nom de SCHEMA utilisé dans l’instruction est celui associé à l’utilisateur (USER) qui a ouvert la session en cours.

Syntaxe

Suppression

Les vues en ligne

- 4 - © ENI Editions - All rigths reserved

Page 78: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

CREATE SCHEMA AUTHORIZATION nom CREATE TABLE/VIEW..../GRANT... ...;

Exemple

Instruction CREATE SCHEMA AUTHORIZATION exécutée sans erreur. Toutes les instructions DDL spécifiées ont été exécutées.

SQL> drop view v_cdecli; Vue supprimée. SQL> drop table ligcdes; Table supprimée. SQL> drop table commandes; Table supprimée. SQL> drop table clients; Table supprimée. SQL> drop table articles; Table supprimée. SQL> create schema authorization LIVRE 2 create table clients( 3 nocli number(4) 4 constraint pk_clients primary key 5 constraint ck_clients_nocli check (nocli>0), 6 nomcli varchar2(30) 7 constraint nn_clients_nomcli not null, 8 adrcli varchar2(80), 9 code_postal number(5) 10 constraint ck_clients_codepostal check(code_postal between 1000 and 95999), 11 ville char(30) 12 ) 13 create table articles( 14 refart char(4) primary key, 15 designation varchar2(30), 16 prix number(8,2), 17 codetva number(1), 18 categorie char(10), 19 qtestk number(5) 20 ) 21 create table commandes( 22 nocde number(9), 23 nocli number(4), 24 datecde date, 25 etatcde char(2), 26 constraint pk_commandes primary key (nocde), 27 constraint fk_commandes_clients foreign key(nocli) references clients(nocli), 28 constraint ck_commandes_etat check (etatcde in (’EC’,’LI’, ’SO’)) 29 ) 30 create table ligcdes( 31 nocde number(6) 32 constraint fk_ligcdes_commandes references commandes(nocde), 33 nolig number(2) 34 constraint ck_ligcdes_nolig check (nolig>0), 35 refart char(4) 36 constraint fk_ligcdes_articles references articles(refart), 37 qtecde number(5), 38 constraint pk_ligcdes primary key(nocde,nolig) 39 ) 40 create view v_cdecli (nocde, datecde, noclient, nomcli) as

- 5 -© ENI Editions - All rigths reserved

Page 79: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

41 select nocde, datecde, commandes.nocli, nomcli 42 from commandes, clients 43 where commandes.nocli=clients.nocli 44 grant select on articles to public 45 ; Schéma créé. SQL> desc commandes Nom NULL ? Type ----------------------------------------- -------- ------------------- NOCDE NOT NULL NUMBER(9) NOCLI NUMBER(4) DATECDE DATE ETATCDE CHAR(2) SQL> desc clients Nom NULL ? Type ----------------------------------------- -------- ------------------- NOCLI NOT NULL NUMBER(4) NOMCLI NOT NULL VARCHAR2(30) ADRCLI VARCHAR2(80) CODE_POSTAL NUMBER(5) VILLE CHAR(30) SQL> desc articles Nom NULL ? Type ----------------------------------------- -------- ------------------- REFART NOT NULL CHAR(4) DESIGNATION VARCHAR2(30) PRIX NUMBER(8,2) CODETVA NUMBER(1) CATEGORIE CHAR(10) QTESTK NUMBER(5) SQL> desc ligcdes Nom NULL ? Type ----------------------------------------- -------- ------------------- NOCDE NOT NULL NUMBER(6) NOLIG NOT NULL NUMBER(2) REFART CHAR(4) QTECDE NUMBER(5) SQL>

Une des instructions DDL spécifiées (CREATE VIEW) contient une erreur (nom de colonne incorrect ligne 18) et n’a pu aboutir. L’autre instruction (CREATE TABLE) spécifiée dans le CREATE SCHEMA AUTHORIZATION a été annulée.

SQL> drop table LIGCDES ; Table supprimée. SQL> drop view V_CLICDELIG ; Vue supprimée. SQL> create schema authorization GILLES 2 create table LIGCDES ( 3 NOCDE number(6) 4 constraint LIGCDES_NOCDE_RF 5 references COMMANDES(NOCDE), 6 NOLIG number(2) 7 constraint LIGCDES_NOLIG_CK check(NOLIG 0), 8 REFART char(4) 9 constraint LIGCDES_refart_RF 10 references ARTICLES(REFART), 11 QTECDE number(5), 12 constraint LIGCDES_PK primary key (NOCDE, NOLIG)) 13 create view V_CLICDELIG (NOCLIENT, NOMCLI, NOCDE, DATECDE, 14 NOLIG, REFART, QTECDE) as

- 6 - © ENI Editions - All rigths reserved

Page 80: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

15 select NOCLIENT, NOMCLI, LIGCDES.NOCDE, DATECDE, NOLIG, 16 REFART, QTECDE 17 from V_CDECLI, LIGCDES 18 where V_CDECLI.NOCDE = LIGCDES.NOCD ; create schema authorization GILLES * ERREUR à la ligne 1: ORA-02427: Echec de création de vue SQL> SQL> select * from LIGCDES ; select * from LIGCDES * ERREUR à la ligne 1: ORA-00942: Table ou vue inexistante SQL>

c. Les objets Synonym

Un synonyme est le nom alternatif donné à un objet TABLE, VIEW, SEQUENCE, SNAPSHOT, PROCEDURE, FUNCTION ou PACKAGE.

Les synonymes apportent plus de souplesse dans la gestion des noms d’objets :

mise à disposition d’objets pour tous les utilisateurs sous le même nom,

masquage du nom du SCHEMA auquel appartient l’objet,

possibilité de référencer plusieurs fois un objet dans une requête,

simplification dans l’écriture des requêtes.

Syntaxe

CREATE [PUBLIC] SYNONYM nom FOR objet ;

PUBLIC place le synomyme dans le groupe PUBLIC, le rendant ainsi visible de tout utilisateur défini sur la base de données (sans référence à un schéma). Sinon le synonyme reste local au SCHEMA de l’utilisateur propriétaire.

Les synonymes offrent la possibilité d’attribuer plusieurs noms à un même objet, ce qui va permettre une simplification lors de l’écriture des requêtes, surtout lorsque la même table doit être utilisée plusieurs fois dans le même ordre SELECT.

Les synonymes PUBLIC sont très utiles car ils offrent la possibilité à une application de travailler avec des tables sans tenir compte du schéma sur lequel les objets ont été créés. Avec ce type d’élément, l’application cliente est totalement indépendante de la structure de la base et du propriétaire des éléments.

Syntaxe

DROP SYNONYM nom ;

Exemple

Jointure de la table NOMENCLATURE avec elle­même pour visualiser les articles composés :

SQL>select * from NOMENCLATURE; REFART DESIGNATION COMPOSANT NOMBRE ------- --------------- ---------- ---------- XX55 VELOCIPEDE 0 x133 Roues XX55 2 x520 Cadre XX55 1

Création

Suppression

- 7 -© ENI Editions - All rigths reserved

Page 81: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

x456 Guidon XX55 1 QD24 Lot de tapis 0 AB03 Carpettes QD24 10 6 ligne(s) selectionnée(s). SQL>create synonym COMPOSE for NOMENCLATURE; Synonyme créé. SQL>select COMPOSE.REFART,COMPOSE.DESIGNATION, 2 NOMENCLATURE.NOMBRE, 3 NOMENCLATURE.DESIGNATION 4 from NOMENCLATURE,COMPOSE 5 where NOMENCLATURE.COMPOSANT=COMPOSE.REFART 6 order by COMPOSE.REFART; REFART DESIGNATION NOMBRE DESIGNATION ---------- ------------------- ---------- -------------------- QD24 Lot de tapis 10 Carpettes XX55 VELOCIPEDE 2 Roues XX55 VELOCIPEDE 1 Cadre XX55 VELOCIPEDE 1 Guidon

d. Les objets Sequence

La création d’un objet SEQUENCE met à disposition de l’utilisateur un générateur de nombres.

Les séquences sont utilisées pour générer des numérotations automatiques, en particulier pour la création de valeurs de clé primaire.

L’utilisation d’une SEQUENCE est plus souple et donne de meilleures performances que la gestion manuelle des compteurs par l’intermédiaire d’une table.

Cependant l’utilisation d’une séquence ne garantit pas l’absence de "trous" dans la numérotation. La séquence est un simple générateur de numéros et tous les numéros sont différents mais si des numéros sont demandés à une séquence et ne sont pas utilisés par la suite, alors ces numéros sont perdus. La séquence est en effet un objet à part entière et peut être utilisée par plusieurs tables.

Chaque valeur séquence s’exprime au maximum sur 28 chiffres significatifs.

Syntaxe

CREATE SEQUENCE nom [paramètres];

ALTER SEQUENCE nom paramètres ;

DROP SEQUENCE nom ;

START WITH n

Valeur initiale.

INCREMENT BY n

Pas d’incrémentation. Il peut être positif ou négatif.

MINVALUE n/NOMINVALUE

Valeur limite minimum ou non.

MAXVALUE n/NOMAXVALUE

Valeur limite maximum ou non.

CYCLE/NOCYCLE

Paramètres

- 8 - © ENI Editions - All rigths reserved

Page 82: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

CYCLE force la séquence à repasser à MINVALUE lorsque MAXVALUE a été atteinte (séquence croissante) ou à MAXVALUE lorsque MINVALUE a été atteinte (séquence décroissante).

CACHE n/NOCACHE

Force l’anticipation de la génération des valeurs suivantes de la séquence en mémoire. A pour effet d’améliorer les temps de réponse de la séquence.

ORDER/NOORDER

Garantit un ordre d’affectation des nombres dans l’ordre des demandes. Cette option ne présente d’intérêt que dans le cas de l’utilisation de l’option PARALLEL OPTION en mode PARALLEL au niveau de l’instance Oracle.

L’utilisation se fait par l’intermédiaire des pseudos­colonnes dans les instructions de manipulation de données.

nomseq.CURRVAL

Donne la valeur actuelle de la séquence. Cette pseudo­colonne n’est pas valorisée par la création de la séquence ni lors de l’ouverture d’une nouvelle session.

nomseq.NEXTVAL

Incrémente la séquence et retourne la nouvelle valeur de la séquence. Cette pseudo­colonne doit être la première référencée après la création de la séquence ou une ouverture de session.

Si la même séquence est référencée à partir de plusieurs sessions, la valeur de la pseudo­colonne CURRVAL dans une session n’est pas modifiée tant que l’utilisateur correspondant ne référence pas la pseudo­colonne NEXTVAL ; et ce, même si d’autres utilisateurs référencent NEXTVAL dans leur session.

Exemple

SQL> create sequence C_NOCLI start with 1000 maxvalue 9999 nocycle; Séquence créée. SQL> insert into CLIENTS (NOCLI, NOMCLI, VILLE) 2 values (C_NOCLI.nextval, ’DUPOND et DUPONT’, ’LILLE’); 1 ligne créée. SQL> insert into CLIENTS (NOCLI, NOMCLI, VILLE) 2 values (C_NOCLI.nextval, ’DURAND et DURANT’, ’TOURCOING’); 1 ligne créée. SQL> select NOCLI, NOMCLI, VILLE from CLIENTS order by NOCLI; NOCLI NOMCLI VILLE --------- ----------------------------- ---------------------- 15<+> DUPONT S.A. NANTES 20 Etb LABICHE NANTES 35 DUBOIS Jean NANTES 36 BERNARD S.A. PARIS 138 DUBOIS Jean TOURS 152 LAROCHE LE MANS 1000 DUPOND et DUPONT LILLE 1001 DURAND et DURANT TOURCOING 8 ligne(s) sélectionnée(s). SQL>

2. Les requêtes complexes

a. Éléments de syntaxe

Pseudos­colonnes

- 9 -© ENI Editions - All rigths reserved

Page 83: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Nom alternatif donné à une colonne ou à une table dans une requête.

Les alias de colonne permettent de :

Changer le nom de la colonne à l’affichage ou pour la table résultante.

Donner un nom comportant des caractères spéciaux (espace par exemple).

Les alias de table définis dans les clauses FROM des instructions SELECT correspondent à des synonymes internes à la requête. Ils permettent d’alléger l’écriture de l’instruction et de référencer dans des contextes différents la même table dans une instruction DML complexe (avec sous­requête).

Syntaxe

SELECT colonne [AS] alias_colonne,... FROM table alias_table,...

Exemples

Affichage d’un nom de colonne comportant des espaces :

SQL> select NOCLI, NOMCLI as "Nom du client" from CLIENTS ; NOCLI Nom du client --------- ------------------------------ 1000 DUPOND et DUPONT 1001 DURAND et DURANT 15 DUPONT S.A. 20 Etb LABICHE 35 DUBOIS Jean 36 BERNARD S.A. 138 DUBOIS Jean 152 LAROCHE 8 ligne(s) sélectionnée(s). SQL>

Utilisation de la table d’origine dans une sous­requête. Alignement de la quantité en stock de chaque article à la valeur maximum de la quantité en stock pour la famille (deux premiers caractères de la référence).

SQL> update articles a 2 set qtestk=(select max (qtestk) from articles b 3 where substr(a.refart,1,2)=substr(b.refart,1,2)); 9 ligne(s) mise(s) à jour. SQL> select refart, designation, prix, qtestk 2 from articles; REFA DESIGNATION PRIX QTESTK ---- ------------------------------ ---------- ---------- AB22 Taps Persan 1250,1 116 CD50 Chaine HIFI 735,4 20 CD21 Platine laser 500 20 ZZZZ Article bidon 25 AA00 Cadeau 8 AB03 Carpette 150 116 AB Tapis 116 ZZ01 Lot de tapis 500 25 AB10 Tapis de chine 1500 116 9 ligne(s) sélectionnée(s). SQL>

Compare, suivant l’opérateur donné (=,<>,<,<=,>,>=), les valeurs des colonnes spécifiées avec chacune des valeurs de la liste. L’expression est vraie si au moins une des comparaisons est vraie. La liste de valeurs peut être une liste de

Alias

Any

- 10 - © ENI Editions - All rigths reserved

Page 84: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

constantes littérales ou des valeurs retournées par une sous­requête.

Syntaxe

SELECT ...... WHERE [(colonne, colonne,...)] opérateur ANY (SELECT ...../expression,...);

La sous­requête ou la liste de valeurs doit retourner autant de valeurs que la liste d’expressions à comparer.

Exemple

Affichage des articles ayant le même prix que l’article ZZ01 :

SQL> select refart, designation, prix, qtestk from articles 2 where prix=ANY(select prix from articles 3 where refart=’ZZ01’); REFA DESIGNATION PRIX QTESTK ---- ------------------------------ ---------- ---------- CD21 Platine laser 500 20 ZZ01 Lot de tapis 500 25 SQL>

Compare, suivant l’opérateur donné (=,<>,<,<=,>,>=), les valeurs des colonnes spécifiées avec chacune des valeurs de la liste. L’expression est vraie si toutes les comparaisons sont vraies. La liste de valeurs peut être une liste de constantes littérales ou des valeurs retournées par une sous­ requête.

Syntaxe

SELECT ...... WHERE [(colonne, colonne,..)] opérateur ALL (SELECT...../expression,...);

La condition est vraie si la sous­requête retourne au moins une ligne.

Syntaxe

SELECT ...... WHERE [(]colonne [, colonne, ..)] EXISTS (SELECT ...../expression,...);

Exemple

La liste des clients n’est affichée que si au moins une commande existe dans la table COMMANDES.

SQL> select NOCLI, NOMCLI from CLIENTS 2 where exists (select ’x’ from COMMANDES) ; NOCLI NOMCLI --------- ------------------------------ 1000 DUPOND et DUPONT 1001 DURAND et DURANT 15 DUPONT S.A. 20 Etb LABICHE 35 DUBOIS Jean 36 BERNARD S.A. 138 DUBOIS Jean 152 LAROCHE 8 ligne(s) sélectionnée(s). SQL> delete from COMMANDES; 4 ligne(s) supprimée(s). SQL> select NOCLI, NOMCLI from CLIENTS 2 where exists (select ’x’ from COMMANDES) ;

All

Exists

- 11 -© ENI Editions - All rigths reserved

Page 85: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

aucune ligne sélectionnée SQL>

b. Les sous­requêtes

Dans l’écriture d’une requête complexe, on distingue la requête externe de la requête interne, la sous­requête.

Les sous­requêtes peuvent être divisées en deux catégories : les sous­requêtes imbriquées et les sous­requêtes corrélées.

Dans une sous­requête imbriquée il n’y a pas de lien explicite entre la requête interne et la requête externe. La requête interne est exécutée une seule fois pour construire la liste de valeurs, avant l’exécution de la requête externe (quel que soit le nombre de lignes ramenées par celle­ci).

Exemple

Liste des clients qui habitent dans la même ville que le client "DUBOIS Jean".

SQL> select NOCLI, NOMCLI, VILLE from CLIENTS 2 where VILLE in (select VILLE from CLIENTS 3 where NOMCLI like ’DUBOIS%’) ; NOCLI NOMCLI VILLE --------- ------------------------------ ---------- 15 DUPONT S.A. NANTES 20 Etb LABICHE NANTES 35 DUBOIS Jean NANTES 138 DUBOIS Jean TOURS SQL>

Dans une sous­requête corrélée, la condition spécifiée dans la clause WHERE de la requête interne fait référence à une ou plusieurs colonnes de la requête externe. La requête interne est donc réexécutée pour chaque ligne retournée par la requête externe.

Exemple

Liste des clients pour lesquels il n’existe pas de commande.

SQL> select nocli, nomcli 2 from clients cl 3 where not exists (select nocli 4 from commandes co 5 where cl.nocli=co.nocli); NOCLI NOMCLI ---------- ------------------------------ 15 DUPONT S.A. 20 Etb LABICHE 35 DUBOIS Jean 36 Bernard S.A. 37 Ets LAROCHE 138 DUBOIS Jean 152 LAROCHE 7 ligne(s) sélectionnée(s). SQL>

Lors de l’écriture des sous­requêtes, il est possible de choisir l’écriture de sous­requête imbriquée, qui favorise alors l’utilisation de la clause IN, ou bien l’écriture de sous­requête corrélée, qui favorise l’utilisation de la clause EXISTS. Pour savoir qu’elle est la solution à retenir en fonction des données à extraire, il faut se pencher un peu plus sur le

Sous­requêtes imbriquées

Sous­requêtes corrélées

Différence entre les deux types de sous­requêtes

- 12 - © ENI Editions - All rigths reserved

Page 86: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

fonctionnement des clauses IN et EXISTS.

Dans le cadre d’utilisation de la clause IN (sous­requête imbriquée), il est possible de concevoir que la sous­requête est évaluée comme une vue en ligne et qu’une jointure est faite sur la table de la requête principale avec les informations issues de cette sous­requête.

L’exemple présentant la sous­requête imbriquée est évalué de la façon suivante :

Select nocli, nomcli, ville from clients cli1, (select ville from clients where nomcli like ’DUBOIS%’) cli2 where cli1.ville=cli2.ville

Dans le cas de l’utilisation de la clause EXISTS, la sous­requête corrélée est exécutée pour chaque ligne issue de la requête externe. Cette solution sera donc favorable si la table de la requête externe est relativement faible et qu’il existe de bons index posés sur la table de la sous­requête sur les colonnes qui participent à la jointure.

L’exemple illustrant la sous­requête corrélée est intéressant par rapport à une sous­requête imbriquée si :

le nombre de clients est restreint par rapport aux commandes ;

l’extraction des différents numéros de clients à partir de la table des commandes représente une lourde charge de travail.

Un index est posé sur la colonne NOCLI de la table des commandes afin d’accélérer les temps de jointure.

c. Les requêtes hiérarchiques

Il est parfois nécessaire d’interroger les données suivant un ordre hiérarchique bien précis. Pour cela Oracle met à notre disposition des commandes pour extraire les données en utilisant un ordre. Ces commandes sont CONNECT BY PRIOR et START WITH. Lors de l’exécution d’une telle requête, Oracle procède de la façon suivante :

Oracle sélectionne la racine de l’arbre, ce sont les lignes qui satisfont la condition indiquée dans la clause START WITH.

Oracle sélectionne les enfants de chaque père. Tous doivent satisfaire la condition indiquée dans la clause CONNECT BY.

Tous les enfants sont sélectionnés les uns après les autres.

Si la requête contient une clause WHERE, Oracle supprime de la hiérarchie toutes les lignes qui ne respectent pas la clause WHERE.

Pour savoir à quel niveau de la hiérarchie on se situe, Oracle met à notre disposition la pseudo­colonne LEVEL.

Exemple

Création de table EMPLOYES. Chaque employé peut dépendre d’un chef dont il connaît le numéro. Le chef d’un employé est lui aussi un employé. On souhaite connaître l’organigramme de l’entreprise.

SQL> create table employes( 2 noemp number(5) 3 constraint pk_employes primary key, 4 nom char(30), 5 poste char(15), 6 nochef number(5)); Table créée. SQL>

La requête SQL permet de connaître l’organisation hiérarchique de l’entreprise :

SQL> select substr(lpad(’ ’,2*(level-1))||nom,1,30) as nom, 2 noemp, nochef, poste 3 from employes 4 start with poste=’pdg’

- 13 -© ENI Editions - All rigths reserved

Page 87: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

5 connect by prior noemp=nochef; NOM NOEMP NOCHEF POSTE ------------------------------ ---------- ---------- --------------- Ernest 5 pdg Bernard 2 5 drh Albert 1 2 comptable Coutard 3 2 secrétaire Hestor 8 2 employé Fergère 6 5 expert Dionaux 4 6 secrétaire Grillet 7 6 employé 8 ligne(s) sélectionnée(s). SQL>

La fonction SYS_CONNECT_BY_PATH, qui n’est utilisable que dans les requêtes hiérarchiques permet de connaître le chemin complet depuis le sommet de l’arbre. Cette fonction ne peut s’appliquer qu’aux colonnes de type caractère.

L’exemple ci­dessous montre l’utilisation de cette fonction dans une requête hiérarchique.

SQL> select lpad(’ ’,2*(level-1))||SYS_connect_by_path(rtrim(nom),’/’) as nom 2 from employes 3 start with poste=’pdg’ 4 connect by prior noemp=nochef; NOM ---------------------------------------------------------------------- /Ernest /Ernest/Bernard /Ernest/Bernard/Albert /Ernest/Bernard/Coutard /Ernest/Bernard/Hestor /Ernest/Fergre /Ernest/Fergre/Dionaux /Ernest/Fergre/Grillet 8 ligne(s) sélectionnée(s). SQL>

La fonction CONNECT_BY_ROOT permet de connaître, à partir d’un élément extrait d’une requête hiérarchique, les informations concernant le sommet de la hiérarchie. Il est nécessaire de faire précéder le nom des colonnes pour lesquelles on souhaite cette information par CONNECT_BY_ROOT.

Cette fonctionnalité est surtout intéressante lorsque l’on souhaite extraire d’une façon hiérarchique les données avec une restriction sur certains critères.

Par exemple, si la table contient des règles d’assemblage de pièces, il est possible à l’aide du CONNECT_BY_ROOT de connaître les éléments qui possèdent la pièce sur laquelle est faite la restriction.

Exemple

L’exemple ci­dessous permet facilement de connaître le "grand chef" de chaque employé.

- 14 - © ENI Editions - All rigths reserved

Page 88: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

L’extraction de données de façon hiérarchique est souvent faite par étape. Pour savoir si un élément est terminal ou non, il faut effectuer une requête hiérarchique à partir de cet élément. Avec la fonction CONNECT_BY_ISLEAF qui retourne 0 si l’élément n’est pas feuille et 1 sinon, il est tout de suite possible d’identifier les éléments qui possèdent un détail.

Exemple

Dans l’exemple ci­dessous on est capable de faire la distinction entre les employés qui gèrent une équipe et ceux qui ne le font pas.

3. Verrouillage des tables

Lors des transactions concurrentes (accès aux mêmes données depuis des transactions différentes), il est nécessaire de préserver la cohérence des données.

À un instant donné, une seule transaction est autorisée à modifier une donnée (une ligne). Les autres transactions souhaitant modifier la même donnée peuvent être mises en attente (sérialisation des demandes) de la fin de la transaction.

Pour permettre ce fonctionnement, Oracle gère simultanément un verrou au niveau de chaque ligne en cours de modification et un verrou au niveau de la table. Le verrou posé au niveau de la ligne (verrou TX : Row exclusive) est un verrou exclusif : si une transaction a pu poser ce verrou, aucune autre ne pourra le faire avant que le verrou ne soit relâché par la transaction (COMMIT ou ROLLBACK).

Les verrous de table peuvent être posés automatiquement par Oracle au cours de l’exécution des instructions DML INSERT, UPDATE, DELETE et PL/SQL SELECT ... FOR UPDATE ou explicitement par les utilisateurs à l’aide de l’instruction LOCK TABLE.

- 15 -© ENI Editions - All rigths reserved

Page 89: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

EXCLUSIVE (X)

La pose de ce type de verrou sur une table empêche toute autre transaction de poser explicitement un verrou sur cette table et d’accéder à cette table en modification.

SHARE (S)

La pose de ce type de verrou sur une table empêche toute autre transaction de poser un verrou autre qu’un verrou SHARE sur la table et d’y accéder en modification.

ROW SHARE (RS)

La pose de ce type de verrou sur une table permet l’accès concurrent à la table (modification de lignes différente dans chacune des transactions) et empêche toute autre transaction de poser sur cette table un verrou exclusif. C’est un verrou d’intention.

ROW EXCLUSIVE (RX)

La pose de ce verrou sur une table indique que des lignes y ont été modifiées par une instruction DML. Il empêche la pose d’un verrou exclusif à partir d’une autre transaction.

SHARE ROW EXCLUSIVE (SRX)

La pose de ce verrou sur une table empêche la pose d’un verrou par une transaction autre qu’un verrou d’intention RS.

Les instructions DML INSERT, UPDATE, DELETE posent automatiquement un verrou RX sur la table en cours de modification. Une instruction SELECT ... FROM ... FOR UPDATE dans un bloc PL/SQL provoque la pose d’un verrou S sur la table.

Syntaxe

LOCK TABLE table / view INEXCLUSIVE / SHARE / ROW SHARE / ROW EXCLUSIVE / SHARE ROW EXCLUSIVE MODE [NOWAIT] ;

Exemple

Session 1 : La transaction verrouille la table COMMANDES de façon exclusive.

SQL> lock table COMMANDES in EXCLUSIVE mode ; Table(s) verrouillée(s). SQL>

Session 2 : Tentative de mise à jour d’une ligne de la table COMMANDES. L’instruction se met en attente du déverrouillage de la table.

SQL> insert into COMMANDES (NOCDE, NOCLI, DATECDE, ETATCDE) 2 values (3001, 35, SYSDATE, ’EC’) ;

Session 1 : Insertion d’une ligne et validation de la transaction.

SQL> insert into COMMANDES (NOCDE, NOCLI, DATECDE, ETATCDE) 2 values (3001, 35, SYSDATE, ’EC’) ; 1 ligne créée. SQL> commit ; Validation effectuée. SQL>

Session 2 : L’instruction d’insertion est exécutée mais échoue car la même donnée vient d’être insérée dans l’autre session.

Types de verrou

Lock

- 16 - © ENI Editions - All rigths reserved

Page 90: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

SQL> insert into COMMANDES (NOCDE, NOCLI, DATECDE, ETATCDE) 2 values (3001, 35, SYSDATE, ’EC’) ; insert into COMMANDES (NOCDE, NOCLI, DATECDE, ETATCDE) * ERREUR à la ligne 1: ORA-00001: violation de contrainte unique (GILLES.COMMANDES_PK) SQL>

4. Les commentaires

Afin de faciliter les opérations de mise à jour de la base, il est possible de poser des commentaires sur les tables et les vues ainsi que sur chacune des colonnes qui composent ces tables et ces vues. La pose de commentaires est une étape indispensable car elle permet de connaître très exactement la signification et le rôle de chaque élément de la base de données. Tous ces commentaires sont stockés dans un dictionnaire de données et sont accessibles en interrogeant certaines vues du dictionnaire.

Pour poser un commentaire sur les colonnes, il n’est pas indispensable d’avoir posé au préalable un commentaire sur la table ou la vue.

Syntaxe

COMMENT ON TABLE nom_table_vue IS ’texte’; COMMENT ON COLUMN nom_table_vue.nom_colonne IS ’texte’;

Exemple

Un commentaire est posé sur la table CLIENTS.

Un commentaire est ensuite posé sur la colonne adrcli pour expliquer les données contenues dans cette colonne :

Pour connaître les commentaires, il faut interroger le dictionnaire :

Les vues ALL_COL_COMMENTS et USER_ COL_COMMENTS contiennent les commentaires posés au niveau colonne.

5. Informations sur les objets du schéma

- 17 -© ENI Editions - All rigths reserved

Page 91: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Le dictionnaire de données possède de nombreuses vues qui donnent une information détaillée des différents éléments présents dans le schéma.

Parmi les vues les plus couramment utilisées, on peut citer :

ALL_OBJECTS, USER_OBJECTS

ALL_CATALOG, USER_CATALOG

ALL_TABLES, USER_TABLES

ALL_TAB_COLUMNS, USER_TAB_COLUMNS

ALL_TAB_COMMENTS, USER_TAB_COMMENTS

ALL_COL_COMMENTS, USER_COL_COMMENTS

ALL_VIEWS, USER_VIEWS

ALL_INDEXES, USER_INDEXES

ALL_IND_COLUMNS, USER_IND_COLUMNS

ALL_SEQUENCES, USER_SEQUENCES

ALL_SYNONYMS, USER_SYNONYMS

ALL_DEPENDENCIES, USER_DEPENDENCIES

Toutes ces vues peuvent être retrouvées en effectuant une requête sur la vue DICT qui recense toutes les vues constitutives du dictionnaire avec pour chacune d’elle un petit commentaire indiquant leur rôle.

Exemple

La vue USER_TABLES est utilisée pour connaître toutes les tables de l’utilisateur scott.

6. Fonctionnalités spécifiques

Certaines fonctions doivent réagir différemment suivant le langage sélectionné au niveau du serveur Oracle. Au niveau Oracle, tous ces critères sont fixés par les paramètres NLS (National Language Support). Ces paramètres ont une incidence principalement sur l’affichage des données de type date et sur l’affichage des données de type numérique.

Toutes les fonctions SQL qui dépendent de NLS acceptent de prendre en charge un paramètre NLS spécifique. Ces fonctions sont : TO_CHAR, TO_DATE, TO_NUMBER, NLS_UPPER, NLS_LOWER, NLS_INITCAP, NLSSORT.

Le principal intérêt de fixer le paramètre NLS au niveau de la fonction est de passer outre le choix réalisé au niveau de la session.

Exemple

Utilisation de paramètre NLS dans une fonction. Pour comparer deux dates, l’exemple suivant transforme la date de référence, qui est saisie sous forme de chaîne de caractères en donnée de type Date. Pour réaliser cette transformation, la fonction TO_DATE est utilisée. En plus de la chaîne de caractères contenant la date, cette fonction accepte deux autres paramètres : le format de la date et le paramètre de type NLS indiquant dans quelle langue la date a été saisie.

NLS

- 18 - © ENI Editions - All rigths reserved

Page 92: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

La liste des différents paramètres NLS disponibles sur les fonctions SQL :

Différents exemples d’utilisation des paramètres NLS sont illustrés dans l’exemple suivant :

TO_CHAR(datecde,’DD/MON/YYYY’,’NLS_DATE_LANGUAGE=FRENCH’) TO_NUMBER(’15.999,80’,’9G999D99’,’NLS_NUMERIC_CHARACTERS=’’,.’’’) TO_CHAR(prix,’9G999D99F’,’NLS_NUMERIC_CHARACTERS=’’,.’’ NLS_ISO_CURRENCY=Japan’) NLS_UPPER(nomcli, ’NLS_SORT=SWISS’) NLSSORT(nomcli,’NLS_SORT=GERMAN’)

L’instruction CASE permet de mettre en place une condition d’instruction conditionnelle directement dans la requête SELECT, sans faire appel à un bloc d’instructions procédurales.

L’intérêt principal de cette instruction est de faciliter la présentation et la mise en forme des résultats directement dans les requêtes SELECT. L’instruction CASE permet également de limiter le nombre de fois où il est nécessaire de faire appel à un bloc PL/SQL pour résoudre le problème.

L’instruction CASE est limitée à 128 choix. Pour pouvoir outre­passer cette limite, il est nécessaire d’imbriquer les instructions les unes dans les autres.

Fonctions SQL Paramètres NLS

TO_DATE NLS_DATE_LANGUAGE

NLS_CALENDAR

TO_NUMBER

NLS_NUMERIC_CHARACTERS

NLS_CURRENCY

NLS_DUAL_CURRENCY

NLS_ISO_CURRENCY

TO_CHAR

NLS_DATE_LANGUAGE

NLS_NUMERIC_CHARACTERS

NLS_CURRENCY

NLS_DUAL_CURRENCY

NLS_ISO_CURRENCY

NLS_CALENDAR

NLS_UPPER NLS_SORT

NLS_LOWER NLS_SORT

NLS_INITCAP NLS_SORT

Case

- 19 -© ENI Editions - All rigths reserved

Page 93: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Syntaxe

CASE expression WHEN expression_comparaison1 THEN expression_retournée1 WHEN expression_comparaison2 THEN expression_retournée2 .... [ELSE expression_retournée] END CASE WHEN condition1 THEN expression_retournée1 WHEN condition2 THEN expression_retournée2 .... [ELSE expression_retournée] END

L’instruction ELSE est optionnelle et, dans le cas où cette condition n’est pas présente, la valeur retournée est NULL si aucune instruction WHEN ... THEN n’est exécutée.

Exemple

L’exemple ci­dessous permet de connaître le libellé du département des clients à partir du code postal.

SQL> select nocli, nomcli, case to_number(substr(code_postal,1,2)) 2 when 44 then ’Loire Atlantique’ 3 when 75 then ’Paris’ 4 else ’Autre’ END as departement 5 from clients; NOCLI NOMCLI DEPARTEMENT ---------- ------------------------------ ---------------- 15 DUPONT S.A. Loire Atlantique 20 Etb LABICHE Loire Atlantique 35 DUBOIS Jean Loire Atlantique 36 Bernard S.A. Paris 37 Ets LAROCHE Autre 138 DUBOIS Jean Autre 152 LAROCHE Autre 7 ligne(s) sélectionnée(s). SQL>

Dans cet exemple, c’est la région qui est connue à partir du code postal du client.

SQL> select nocli, nomcli, case 2 when to_number(substr(code_postal,1,2)) in (44,49,72,85,53) 3 then ’Pays de la Loire’ 4 else ’Autre’ END as departement 5 from clients; NOCLI NOMCLI DEPARTEMENT ---------- ------------------------------ ---------------- 15 DUPONT S.A. Pays de la Loire 20 Etb LABICHE Pays de la Loire 35 DUBOIS Jean Pays de la Loire 36 Bernard S.A. Autre 37 Ets LAROCHE Autre 138 DUBOIS Jean Autre 152 LAROCHE Pays de la Loire 7 ligne(s) sélectionnée(s). SQL>

7. Les expressions régulières

- 20 - © ENI Editions - All rigths reserved

Page 94: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Les expressions régulières représentent un outil puissant pour travailler avec les chaînes de caractères. Cette fonctionnalité est déjà présente sur de nombreux langages de programmation et sous Unix.

Les requêtes d’extraction de données avec des critères très précis de sélection sur les données de type caractère vont pouvoir être écrites plus facilement.

Pour pouvoir travailler avec les expressions régulières, Oracle propose un opérateur REGEXP_LIKE et trois fonctions : REGEXP_INSTR, REGEXP_ SUBSTR et REGEXP_REPLACE.

Les expressions régulières vont décrire à l’aide de méta­caractères la structure que doit posséder la chaîne de caractères avec laquelle on souhaite travailler.

Bien que les différents méta­caractères sont présentés par la suite, il est préférable de travailler avec quelques exemples d’expressions régulières afin de bien comprendre comment elles fonctionnent.

Les ancres

^ : marque le début de la ligne

$ : marque la fin de la ligne

Les quantifieurs

^ : correspond à 0 ou plusieurs caractères.

? : correspond à 0 ou 1 caractère.

+ : correspond 1 ou plusieurs caractères.

m : correspond à m caractères exactement.

m, : correspond à au moins m caractères.

m, n : correspond à au moins m caractères mais moins que n caractères.

Il faut faire attention à la manipulation de ces méta­caractères car ils ne possèdent pas forcément le même sens que ceux utilisés avec l’opérateur LIKE.

Le caractère . permet de signaler l’existence de n’importe quel caractère dans la chaîne.

Par exemple, l’expression régulière a.l peut correspondre aux chaînes de caractères apl, agl, ... mais également table, stable, allo. En effet dans l’expression régulière, seul est stipulé que les lettres a et l doivent être séparées par un caractère exactement. En aucun cas il n’est dit que la chaîne de caractères doit commencer par la lettre a et se finir par la lettre l. Si l’on souhaite un tel scénario, il faut utiliser les ancres afin de préciser le caractère qui marque le début de la chaîne. L’expression régulière ^a.l précise que la chaîne de caractères recherchée doit obligatoirement commencer par la lettre a, soit par exemple apl, agl, allo...

Par défaut, les caractères présents dans l’expression régulière ne doivent être présents qu’une seule fois dans la chaîne de caractères. Ainsi l’expression régulière ^a.*e$ signifie que l’on recherche une chaîne commençant par la lettre a et se terminant par la lettre e. Entre le premier et le dernier caractère il est possible d’avoir entre 0 et n caractères. Les chaînes ae, ane, anémone, ... répondent à cette expression.

Afin de permettre la construction d’expressions encore plus complexes, Oracle supporte les classes de caractères POSIX (Portable Operating system Interface). Grâce à cette classe de caractères, il va être possible d’écrire des expressions régulières extrêmement précises afin de retrouver seulement l’information voulue.

Les classes de caractères POSIX sont citées dans le tableau ci­dessus :

[:alpha:] caractère alphabétique.

[:lower:] caractère alphabétique en minuscule.

[:upper:] caractère alphabétique en majuscule.

[:digit:] numéro.

[:alnum:] caractère alpha numérique.

[:space:] espace.

[:punct:] caractère de ponctuation.

[:cntrl:] caractère de contrôle non imprimable.

[:print:] caractère imprimable.

Ces différentes classes de caractères permettent de couvrir l’ensemble des caractères présents dans la table ASCII.

- 21 -© ENI Editions - All rigths reserved

Page 95: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Pour pouvoir utiliser les classes de caractères POSIX dans les expressions régulières, il est nécessaire de les positionner entre des crochets [].

Par exemple, l’expression [[:upper:]] permet de rechercher une chaîne de caractères écrite uniquement en majuscules alors que [[:lower:]]5 correspond à des mots de 5 lettres en minuscules.

Pour affiner les recherches, il est possible de citer une liste de caractères que l’on souhaite voir apparaître à un emplacement particulier. Par exemple l’expression ^pla[tc]e$ permet d’identifier aussi bien plate que place.

Enfin, et c’est souvent là que réside la difficulté d’écriture des expressions régulières, certains méta­caractères ne possèdent pas le même sens suivant leur emplacement. C’est le cas pour les 2 méta­caractères ^ et ­.

Le caractère ^ lorsqu’il est placé en premier caractère d’une expression marque le début de l’expression par contre lorsqu’il apparaît comme premier caractère d’une liste de valeurs alors il marque la négation.

Par exemple ^A[[:lower::]] correspond aux chaînes Ane, Anneau, Arbre, Appel, .... Par contre l’expression ^A[^nop][[:lower:]] permet simplement d’extraire Arbre, Ami, Avant, ....

Le caractère ­ permet de simplifier l’écriture des plages de valeur en citant simplement le premier et le dernier caractères séparés par ­. Par exemple dans l’expression ^A[n­p][[:lower:]] permet d’identifier les chaînes suivantes Ane, Anneau, Appel, ....

Par contre s’il est placé en premier caractère d’une liste, il signale que les caractères situés à sa suite ne peuvent pas participer à la chaîne final.

Donc l’expression ^A[­nop][[:lower:]] permet d’identifier Avant, Ami, Arbre....

Cet opérateur permet l’utilisation des expressions régulières pour la recherche dans les clauses WHERE ou bien lors de la construction des contraintes d’intégrité.

Syntaxe

REGEXP_LIKE(colonne, exempression regulière)

Exemple

Dans l’exemple suivant, on recherche les clients dont le nom commence par B suivi de caractères en minuscules.

Mais l’opérateur REGEXP_LIKE peut également être utilisé pour définir des contraintes d’intégrité bien précise.

Par exemple, si l’on souhaite que les 2 premiers caractères d’une référence article soit toujours des caractères alphabétiques en majuscules, il est possible d’ajouter la contrainte d’intégrité suivante à la table des articles:

REGEXP_LIKE

- 22 - © ENI Editions - All rigths reserved

Page 96: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

La fonction REPLACE en SQL permet de substituer une chaîne de caractères par une autre. Mais l’utilisation de cette fonction nécessite de connaître exactement la chaîne à remplacer, ce qui n’est pas toujours le cas. La fonction REGEXP_REPLACE quant à elle se sert simplement d’une description de la chaîne à remplacer.

Syntaxe

REGEXP_REPLACE(chaîne, expression_regulière, chaîne_de_remplacement)

Exemple

Par exemple lorsque l’on souhaite éliminer les espaces inutiles dans une chaîne de caractères, la seule certitude que l’on possède est que s’il y a plus d’un espace (2, 3 ou plus) alors il est possible d’éliminer les espaces inutiles.

Dans l’exemple ci­dessus, les espaces inutiles sont supprimés du nom du client.

Cette fonction, dont l’objectif est le même que INSTR, permet de localiser l’emplacement de départ d’une sous­chaîne à l’intérieur d’une chaîne. L’avantage réside dans le fait qu’il n’est pas nécessaire de citer la sous chaîne, mais il suffit de la décrire à l’aide d’une expression régulière pour la localiser.

Syntaxe

REGEXP_REPLACE

REGEXP_INSTR

- 23 -© ENI Editions - All rigths reserved

Page 97: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

REGEXP_INSTR(chaîne, expression_regulière)

Exemple

Dans l’exemple ci­dessous, on souhaite connaître la position de la sous­ chaîne S.A. dans le nom des clients.

Comme pour la fonction SUBSTR, l’objectif de REGEXP_SUBSTR est d’extraire une sous­chaîne à partir d’une chaîne de caractères, mais en décrivant la sous­chaîne extraite à l’aide d’une expression régulière. Ceci permet d’extraire la sous­chaîne sans connaître sa position exacte, ni même sa longueur.

Syntaxe

REGEXP_SUBSTR(chaine, expression_regulière)

Exemple :

Dans l’exemple suivant, les noms des clients qui commence par LA est extrait.

REGEXP_SUBSTR

- 24 - © ENI Editions - All rigths reserved

Page 98: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Utilisation de SQL*Plus

L’accès et l’utilisation d’une base de données ORACLE peut se faire à l’aide de différents outils.

L’outil principal pour l’utilisation du SQL et du PL/SQL est l’interface utilisateur SQL*Plus.

Ce programme permet aux utilisateurs finaux, aux développeurs et aux administrateurs les fonctionnalités suivantes :

manipulation et exécution de commandes SQL et de blocs PL/SQL.

mise en forme des résultats de requêtes.

visualisation des structures des tables et copie de données inter­base.

commandes et opérations d’entrée/sortie (saisie, affichage, manipulation de variables).

SQL*Plus possède également ses propres ordres de programmation. Il faut veiller à ne pas confondre l’utilitaire SQL*Plus et le langage SQL*Plus.

L’outil SQL*Plus se décline sous trois formes différentes :

sqlplus.exe est un outil en ligne de commande.

sqlplusw.exe est un outil graphique que l’on peut utiliser depuis un poste Windows sur lequel le client Oracle est installé.

isqlplus est une application en mode Web qui permet de travailler avec une interface HTML de type sqlplus afin de faire des requêtes sur la base de données Oracle, sans pour autant avoir besoin d’installer quoi que ce soit sur le poste client.

- 1 -© ENI Editions - All rigths reserved

Page 99: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

L’interface isqlplus est extrêmement facile à utiliser et elle permet de présenter les résultats sous forme de tableau de façon systématique. De plus, cette interface possède un historique, ce qui permet de connaître les dernières instructions exécutées.

Attention toutefois lors de l’utilisation de isqlplus car par défaut la session est coupée sur le serveur Web au bout d’un temps, relativement court, de non utilisation. Cette rupture de connexion a lieu sur le serveur et l’utilisateur ne se rend compte de rien avant de demander l’exécution d’une requête. Afin de remédier à ce souci, il suffit simplement de demander au DBA de modifier la valeur du paramètre iSQLPlusTimeOutInterval dans le fichier isqlplus.conf.

Pour exécuter isqplus, il suffit depuis son navigateur Internet de saisir l’url suivante : http://nomServeur:7778/isqlplus où nomServeur représente le nom du serveur qui exécute le service Oracle http Server. Ce nom correspond normalement au serveur qui héberge l’instance Oracle. Le port 7778 est celui défini en standard par Oracle pour isqlplus mais l’administrateur de la base de données a pu le changer. Dans tous les cas, il faut demander confirmation de cette url auprès du DBA.

L’administrateur Oracle possède également la possibilité de modifier le feuille de style (.css) utilisée par l’application isqlplus afin de personnaliser au mieux l’interface en fonction de la charte graphique de l’entreprise.

Après avoir saisi le nom de l’utilisateur, son mot de passe et la chaine de connexion, l’écran de travail de isqlplus est affiché. Cet écran se divise en 2 zones.

La première zone permet de saisir le chemin complet d’un script. Il est possible d’utiliser le bouton Parcourir... pour localiser le script sans avoir à saisir le chemin complet. Ensuite, il est nécessaire de charger le script dans la zone de saisie des instructions par l’intermédiaire du bouton Charger le script.

La seconde zone permet de saisir librement les instructions SQL avant leur exécution.

- 2 - © ENI Editions - All rigths reserved

Page 100: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Dans tous les cas, le résultat des opérations d’extraction de données est présenté sous forme de tableau HTML. La lecture des informations est donc plus facile à réaliser que depuis sql*plus, surtout lorsque les colonnes sont définies sur des types de grande dimension pour lesquelles l’affichage dépasse la largeur de l’écran.

Les icones situées en haut à droite de l’écran permettent de faire les opérations les plus courantes telles que se connecter, se déconnecter, consulter l’historique des commandes ou encore accéder à la documentation.

Par défaut, la documentation disponible est celle relative à isqlplus, mais si votre poste dispose d’un accès Internet, vous pourrez consulter la documentation Oracle dans sa totalité.

Il est également possible par l’intermédiaire de l’icone préférences de modifier les préférences utilisateur par rapport à l’interface graphique de isqlplus, comme par exemple la largeur et la hauteur de la zone de texte qui est utilisée pour saisir les scripts.

1. Connexion et déconnexion

Pour pouvoir utiliser le SQL, il faut se connecter à la base de données, c’est­à­dire fournir un nom d’utilisateur, éventuellement protégé par un mot de passe.

SQL*Plus permet, soit de se connecter automatiquement en passant le nom et le mot de passe en paramètres de la ligne de commande du système d’exploitation, soit de demander le nom ou le mot de passe après le lancement.

On peut, en outre, changer de nom d’utilisateur en cours de session SQL*Plus en se reconnectant.

a. Lancement du programme

À partir du prompteur du système d’exploitation ;

Syntaxe

sqlplus[[-S] [nomuser[/motpasse][@chaîne_de_connexion]]

-S

mode silencieux.

nomuser

nom de connexion à la base.

- 3 -© ENI Editions - All rigths reserved

Page 101: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

motpasse

mot de passe de l’utilisateur.

chaîne_de_connexion

nom du service défini dans le fichier TNSNAMES.ORA à utiliser pour se connecter au serveur Oracle.

Les différents ordres permettant la configuration de SQL*Plus sont détaillés par la suite.

Si on souhaite retrouver toujours le même environnement de travail, il est possible de stocker ses préférences dans le ficher login.sql. Le fichier login.sql du répertoire courant est exécuté à la première connexion à SQL*Plus.

Exemples

Lancement du programme avec passage en paramètres du nom de l’utilisateur (TOTO) et du mot de passe (PIZZA) :

$sqlplus toto/pizza Connecté à : ........... SQL>_

Lancement du programme avec demande de connexion (le mot de passe est saisi en frappe aveugle) :

$sqlplus username : toto password : Connecté à : ............ SQL>_

b. Connexion après lancement

Syntaxe

CONNECT [nomuser[/motpasse]] [@chaîne_de_connexion]]

Exemple

L’utilisateur courant veut se connecter sous le nom FLORIAN :

SQL> Connect florian password : < Saisie du mot de passe en frappe aveugle> connecté. SQL>_

La chaîne de connexion n’est nécessaire que si l’on souhaite se connecter à un serveur Oracle qui n’est pas local. On peut donc se passer de chaîne de connexion lorsque l’on exécute SQL*PLUS directement sur le serveur Oracle.

Connexion à une base distante depuis SQL*PLUS

c. Changement du mot de passe

Permet à l’utilisateur de changer son mot de passe dans l’environnement SQL*Plus.

Syntaxe

CONNECT

PASSWORD

- 4 - © ENI Editions - All rigths reserved

Page 102: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

PASSWORD [nomuser]

Exemple

Changement du mot de passe de l’utilisateur courant.

d. Déconnexion

Après déconnexion, l’utilisateur ne peut plus utiliser de commande SQL ou PL/SQL.

Syntaxe

DISCONNECT

Exemple

Déconnexion sans sortie de SQL*Plus :

SQL>DISCONNECT Disconnected from ....... ....... SQL>_

e. Sortie de SQL*Plus

La sortie du programme entraîne la déconnexion à la base.

Syntaxe

EXIT [SUCCESS / FAILURE / WARNING /n /variable /:variable_liée][COMMIT / ROLLBACK]

SUCCESS/FAILURE/WARNING/n/ variable/:variable_liée

permet de communiquer au système d’exploitation un code de retour sur l’exécution de la session.

COMMIT/ROLLBACK

annule la transaction en cours au moment de la fin de session (COMMIT par défaut).

Exemple

Sortie de SQL*Plus et retour au système d’exploitation ($ : prompteur UNIX).

SQL> EXIT $.

2. Exécution des instructions

Après la connexion, l’utilisateur peut utiliser le SQL*Plus pour saisir des commandes SQL, des blocs PL/SQL ou des commandes SQL*Plus, à partir du prompteur.

Les commandes SQL et PL/SQL peuvent être saisies sur plusieurs lignes (on marque une fin de ligne par la touche [Entrée]), le caractère de fin de commande étant le point­virgule (;). Pour améliorer la lisibilité on peut insérer dans la

DISCONNECT

- 5 -© ENI Editions - All rigths reserved

Page 103: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

syntaxe autant d’espaces ou de tabulations qu’on le souhaite. Il n’y a pas de distinction entre majuscules et minuscules (sauf utilisation de guillemets).

Exemple

Création de lignes dans la table CLIENTS :

SQL> insert into CLIENTS (nocli, nom) values (10, ’TOTO’) ; 1 ligne creee SQL> insert into 2> Clients (Nocli, Nom) 3> values (15, ’Titi’) 4> ; 1 ligne creee SQL>

Les commandes SQL*Plus ne nécessitent pas de caractère de fin de commande, la marque de fin de ligne ([Entrée]) suffit. Si une commande doit être saisie sur plusieurs lignes, il faut utiliser le caractère de césure de ligne (tiret (­)).

Exemple

Déclaration de format de colonne :

SQL> column REFART heading "Référence" SQL> column DESIGN - SQL> heading "Désignation" SQL>

a. Gestion du buffer

La dernière instruction SQL est stockée en mémoire (buffer).

Ce buffer peut être réutilisé dans plusieurs cas :

réexécution de la dernière commande SQL ou du dernier bloc PL/SQL.

visualisation de la dernière commande.

modification de la dernière commande.

sauvegarde dans un fichier du buffer.

La rééxécution du buffer se fait par la commande RUN ou /.

Visualisation du buffer.

La ligne courante est indiqué par une astérisque (*). Il est possible de changer la ligne courante en ne listant qu’une seule ligne (on précise son numéro). La ligne listée devient alors la nouvelle ligne courante.

Syntaxe

L[IST] [n|n m|n|n LAST|*|* n|* LAST|LAST]

n, m : numéro de ligne

* : ligne courante

LAST : dernière ligne

Il est également possible de lister une seule ligne (qui devient alors la ligne courante) en tapant directement le numéro de la ligne.

Exemple

Saisie d’une commande SQL, visualisation du buffer, puis exécution :

LIST

- 6 - © ENI Editions - All rigths reserved

Page 104: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Ajout de ligne au buffer après la ligne courante.

Syntaxe

I[NPUT] [texte]

Exemple

Ajout d’une ligne à la dernière commande :

SQL> select * 2 from clients 3 where nocli>15 4 SQL> i 4 order by nomcli 5 SQL> l 1 select * 2 from clients 3 where nocli>15 4* order by nomcli SQL>

Ajout à la fin de la ligne courante.

Syntaxe

A[PPEND] texte

Exemple

Ajout de texte à la fin de la ligne 2 :

SQL> l 1 select * from CLIENT 2 where NOCLI>15 3* order by NOM SQL> 2 2* where NOCLI>15 SQL> A and NOCLI<20 2* where NOCLI>11 and NOCLI<20 SQL>

INPUT

APPEND

CHANGE

- 7 -© ENI Editions - All rigths reserved

Page 105: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Modification de la ligne courante.

Syntaxe

C[HANGE]/ancien texte/[nouveau texte]

Si le nouveau texte est omis, il y a suppression de l’ancien texte.

Exemple

Modification de la première ligne :

SQL> l 1 select * from clients 2* order by NOCLI SQL>1 1* select * from clients SQL>C/clients/COMMANDES 1* select * from COMMANDES SQL>

Suppression d’une ou de plusieurs lignes du buffer.

Syntaxe

DEL [n|n m|n|n LAST|*|* n|* LAST|LAST]

n, m : numéro de ligne

* : ligne courante

LAST : dernière ligne

Si la commande DEL est exécutée sans paramètres alors la ligne courante est supprimée.

Si la ligne courante est supprimée, alors c’est la ligne suivante (si elle existe) qui devient la nouvelle ligne courante.

Exemple

Suppression de la dernière ligne du buffer :

SQL> l 1 select * from clients 2 where NOCLI>10 3* order by NOM SQL> del SQL> l 1 select * from clients 2* where NOCLI>10 SQL>

Sauvegarde du buffer dans un fichier.

Syntaxe

S[AVE] nomfic [CREATE/REPLACE/APPEND]

Le fichier créé prend automatiquement l’extension .sql si aucune autre extension n’est précisée.

CREATE

(option par défaut) crée un nouveau fichier.

DEL

SAVE

- 8 - © ENI Editions - All rigths reserved

Page 106: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

REPLACE

remplace le contenu d’un fichier existant.

APPEND

ajoute le buffer à la fin d’un fichier existant.

Chargement du buffer à partir d’un fichier.

Syntaxe

G[ET] nomfic [LIST/NOLIST]

LIST

(option par défaut) liste le buffer.

NOLIST

supprime l’affichage.

b. Utilisation de scripts

Il est possible de stocker des commandes SQL ou SQL*Plus dans des fichiers de texte soit par SAVE, soit par l’éditeur système, puis d’exécuter ces scripts par SQL*Plus. Ces fichiers de commandes sont reconnus avec l’extension par défaut .sql, ils peuvent contenir des commentaires.

Appel de l’éditeur standard du système d’exploitation.

Syntaxe

[ED]IT [nomfic]

L’éditeur appelé est l’éditeur système sauf si la variable _EDITOR est valorisée (sous UNIX def _editor = vi, sous NT def _editor=notepad.exe).

Edit charge par défaut le fichier avec l’extension .sql. Si aucun nom de fichier n’est spécifié, Edit crée un fichier AFIEDT.BUF et recharge le buffer avec le contenu du fichier au retour dans SQL*Plus.

Commentaires.

Syntaxe

REM[ARK] texte

Le texte sera ignoré à l’exécution.

Les commentaires peuvent aussi être indiqués par :

--

le reste de la ligne situé après ­­ est ignoré par SQL*Plus.

/*... */

le texte situé entre ces deux séparateurs est ignoré par SQL*Plus. Le commentaire peut comporter plusieurs lignes.

Exécution des commandes contenues dans le fichier.

Syntaxe

STA[RT] nomfic ou @ nomfic ou @@nomfic

Par défaut, l’extension .sql est prise pour le fichier.

GET

EDIT

REM

START,@,@@

- 9 -© ENI Editions - All rigths reserved

Page 107: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Le nom du fichier doit contenir le chemin complet d’accès au fichier si ce dernier n’est pas dans le répertoire courant.

Par défaut, si seul le nom du fichier est indiqué derrière la commande START ou @ alors le fichier script est recherché dans le répertoire local de SQLPLUS. Le fait de lancer un script au travers de la commande @@ permet de garantir que le fichier sera recherché dans le même répertoire que celui du script qui demande l’exécution.

Il est possible de copier des données d’une table à une autre table située sur une base de données locale ou non. Pour cela on utilise la commande SQL*Plus COPY et les clauses FROM et TO pour préciser la source et la destination des données. Les données à copier sont issues d’une requête SELECT.

Syntaxe

COPY FROM base| TO base| FROM base TO base APPEND|CREATE|INSERT|REPLACE table_de_destination [(colonne, ...)] USING requête

FROM base

Permet de préciser le schéma qui contient les données à copier. Si la clause FROM est omise, alors l’origine des données est le schéma auquel SQL*Plus est connecté.

TO base

Permet de préciser le schéma de destination des données. Si la clause TO est omise, alors la destination des données est le schéma auquel SQL*Plus est connecté.

base

Sous ce terme sont regroupés le nom de l’utilisateur, son mot de passe et la chaîne de connexion pour accéder à une base de données distante.

APPEND

Les données issues de la requête sont insérées dans la table de destination. Si cette dernière n’existe pas, alors la table est créée avant l’insertion des données.

CREATE

Les données issues de la requête sont insérées dans la table de destination après la création de cette dernière. Si la table de destination était déjà présente avant l’exécution de la commande COPY, alors une erreur est retournée.

INSERT

Les données issues de la requête sont insérées dans la table de destination. Si la table de destination n’existe pas, alors COPY retourne une erreur.

REPLACE

Les données issues de la requête remplacent celles de la table de destination. Si la table de destination n’existe pas, alors elle est créée par la commande COPY.

Exemple

La table DEPT de l’utilisateur SCOTT va être copiée sous le schéma de l’utilisateur LIVRE. Les deux schémas se situent sur une base de données distante.

COPY

- 10 - © ENI Editions - All rigths reserved

Page 108: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

3. Gestion de l’environnement SQL*Plus

SQL*Plus permet de gérer directement (sans passer par le SQL) certaines fonctionnalités de la base, comme la visualisation des structures d’objet ou la copie de données d’une base à une autre. Il est également possible de personnaliser l’utilisation de SQL*Plus en modifiant des paramètres agissant sur le fonctionnement des commandes, sur l’affichage, ou sur le résultat des commandes.

Description de structure de table, vue ou synonyme.

Syntaxe

DESC[RIBE] table

Redirection des sorties.

Syntaxe

SPO[OL] nomfic/OFF/OUT

nomfic

nom du fichier recevant les sorties (extension .lst par defaut).

OFF

fermeture du fichier.

OUT

fermeture du fichier et sortie sur l’imprimante.

Visualisation de l’environnement.

Syntaxe

SHO[W] ALL/paramètre

Paramètres d’environnement.

Syntaxe

SET parametre valeur

La valeur par défaut des paramètres est la première des valeurs possibles indiquées :

DESCRIBE

SPOOL

SHOW

SET

- 11 -© ENI Editions - All rigths reserved

Page 109: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

AUTOCOMMIT OFF/ON/IMMEDIATE/n

validation automatique.

CMDSEP ;/OFF/ON/c

séparateur de commandes multilignes.

FEEDBACK 6/n/OFF/ON

affichage du nombre d’enregistrements selectionnés à partir de n.

LONG 80/n

format maximum des colonnes de type LONG.

NULL texte

représentation des valeurs NULL.

PAUSE OFF/ON/texte

activation de la pause en fin de page.

SPACE 1/n

nombre de caractères séparant les colonnes à l’affichage.

SQLCASE MIXED/LOWER/UPPER

conversion en majuscules ou minuscules des commandes avant exécution.

SQLCONTINUE >/texte

prompteur de la énième ligne.

SQLNUMBER ON/OFF

numérotation du prompteur de énième ligne.

SQLPROMPT SQL/texte

prompteur de la première ligne.

SQLTERMINATOR ;/c/OFF/ON

caractère de fin de commande.

ECHO OFF/ON

affichage des commandes d’un script à l’exécution.

TERMOUT ON/OFF

affichage du résultat des commandes d’un script.

Accès au système d’aide.

Syntaxe

HELP [commande]

HELP

- 12 - © ENI Editions - All rigths reserved

Page 110: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Accès au système d’exploitation.

Syntaxe

HOST [commande S.E.]

Avec certains systèmes d’exploitation, il est possible d’utiliser un caractère générique pour lancer une commande système depuis SQL*Plus. Comme ce caractère dépend du système, il faut consulter la documentation Oracle

relative à la plate­forme d’installation pour connaître ce caractère.

HOST

- 13 -© ENI Editions - All rigths reserved

Page 111: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Présentation des données

SQL*Plus offre quelques fonctionnalités pour gérer des variables, saisir des valeurs et mettre en page des résultats de requêtes.

Cela permet d’utiliser de manière plus conviviale le SQL ou le PL/SQL et de créer de véritables procédures de manière simple.

1. Gestion des variables

Il est possible de gérer deux sortes de variables :

les variables utilisateur, utilisées par SQL*Plus ou pour de la substitution de texte dans des commandes SQL et SQL*Plus avant leur exécution.

les variables de lien utilisées en interface avec le PL/SQL.

Création d’une variable utilisateur.

Syntaxe

DEF[INE] [variable = texte]

Sans paramètre, DEFINE permet de visualiser les variables existantes.

Les variables créées sont obligatoirement de type caractère.

Certaines variables ont des noms et des utilisations réservées :

_EDITOR

éditeur appelé par EDIT.

_O_VERSION

version ORACLE.

_O_RELEASE

numéro de "release" ORACLE.

On peut définir 1024 variables au maximum.

Suppression d’une variable utilisateur.

Syntaxe

UNDEF[INE] variable

Exemple

Création des variables x et _editor, visualisation des variables, suppression de x.

SQL> define x = abcdef SQL> def _EDITOR = vi SQL> DEF DEFINE _EDITOR ="vi"(CHAR) DEFINE X ="abcdef" (CHAR) SQL> undef x

Saisie d’une variable utilisateur.

Si la variable n’a pas été définie, elle est créée.

DEFINE

UNDEFINE

ACCEPT

- 1 -© ENI Editions - All rigths reserved

Page 112: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Syntaxe

ACCEPT variable [NUM/CHAR] [PROMPT texte] [HIDE]

NUM/CHAR

caractères autorisés pour la valeur de la variable (chiffres uniquement ou alphanumérique). CHAR par défaut.

PROMPT texte

affichage du texte avant la saisie.

HIDE

frappe aveugle.

Exemple

Saisie des variables V_code et V_nom :

SQL> accept V_NOM (saisie par l’utilisateur de : Dupont) SQL> accept V_CODE NUM prompt "Code ?" Code ? (saisie de : 15) SQL> def DEFINE V_NOM = "Dupont" (CHAR) DEFINE V_CODE = 15 (NUMBER) SQL>

Utilisation d’une variable de substitution.

Syntaxe

&variable

Si la variable n’existe pas, une saisie est demandée.

Exemple

Saisie de variables et utilisation dans une commande SQL :

SQL> accept NUMERO NUMBER prompt "Numero client ?" Numero client ? 15 SQL> accept NOM prompt "Nom client ?" Nom client ? TOTO SQL> def tb = clients SQL> select * from &tb where 2> Nocli > &NUMERO and 3> NOM = ’&NOM’; ancien 1 : select * from &tb where nouveau 1 : select * from client where ancien 2 : nocli > &NUMERO nouveau 2 : nocli >15 ancien 3 : NOM =’&NOM’ ; nouveau 3 : NOM =’TOTO’ ; aucune ligne sélectionnee SQL>

Permet en plus de créer la variable.

Syntaxe

&&variable

&nom

&&nom

- 2 - © ENI Editions - All rigths reserved

Page 113: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Exemple

Lorsque la requête est réexécutée, la valeur de la variable n’est pas redemandée.

SQL> select * from &&NomTab 2 / Entrez une valeur pour nomtab: LIGCDES ancien 1: select * from &&NomTab nouveau 1: select * from LIGCDES aucune ligne sélectionnée SQL> run 1* select * from &&NomTab ancien 1: select * from &&NomTab nouveau 1: select * from LIGCDES aucune ligne sélectionnée SQL>

Création d’une variable pour utilisation dans un bloc PL/SQL.

Syntaxe

VAR[IABLE] [nom [NUMBER/CHAR(n)]]

Sans paramètre, VARIABLE affiche les caractéristiques des variables existantes.

Une variable PL/SQL ne peut être valorisée que dans un bloc PL/SQL par des instructions spécifiques au PL/SQL, elle est considérée par le PL/SQL comme une variable de l’hôte (préfixée de :).

Affichage du contenu de la variable PL/SQL.

Syntaxe

PRINT variable

Exemple

SQL> var ncli number SQL> variable variable ncli type de données NUMBER SQL> begin 2 select count(*) into :ncli 3 from clients; 4 end; 5 / Procédure PL/SQL terminée avec succès. SQL> print ncli NCLI ---------- 7 SQL>

2. Présentation des résultats

Le résultat des requêtes peut être mis en forme de manière simple en utilisant des commandes SQL*Plus.

VARIABLE

PRINT

- 3 -© ENI Editions - All rigths reserved

Page 114: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Ces commandes sont généralement des déclarations qui doivent être faites avant les instructions SELECT et qui doivent être annulées ou désactivées après la requête.

a. Contrôle du déroulement des scripts

Définition d’une suspension d’exécution.

Syntaxe

PAUSE [texte]

Affichage de texte.

Syntaxe

PROMPT [texte]

b. En­tête et pied de page

Déclaration ou annulation d’un en­tête : TTITLE.

Déclaration ou annulation d’un pied de page : BTITLE

Syntaxe

BTITLE/TTITLE [option [texte/variable]]/ [OFF/ON]

Les différentes options sont :

COL n

place le texte en colonne n.

SKIP n

saute n lignes.

TAB n

saute n colonnes.

LEFT/CENTER/RIGHT

alignement.

BOLD

caractère gras.

FORMAT

format d’affichage composé de :

9 remplace un chiffre (ex. : format ’9999’ pour 4 chiffres).

0 n’affiche pas les zéros non significatifs (ex.: ’00999’).

$ est le préfixe du signe $.

B remplace les zéros non significatifs par des espaces.

MI/PR : MI affiche ­ après une valeur négative, PR affiche les valeurs négatives entre crochets.

, insère une virgule.

. positionne la marque décimale (ex. : ’999.99’ pour 3 entiers 2 décimales).

V multiplie par 10 fois le nombre de décimales.

PAUSE

PROMPT

BTITLE, TTITLE

- 4 - © ENI Editions - All rigths reserved

Page 115: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

EEEE est une notation scientifique.

DATE est le format date.

An permet un affichage sur n caractères.

Les variables prédéfinies :

SQL.PNO

page courante.

SQL.LNO

ligne courante.

SQL.RELEASE

numéro de release ORACLE.

SQL.SQLCODE

dernier code erreur.

SQL.USER

utilisateur courant.

c. Rupture

Déclaration d’action à effectuer lors d’un changement de valeur de la colonne.

Syntaxe

BREAK [ONcolonne/expression/ROW/REPORT [SKIPn/PAGE/DUPLICATES]...]

d. Format de colonne

Déclaration des attributs des colonnes sélectionnées.

Syntaxe

COLUMN [colonne/expression option]

Les différentes options sont :

ALIAS nom

nom alternatif.

LIKE alias

copie les attributs de l’alias.

CLEAR

réinitialise les attributs.

COLOR couleur

couleur d’affichage.

FOLD_AFTER

insère un retour chariot après la colonne.

BREAK

COLUMN

- 5 -© ENI Editions - All rigths reserved

Page 116: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

FOLD_BEFORE

insère un retour chariot avant la colonne.

FORMAT format

format de la valeur affichée.

HEADING texte

en­tête de colonne.

JUSTIFYLEFT/CENTER/RIGHT

justification.

NEWLINE

idem à FOLD_BEFORE.

NEW_VALUE variable

place la valeur de la colonne dans la variable pour l’afficher dans l’en­tête de page.

OLD_VALUE variable

idem à NEW_VALUE pour le pied de page.

NULL c

texte pour les valeurs nulles.

NOPRINT/PRINT

affichage ou non de la colonne.

WRAPPED/WORD_WRAPPED/TRUNCATED

césure des lignes trop longues.

OFF

désactivation de la définition.

ON

réactivation de la définition.

e. Calcul statistique

Déclaration d’un calcul à effectuer au changement de valeur de l’expression (qui doit avoir été déclarée par un BREAK).

Syntaxe

COMPUTE fonction OF expression/colonne ON expression/colonne/REPORT/ROW

Les fonctions qu’il est possible d’utiliser sont :

AVG

COMPUTE

- 6 - © ENI Editions - All rigths reserved

Page 117: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

moyenne des valeurs non nulles.

COUNT

dénombrement des valeurs non nulles.

MAXIMUM

valeur maxi.

MINIMUM

valeur mini.

NUMBER

nombre de lignes.

STD

écart type.

SUM

somme des valeurs.

VARIANCE

variance.

f. Annulation des déclarations

Syntaxe

CLEAR BREAKS/COLUMNS/COMPUTES/TIMING/BUFFER/SQL/SCREEN

3. Environnement et traitement des erreurs

Un certain nombre de paramètres d’environnement permettent de gérer le fonctionnement des commandes de mise en page. Ces paramètres sont généralement valorisés en début de script et annulés en fin de script.

a. Statistiques de temps

Syntaxe

TIMING [START texte/SHOW/STOP]

b. Traitement des erreurs

En cas d’erreurs soit du système d’exploitation, soit du SQL, SQL*Plus les ignore, ce qui peut être gênant dans des enchaînements de commandes ou pour l’intégrité des données.

La déclaration WHENEVER permet de prévenir ces erreurs.

CLEAR

TIMING

WHENEVER

- 7 -© ENI Editions - All rigths reserved

Page 118: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Syntaxe

WHENEVER OSERROR/SQLERROR EXIT[SUCCESS/ FAILURE/OSCODE/"][COMMIT/ROLLBACK]/CONTINUE [COMMIT/ROLLBACK/NONE]

EXIT

Sort de SQL*Plus en envoyant le code erreur spécifié.

CONTINUE

Ne sort pas de SQL*Plus.

COMMIT ou ROLLBACK

Force une validation ou une annulation avant de sortir ou de continuer.

NONE

Ne fait rien avant de sortir ou de continuer.

c. Paramètres d’environnement

Paramètres liés à l’affichage.

Syntaxe

SET parametre valeur

DEFINE ’&’/c/ON/OFF

caractère utilisé pour les substitutions de variables.

EMBEDDED OFF/ON

chaque rapport débute sur une nouvelle page.

HEADSEP |/c/ON/OFF

caractère définissant un en­tête de colonne multiligne.

LINESIZE 80/n

nombre de caractères par ligne.

NEWPAGE 1/n/NONE

nombre de lignes entre le début de page et l’en­tête défini.

NUMFORMAT format

format par défaut des numériques.

NUMWIDTH 10/n

taille par défaut des numériques.

PAGESIZE 14/n

nombre de lignes entre l’en­tête et le bas de page.

SET

- 8 - © ENI Editions - All rigths reserved

Page 119: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

SCAN ON/OFF

contrôle la présence des variables de substitution.

SHOWMODE ON/OFF

affichage des valeurs des variables en cas de changement.

TAB OFF/ON

utilisation des tabulations.

TIME OFF/ON

affichage de l’heure avant chaque commande.

TIMING OFF/ON

affichage des statistiques de temps.

TRIMOUT ON/OFF

suppression des espaces en fin de ligne.

UNDERLINE ­/c/ON/OFF

caractère de soulignement.

VERIFY ON/OFF

liste la commande avant son exécution.

WRAP ON/OFF

césure des lignes.

La commande SET possède de nombreuses autres options mais seules les plus courantes sont documentées dans cet ouvrage.

Exemple

Script de mise en page, extraction et sauvegarde dans un fichier (confcde.lis) d’une confirmation de commande dont le numéro est saisi par l’utilisateur.

rem Edition de la confirmation d’une commande rem Environnement set echo off set feed off set pagesize 60 set newpage 0 set linesize 80 rem Saisie du numero de commande accept VCDE number prompt ’No de commande à éditer ? ’ rem Mise en page set term off column REFART heading "Reference|article" column DESIGNATION heading "Désignation" column PRIXUNITHT heading "Prix H.T." column QTECDE heading "Qté cde."

- 9 -© ENI Editions - All rigths reserved

Page 120: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

column NOCDE noprint new_value VNOCDE column NOMCLIENT noprint new_value VNOM break on NOCDE skip page compute sum of Mt on NOCDE ttitle center "Confirmation de commande" - skip 2 left "Numero : " VNOCDE - skip 1 left "Client : " VNOM skip 3 btitle tab 40 "Page " sql.pno spool confcde.lis rem Extraction select COMMANDES.NOCDE,NOMCLIENT,LIGNESCDE.REFART,DESIGNATION, PRIXUNITHT,QTECDE,PRIXUNITHT*QTECDE "Mt" from COMMANDES,LIGNESCDE,CLIENTS,ARTICLES where COMMANDES.NOCDE = &VCDE and COMMANDES.NOCLIENT = CLIENTS.NOCLIENT and COMMANDES.NOCDE = LIGNESCDE.NOCDE and LIGNESCDE.REFART = ARTICLES.REFART / spool out rem Annulation de la mise en page ttitle off btitle off clear breaks clear columns clear compute set pagesize 14 set newpage 1 set feed on set echo on set term on

Résultat du script précédent si N° de commande saisi est 1210 :

Confirmation de commande Numero : 1210 Client : DUPONT S.A. Reference article Désignation Prix H.T. Qté cde. Mt ---------- ----------------- ----------- --------- ------- AB10 Tapis de Chine 1500 3 4500 CD50 Chaîne HIFI 735,4 4 2941,6 ------- 7441,6 Page 1

4. Création d’un rapport au format HTML

SQL*Plus offre la possibilité de créer un rapport au format HTML en utilisant les commandes SET MARKUP et SPOOL. Les informations du rapport sont insérées à l’intérieur du tag HTML <PRE>, et donc l’affichage au sein de l’explorateur internet est exactement le même que celui perçu dans SQL*Plus.

Syntaxe

SET MARK[UP] HTML [ON|OFF] [HEAD ’texte’] [BODY ’texte’] [ENTMAP ON|OFF] [SPOOL ON|OFF] [PRE[FORMAT]ON|OFF]

- 10 - © ENI Editions - All rigths reserved

Page 121: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Les choix par défaut des options sont soulignés.

La commande MARKUP est compatible avec HTML 3.2.

La commande SET MARKUP permet à SQL*Plus de générer un résultat au format HTML et non plus au simple format texte. L’intérêt de fournir directement les données au format HTML n’est plus à démontrer car ce format permet une présentation simple à mettre en place et soignée tout en restant indépendante de l’outil utilisé pour visualiser le résultat.

Les différents paramètres de cette commande sont :

HTML

(OFF par défaut) Positionner à ON la valeur de cette option permet d’activer la génération des résultats au format HTML.

HEAD

Permet de personnaliser l’en­tête de la page HTML comme par exemple le fait de définir un titre à l’aide des balises <TITLE> et </TITLE>. C’est également à cet endroit que l’on pourra définir les styles à appliquer aux différentes balises.

BODY

L’option BODY permet de définir les attributs de la balise BODY. Par défaut aucun attribut n’est sélectionné mais il est toujours possible de le faire par cette option.

TABLE

Permet de spécifier les attributs du tableau. Par défaut, le tableau est défini comme possédant une largeur de 90% (WIDTH=’90%’) et la largeur de la bordure est fixée à 1 (border=’1’).

ENTMAP

(ON par défaut) Positionner à OFF la valeur de cette option permet d’interpréter les caractères HTML correctement, ce qui peut être le cas pour <, >," et &. Avec cette précaution, ces caractères ne sont pas remplacés par leur entité respective &lt, &gt,&quot et &amp.

SPOOL

(OFF par défaut) Positionner à ON la valeur de cette option permet d’ajouter les balises <HTML> et <BODY> ainsi que les balises fermant correspondant en début et fin de fichier. Ce paramètre n’est en aucun cas équivalent à la commande SPOOL qui permet de rediriger les informations affichées à l’écran vers un fichier.

PREFORMAT

(OFF par défaut) indique à SQL*Plus que les résultats sont présentés sous forme de tableau. Positionner à ON la valeur de cette option permet de préciser les informations indiquées après une balise <PRE>.

Afin de présenter au mieux le script SQL*Plus qui contient la commande SET MARKUP, il est fortement recommandé de saisir cette commande sur plusieurs lignes en prenant soin de ne pas oublier le caractère de

continuation (­) des instructions SQL*Plus.

Le script ci­dessous illustre comment il est possible de produire un résultat au format HTML depuis SQL*Plus.

rem Exemple de génération de rapport en HTML set echo on set markup html on spool on entmap on - head "<TITLE>Les commandes</TITLE> - <STYLE type=’text/css’> - <!-- BODYbackground:#FFFFC6 --> - </style>"- BODY "TEXT=’#FF00FF’" - TABLE "BORDER=’2’" - preformat off column nocde heading ’N°’ column nocli heading ’Client’ column datecde heading ’Date’

- 11 -© ENI Editions - All rigths reserved

Page 122: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

column etatcde heading ’Etat’ format A4 spool test.html select nocde, nocli, datecde, etatcde from commandes; spool off set markup html off spool off

L’exécution de ce script donne le résultat suivant :

SQL> select nocde, nocli, datecde, etatcde from commandes; N° Client Date Etat 100 15 23/07/02 EC 1301 15 22/07/02 EC 1210 15 20/07/02 SO 1250 35 19/07/02 EC 1230 35 18/07/02 SO SQL> spool off

- 12 - © ENI Editions - All rigths reserved

Page 123: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Introduction

1. Qu’est­ce que le PL/SQL ?

Le PL/SQL est le langage procédural d’ORACLE. Il constitue une extension au SQL qui est un langage ensembliste.

L’intérêt du PL/SQL est de pouvoir mélanger la puissance des instructions SQL avec la souplesse d’un langage procédural dans un même traitement.

Ces traitements peuvent être exécutés, soit directement par les outils ORACLE (blocs anonymes), soit à partir d’objets de la base (procédures stockées et PACKAGES).

Les avantages du PL/SQL sont multiples :

Intégration du SQL : les instructions du DML, du transaction control et les fonctions SQL peuvent être utilisées avec pratiquement la même syntaxe.

Traitements procéduraux : la gestion des variables et les structures de contrôle (test, boucles) accroissent les possibilités de gestion des données.

Fonctionnalités supplémentaires : la gestion des curseurs et le traitement des erreurs offrent de nouvelles possibilités de traitements.

Amélioration des performances : plusieurs instructions sont regroupées dans une unité (bloc) qui ne génèrera qu’un "accès" à la base (à la place d’un accès par instruction).

Incorporation aux produits ORACLE : les blocs ou procédures PL/SQL sont compilés et exécutés par le "moteur" PL/SQL. Ce moteur est directement intégré au moteur de la base de données ainsi qu’à certains outils Oracle : Oracle*Forms, Oracle*Report.

2. Instructions SQL intégrées dans PL/SQL

Ces instructions sont utilisables avec pratiquement la même syntaxe qu’en SQL.

La partie interrogation : SELECT.

La partie manipulation : INSERT, UPDATE, DELETE.

La partie gestion des transactions : COMMIT, ROLLBACK, SAVEPOINT...

Les fonctions TO_CHAR, TO_DATE, UPPER, SUBSTR, ROUND...

3. Instructions spécifiques au PL/SQL

Les caractéristiques procédurales de PL/SQL apportent les possibilités suivantes :

la gestion des variables (déclaration, valorisation, utilisation),

les structures de contrôle (séquence, test, boucles).

Des fonctionnalités supplémentaires sont disponibles :

la gestion des curseurs (traitement du résultat d’une requête ligne par ligne),

les traitements d’erreurs (déclaration, action à effectuer).

- 1 -© ENI Editions - All rigths reserved

Page 124: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

4. Le bloc PL/SQL

PL/SQL n’interprète pas une commande, mais un ensemble de commandes contenues dans un "bloc" PL/SQL. Ce bloc est compilé et exécuté par le moteur PL/SQL du produit ou de la base.

Un bloc est composé de trois sections.

DECLARE (déclaration des variables, des constantes, des exceptions et des curseurs) BEGIN [nom du bloc] (instruction SQL, PL/SQL, structures de contrôle) EXCEPTION (traitement des erreurs) END [nom du bloc] ;

Il est possible d’ajouter des commentaires à un bloc :

­­

permet de mettre en commentaire ce qui suit sur la ligne.

/*... ... */

permet de mettre en commentaire plusieurs lignes.

Des étiquettes (label) permettent de marquer des parties de bloc, sous la forme <<nometiquette>>.

La section DECLARE qui permet de déclarer les variables qui vont être utilisées dans le bloc PL/SQL n’est nécessaire que si le bloc a besoin de définir des variables. De même, la section EXCEPTION ne sera présente que dans les blocs qui vont gérer les erreurs.

Structure d’un bloc PL/SQL

- 2 - © ENI Editions - All rigths reserved

Page 125: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Gestion des variables

Les variables sont des zones mémoires nommées permettant de stocker une valeur.

En PL/SQL, elles permettent de stocker des valeurs issues de la base ou de calculs, afin de pouvoir effectuer des tests, des calculs ou des valorisations d’autres variables ou de données de la base.

Les variables sont caractérisées par :

leur nom, composé de lettres, chiffres, $, _ ou # . Un maximum de 30 caractères est possible. Ce ne doit pas être un nom réservé.

leur type, qui détermine le format de stockage et d’utilisation de la variable.

Les variables doivent être obligatoirement déclarées avant leur utilisation.

Comme SQL, PL/SQL n’est pas sensible à la casse. Les noms des variables peuvent donc être saisis indifféremment en minuscules ou en majuscules.

1. Variables locales

PL/SQL dispose de l’ensemble des types utilisables dans la définition des colonnes des tables dans le but de faciliter les échanges de données entre les tables et les blocs de code. Cependant, les étendues des valeurs possibles pour chacun de ces types peuvent être différentes de celles du SQL.

Il dispose également d’un certain nombre de types propres, principalement pour gérer les données numériques.

Enfin, PL/SQL permet de définir des types complexes basés soit sur des structures issues des tables, soit sur des descriptions propres à l’utilisateur.

Syntaxe

nom-de-variable [CONSTANT] type [[NOT NULL]:=expression] ;

CONSTANT

La valeur de la variable n’est pas modifiable dans le code de la section BEGIN.

NOT NULL

Empêche l’affectation d’une valeur NULL à la variable, expression doit être fournie.

expression

Valeur initiale affectée à la variable lors de l’exécution du bloc.

Déclaration

- 1 -© ENI Editions - All rigths reserved

Page 126: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

2. Types prédéfinis

a. Types caractères

CHAR[(n)]

Chaîne de caractères de longueur fixe avec n compris entre 1 et 32767. Si aucune taille maximale n’est précisée alors la valeur utilisée par défaut est 1. Il faut également garder présent à l’esprit que la longueur maximale d’une colonne de type CHAR est 2000, et il est donc impossible d’insérer une valeur de plus de 2000 caractères dans une telle colonne.

VARCHAR2[(n)]

Chaîne de caractères de longueur variable avec n compris entre 1 et 32767 et représentant le nombre maximum d’octets alloués à la variable. Il faut également considérer que la longueur maximale d’une colonne de type VARCHAR2 est 4000 octets, et il est donc impossible d’insérer une valeur de plus de 4000 caractères dans une telle colonne.

LONG

Chaîne de caractères de longueur variable comprenant au maximum 32760 octets.

RAW[(n)]

Chaîne de caractères ou données binaires de longueur variable avec n compris entre 1 et 32767. Le contenu d’une variable de ce type n’est pas interprété par PL/SQL (pas de gestion des caractères nationaux).

LONG RAW

Identique au type LONG, mais PL/SQL n’en interprète pas le contenu.

En règle générale, un octet suffit à coder tous les caractères présents dans une langue. Mais certaines langues comme le japonais, le chinois... possèdent trop de caractères pour pouvoir tous les coder sur un octet. Oracle offre donc une solution pour coder ces caractères sur plusieurs octets. Le nombre d’octets dépend de la langue fixée au moyen de NLS (National Language Service).

- 2 - © ENI Editions - All rigths reserved

Page 127: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

NCHAR[(n)]

Chaîne de caractères de longueur fixe. N compris entre 1 et 32767.

NVARCHAR2[(n)]

Chaîne de caractères de longueur variable. N compris entre 1 et 32767.

Le nombre de caractères effectivement stockés dépend du nombre d’octets utilisés pour coder chaque caractère dans le jeux de caractères choisi.

UROWID, ROWID

Permet de définir des variables dont la valeur représente l’adresse absolue de stockage d’une ligne d’une table sous forme d’une chaîne de caractères.

Les valeurs de type ROWID sont composées de la façon suivante : OOOOOOFFFBBBBBBRRR et se décomposent en quatre parties :

OOOOOO

Permet de connaître le numéro de l’objet qui possède cette ligne. En effet, il est nécessaire de connaître l’objet qui possède la ligne d’information car, dans le cas de cluster, plusieurs objets peuvent partager le même segment.

FFF

Le numéro du fichier qui contient la ligne d’information. Le numéro de fichier est unique dans la base de données.

BBBBBB

Le numéro du bloc qui contient la ligne d’information. Le numéro du bloc est relatif au fichier et non pas au tablespace.

RRR

Permet de connaître le numéro de la ligne dans le bloc.

Le type de données ROWID est maintenu pour des raisons de compatibilité avec les applications existantes. Les nouveaux développements doivent utiliser le type UROWID.

b. Types numériques

NUMBER[(p,s)]

Nombres réels avec p chiffres significatifs stockés et un arrondi à droite de la marque décimale à s chiffres.

BINARY_INTEGER

Nombre entier compris entre ­2 147 483 647 et +2 147 483 647.

PLS_INTEGER

Nombre entier compris entre ­2 147 483 647 et +2 147 483 647.

Les variables de type PLS_INTEGER et BINARY_INTEGER nécessitent moins d’espace mémoire que celles de type NUMBER. Les variables de type PLS_INTEGER permettent des calculs plus rapides que celles de type BINARY_INTEGER.

c. Types pour les grands objets

Les variables déclarées avec les types suivants permettent de stocker des données non structurées (dont la structure n’est pas gérée par PL/SQL) de grande taille.

BFILE

- 3 -© ENI Editions - All rigths reserved

Page 128: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Permet de stocker la référence vers un fichier du système d’exploitation qui contient physiquement les données.

BLOB

Permet de stocker un objet binaire jusqu’à 4 Go.

CLOB

Permet de stocker un ensemble de caractères, codés sur un octet, jusqu’à 4 Go.

NCLOB

Permet de stocker un ensemble de caractères, codés sur un octet ou plusieurs octets, jusqu’à 4 Go.

d. Autres types

BOOLEAN

Stocke des valeurs logiques TRUE, FALSE ou la valeur NULL.

DATE

Stocke une date dans un format de longueur fixe. La plage de date valide va du 1er janvier 4712 avant JC au 31 décembre 9999 après JC.

TIMESTAMP

Permet d’étendre le type DATE en conservant des fractions de secondes en plus des informations de type année, mois, jour, heure, minute et seconde. Par défaut, la précision des fractions de secondes est exprimée sur 6 chiffres mais elle peut s’étendre de 0 à 9 chiffres.

e. Sous­Types

PL/SQL propose des sous­types synonymes des types donnés ci­dessus. Ces sous­types permettent d’assurer la compatibilité avec les types standards ANSI/ISO et IBM.

3. Types définis par l’utilisateur

PL/SQL autorise la définition de nouveaux types propres à une application. Ces types structurés permettent de définir des variables qui regroupent sous un nom plusieurs valeurs de même type ou de type différent.

Pour chaque type de données il existe une plage des valeurs possibles et un ensemble d’opérations qui travaillent avec ce type de données. Les sous­ types permettent d’utiliser les mêmes opérations mais la plage des valeurs possibles est réduite. On peut donc dire que les sous­types n’introduisent pas de nouveaux types de données mais ils permettent au contraire de poser des contraintes sur des types de données existants.

Le but des sous­types est de simplifier l’écriture et la compréhension du programme en utilisant des noms de types de données déjà connus par le programmeur ou utilisés dans l’entreprise. Par exemple, le type de données CHARACTER est un sous­type de CHAR pour que le langage PL/SQL respecte la norme ANSI.

Après la définition des sous­types dans la section DECLARE du bloc PL/SQL, il est possible d’y définir des variables de la même façon que sur des types de base.

Type ORACLE Sous­types

NUMBER DEC, DECIMAL, NUMERIC, DOUBLE PRECISION, FLOAT, REAL INTEGER, INT, SMALLINT

BINARY_INTEGER NATURAL, NATURALN, POSITIVE, POSITIVEN, SIGNTYPE

VARCHAR2 STRING, VARCHAR

CHAR CHARACTER

- 4 - © ENI Editions - All rigths reserved

Page 129: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Syntaxe

SUBTYPE nom_sous_type IS type;

Exemple

Définition et utilisation d’un sous­type : déclaration du sous­type date­naissance et utilisation dans un bloc PL/SQL.

4. Collections et enregistrements

Les collections et les enregistrements ont pour but de faciliter la programmation en PL/SQL. Ces types de données n’existent qu’en PL/SQL et ne trouvent pas leur équivalent dans la base Oracle. Il n’est pas possible de stocker un enregistrement directement dans la base mais par contre, il est tout à fait possible de stocker chaque élément qui compose l’enregistrement dans la base.

a. Les collections

Une collection est un ensemble ordonné d’éléments de même type. Une collection peut être comparée aux tableaux qu’il est possible de définir dans certains langages de programmation mais à cette différence que les collections ne peuvent avoir qu’une seule dimension et que les éléments de la collection sont indexés par une valeur de type numérique.

Parmi les collections il faut distinguer deux types différents : les tables (TABLE) qui sont de type index by table ou nested table (qui étend les fonctionnalités offertes par les tables de type index) et les tableaux de type VARRAY.

Après la déclaration, les collections doivent être initialisées. Pour cela, il existe une fonction particulière, nommée constructeur, qui porte le même nom que la collection et qui accepte en paramètres les valeurs que contient initialement la collection. Attention, ce constructeur n’est pas appelé implicitement par Oracle.

Ces collections sont de taille dynamique et il n’existe pas forcément de valeurs pour toutes les positions.

Les collections

Comme le montre le schéma ci­dessus, les collections sont beaucoup plus souples que les tableaux, car il est possible de supprimer des éléments particuliers de la collection.

Les collections de type nested table présentent la particularité que les données qu’elles contiennent peuvent être stockées directement dans une colonne de table, d’où leur nom. De plus, les collections non initialisées sont NULL.

Les collections de type index­by table représentent quant à elle la méthode la plus rapide pour transférer des données entre un bloc PL/SQL et la base de données.

Syntaxes

Déclaration d’une collection de type nested table

Les collections de type nested table et Index by table

- 5 -© ENI Editions - All rigths reserved

Page 130: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

TYPE nom_type IS TABLE OF type_element [NOT NULL]

Déclaration d’une collection de type index­by table

TYPE nom_type IS TABLE OF type_element [NOT NULL] INDEX BY BINARY_INTEGER

Exemple

Déclaration et utilisation de collections : dans l’exemple ci­après, deux collections sont définies puis sont utilisées pour valider leur définition (l’utilisation des collections sera détaillée ultérieurement dans ce chapitre).

Une collection de type VARRAY possède une dimension maximale qui doit être précisée lors de la déclaration de la collection. Ces collections possèdent une longueur fixe et donc la suppression d’éléments ne permet pas de gagner de la place en mémoire. Les éléments sont numérotés à partir de la valeur 1.

Syntaxe

TYPE nom_type IS VARRAY (taille_maxi) OF type_element [NOT NULL]

nom_type

représente le nom de la collection.

taille_maxi

représente le nombre maximum d’éléments présents dans la collection.

type_element

représente le type de données des éléments qui constituent la collection.

Exemple

Déclaration et utilisation de collections : dans l’exemple suivant, une collection nommée Calendrier est définie.

Les collections de type VARRAY

- 6 - © ENI Editions - All rigths reserved

Page 131: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

b. Les enregistrements

Un enregistrement est un ensemble de valeurs liées entre elles et regroupées sous un même nom. Chaque valeur est stockée dans un champ. Par exemple, l’enregistrement qui permet de manipuler un client sera composé des champs numéro, nom, adresse... Les enregistrements représentent donc un moyen simple de manipuler les informations qui sont liées entre elles.

Pour pouvoir créer un enregistrement, il est nécessaire au préalable, de définir le type d’enregistrement dans la section DECLARE du bloc PL/SQL.

Un RECORD est un regroupement d’éléments de types différents logiquement liés entre eux et désignés par un nom unique.

Syntaxe

TYPE nom_type IS RECORD ([nom_champs type_champs[[NOT NULL] : =expression ] [, ...]) ; nom_variable nom_type ;

type_champs correspond à un type PL/SQL défini plus haut.

Les champs d’une variable de type RECORD peuvent être référencés à l’aide de l’opérateur "." : Nom_variable.nom_champs

Exemple

Définition d’un RECORD client reprenant les informations relatives à un client :

SQL> declare 2 type T_CLIREC is record ( 3 NOCLI number(4), 4 NOM char(20), 5 ADR char(20), 6 CODPOST number(5)); 7 UNCLIENT T_CLIREC ; 8 begin 9 -- Instructions 10 UNCLIENT.NOCLI := 1024; 11 -- Instructions 12 end; 13 / Procédure PL/SQL terminée avec succès. SQL>

Record

- 7 -© ENI Editions - All rigths reserved

Page 132: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Comme pour la déclaration des variables, il est possible d’initialiser les champs lors de leur déclaration et de les rendre obligatoires ou non.

5. Types dérivés

À la déclaration d’une variable, on peut faire référence à une entité existante : colonne, table, curseur ou variable. Ceci est intéressant pour des raisons de simplification d’écriture et d’évolutivité des structures de données.

L’attribut %TYPE permet de référencer soit une colonne d’une table, soit une variable précédemment définie.

Syntaxe

nom-de-variable nomdetable.nomdecolonne%TYPE;

ou

nom-de-variable2 nomdevariable1%TYPE;

Exemple

-- Déclaration d’une variable de même type que le nom client. DECLARE V_nom FLORIAN.CLIENTS.NOMCLI%TYPE ; -- Déclaration de deux variables de même type. x NUMBER(10,3) ; y x%TYPE ;

On peut référencer des structures entières de table ou de curseur afin de créer des variables qui seront composées de la même structure.

Syntaxe

nom-de-variable nom de table | nom de curseur %ROWTYPE ;

Exemple

-- Déclaration d’une variable pouvant recevoir une ligne entière de la table ARTICLES. DECLARE LIGART ARTICLES%ROWTYPE ; -- A l’utilisation on pourra prendre le nom simple SELECT * INTO LIGART ; -- ou prendre le nom en combinaison avec la colonne x := LIGART.prixht * 1.1 ;

6. Variables définies dans un environnement extérieur à PL/SQL

Ces variables sont déclarées en dehors du bloc et utilisables dans le bloc.

Ce sont des champs d’écran créés dans Oracle*Forms, ou des variables définies en langage hôte par les précompilateurs ou par SQL*Plus (ces variables sont toujours préfixées de ":" dans un bloc PL/SQL).

Exemple

Utilisation d’une variable de lien SQL*Plus (x) :

SQL> variable x NUMBER SQL> define t = CLIENTS SQL> Begin 2> select COUNT(*) INTO :x from &t ; 3> end ;

%TYPE

%ROWTYPE

- 8 - © ENI Editions - All rigths reserved

Page 133: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

4> / Procédure PL/SQL terminée avec succès SQL> print x x 15 SQL>

7. Utilisation des variables

Les variables sont utilisées soit pour leur affecter une valeur, soit en tant qu’expression dans les tests ou les modifications de données.

a. Affectation de valeur

Plusieurs possibilités de valorisation de variables sont possibles.

L’affectation directe de valeur.

Syntaxe

nom de variable := expression ;

L’expression peut être soit une constante, soit une variable, soit un calcul portant sur des constantes et des variables.

Les opérateurs de calcul sont les suivants :

opérateurs arithmétiques + ; ­ ; * ; / ; **(exponentiation)

opérateur de concaténation ||

On peut utiliser les parenthèses pour grouper les calculs.

L’écriture des constantes suit les mêmes règles qu’en SQL.

Exemple

Valorisation de variables (dans la section BEGIN) :

x := 0 ; Vnom := ’Monsieur’|| Vnom ; y := (x + 5) * y ;

La clause INTO des instructions SELECT et FETCH du PL/SQL permet la valorisation des variables à partir d’une ligne issue d’une requête (et une seule).

Syntaxe

SELECT * | liste d’expression INTO liste de variable FROM ... ; FETCH nom curseur INTO liste de variables ;

Exemple

Valorisation de variables à partir de tables de la base :

DECLARE Vref CHAR(10) ; Vprix ARTICLES.PRIXHT%TYPE ; Cli CLIENTS%ROWTYPE ; BEGIN select REFART, PRIXHT into Vref, Vprix from Articles where DESIGNATION = ’Cadeau’ ; select * into Cli from CLIENTS where NOCLI = 10 ;

:=

INTO

- 9 -© ENI Editions - All rigths reserved

Page 134: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

b. Utilisation

Les valeurs stockées dans les variables peuvent être utilisées en tant qu’expression dans les commandes SQL ou PL/SQL.

Exemple

Modification de la table CLIENTS à partir des valeurs de variables :

DECLARE Vnocli CLIENTS.NOCLI%TYPE := 10 ; Vnom CLIENTS.NOM%TYPE ; BEGIN Vnom := ’Dupont’ ; UPDATE CLIENTS SET NOM = Vnom where NOCLI = Vnocli ; Vnocli := Vnocli + 1 ; INSERT INTO CLIENTS (NOCLI, NOM) VALUES (Vnocli, Vnom) ; COMMIT ; END ;

c. Visibilité

Une variable est visible dans le bloc où elle a été déclarée, et dans les blocs imbriqués si elle n’a pas été redéfinie.

Exemple

Test de la visibilité des variables dans des blocs PL/SQL imbriqués :

8. Variables structurées et instruction du DML

Il est possible d’utiliser une variable de type structuré dans une opération INSERT pour ajouter des données dans une table de la base depuis un bloc PL/SQL.

Exemple

L’exemple ci­dessous montre la mise en place de cette possibilité depuis le bloc PL/SQL. La variable structurée vcli est composée de champs. Chacun de ces champs est destiné à recevoir une valeur d’une colonne de la table CLIENTS. Les différents champs sont renseignés puis cette variable est utilisée directement dans la commande INSERT.

- 10 - © ENI Editions - All rigths reserved

Page 135: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

declare vcli clients%rowtype; begin -- renseigner les différents champs de la variable structurée vcli.nocli :=100; vcli.nomcli :=’MOORE’; vcli.adrcli :=’13 rue de la croissance’; vcli.code_postal:=’69004’; vcli.ville:=’LYON’; -- insérer ces données ds la table des clients insert into clients values vcli; end; /

Le travail avec les variables structurées est également possible pour les opérations de mise à jour avec les instructions UPDATE. Pour cela, la variable structurée doit contenir un champ pour chaque colonne de la table et c’est donc la totalité de la ligne qui est mise à jour d’un coup. La commande UPDATE utilise alors l’instruction SET ROW= variable composée.

Exemple

-- script pour la mise à jour à partir d’une variable structuré declare vcli clients%rowtype; begin -- initialiser la variable vcli select * into vcli from clients where nocli=100; -- mettre à jour les données vcli.nomcli:=’Newton’; -- mise à jour des informations dans la base update clients set row=vcli where nocli=100; end; /

L’instruction SET ROW n’accepte pas le résultat d’une sous­requête.

Il est parfois nécessaire d’aller lire les données nouvellement insérées, supprimées ou mises à jour. L’opération habituelle consiste à utiliser un ordre SELECT pour connaître la valeur des colonnes après mise à jour. Il est maintenant possible de demander aux instructions INSERT, UPDATE ou DELETE de retourner la valeur des colonnes nouvellement mises à jour par l’intermédiaire de la clause RETURNING. Bien sûr, il est possible d’utiliser cette clause uniquement si la commande SQL DML a porté sur exactement une ligne de données.

Exemple

L’exemple suivant permet de connaître la valeur du prix d’un article après son augmentation de 10%.

declare type rec_art_info is record( refart char(4), prix number(8,2) ); art_info rec_art_info; begin update articles set prix=prix*1.1 where refart=’AB01’ returning refart, prix into art_info; -- art_info contient les valeurs après mise à jour end; /

- 11 -© ENI Editions - All rigths reserved

Page 136: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Structures de contrôle

Les structures de contrôle permettent de choisir la façon dont les différentes instructions vont être exécutées.

Les trois structures de contrôles sont :

la séquence : exécution d’instructions les unes après les autres.

l’alternative : exécution d’instructions en fonction d’une condition.

la répétitive : exécution d’instructions plusieurs fois en fonction d’une condition.

1. Traitements conditionnels

Il permet l’exécution d’instructions en fonction du résultat d’une condition.

Syntaxe

If

- 1 -© ENI Editions - All rigths reserved

Page 137: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

IF condition1 THEN traitement1; [ELSIF condition2 THEN traitement2;] [ELSE traitement3;] [END IF;]

Les opérateurs utilisés dans les conditions sont les mêmes que dans SQL :

=; <, >, !, >=, <=, IS NULL, IS NOT NULL, BETWEEN, LIKE, AND, OR, etc.

Exemple

Si le client 10 est en cours de traitement, on le met à jour sinon on annule la transaction :

if Vnocli = 10 THEN UPDATE CLIENTS SET NOM = ’Dupont’ where NOCLI = Vnocli ; COMMIT ; else ROLLBACK ; end if ;

L’instruction CASE permet une exécution conditionnelle comme l’instruction IF. Cependant, cette instruction CASE est particulièrement bien adaptée aux conditions comportant de nombreux choix différents. Elle permet une présentation plus lisible du code, donc moins de risque d’erreur. De plus, l’utilisation du CASE est susceptible d’améliorer les performances au cours de l’exécution.

Syntaxe

[<<étiquette>>] CASE element_de_selection WHEN valeur1 THEN instructions1; WHEN valeur2 THEN instructions2; ... [ELSE instructions;] END CASE [étiquette]; [<<étiquette>>] CASE WHEN condition1 THEN instructions1; WHEN condition2 THEN instructions2; ... [ELSE instructions;] END CASE [étiquette];

La condition ELSE est optionnelle et elle n’est exécutée que si aucune des conditions WHEN précédentes n’est exécutée. En l’absence de définition de la condition ELSE, PL/SQL ajoute implicitement la condition ELSE suivante :

ELSE RAISE CASE_NOT_FOUND;.

L’instruction CASE peut se présenter sous deux formes : dans un premier cas, soit la valeur à tester suit immédiatement le CASE et c’est alors un test d’égalité qui est fait avec chaque valeur suivant les instructions WHEN pour déterminer s’il faut ou non exécuter les instructions PL/SQL associées. Dans sa deuxième forme, chaque instruction WHEN est suivie d’une condition, et c’est l’évaluation de cette condition à vraie qui permet d’exécuter les instructions associées PL/SQL.

Dans tous les cas, les instructions WHEN sont évaluées de façon séquentielle et seule la première évaluée à vraie est exécutée.

Exemples

L’exemple suivant permet de comparer la valeur contenue dans la variable département avec chacune des valeurs qui suit le WHEN.

declare departement number:=44; libelle varchar2(40); begin case departement when 44 then libelle:=’Loire Atlantique’; when 49 then libelle:=’Maine et Loire’; when 53 then libelle:=’Mayenne’;

CASE

- 2 - © ENI Editions - All rigths reserved

Page 138: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

when 72 then libelle:=’Sarthe’; when 85 then libelle:=’Vendée’; else libelle:=’Hors Region’; end case; end; /

Dans l’exemple ci­dessous la condition de chaque instruction WHEN est évaluée pour savoir s’il est nécessaire d’exécuter ou non les instructions placées dernière le mot clé THEN.

declare departement number:=44; region varchar2(40); begin case when departement in (18,28,36,37,41,45) then region:=’Centre’; when departement in (75,77,78,91,92,93,94,95) then region:=’Ile de France’; when departement in (44,49,53,72,85) then region:=’Pays de la loire’; end case; end; /

Ce dernier exemple, permet de mettre en évidence la possibilité d’imbriquer les instructions CASE les unes dans les autres. Avec ce type d’imbrication, il faut prendre en compte les problèmes de clarté du code.

set serveroutput on declare departement number:=44; region varchar2(80); libelle varchar2(80); begin case when departement in (18,28,36,37,41,45) then region:=’Centre’; when departement in (75,77,78,91,92,93,94,95) then region:=’Ile de France’; when departement in (44,49,53,72,85) then region:=’Pays de la loire’; case departement when 44 then libelle:=’Loire Atlantique’; when 49 then libelle:=’Maine et Loire’; when 53 then libelle:=’Mayenne’; when 72 then libelle:=’Sarthe’; when 85 then libelle:=’Vendée’; else libelle:=’Hors Region’; end case; end case; dbms_output.put_line(’region:’||region); end; /

2. Traitements répétitifs

Ce sont des ensembles d’instructions écrites une seule fois et exécutées à plusieurs reprises.

PL/SQL permet d’effectuer des traitements répétitifs grâce à la clause LOOP.

Utilisé seul, LOOP initialise des boucles sans fin et systématiques.

Syntaxe

[<<LABEL>>] LOOP

LOOP

- 3 -© ENI Editions - All rigths reserved

Page 139: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

instructions; ....... END LOOP [LABEL] ;

Sortie de la boucle par la commande :

EXIT [LABEL] [WHEN condition]

où LABEL est le nom de la boucle et condition la condition qui doit être vraie pour la sortie.

Exemple

Insertion de 10 lignes dans CLIENTS :

x := 0 ; <<INCREMENTATION>> LOOP x := x + 1 ; exit INCREMENTATION when x > 10 ; insert into CLIENTS (NOCLI) VALUES (x) ; END LOOP INCREMENTATION ; COMMIT ;

La boucle FOR permet d’exécuter les instructions de la boucle en faisant varier un indice.

Les instructions sont exécutées autant de fois que l’indice change de valeur.

L’indice peut être utilisé dans les instructions comme une variable (en lecture).

Syntaxe

[<<LABEL>>] FOR indice IN [REVERSE] exp1..exp2 LOOP instructions; .... END LOOP [LABEL];

L’indice est déclaré implicitement.

exp1, exp2 sont des constantes, expressions ou variables.

Sans l’option REVERSE, indice varie de exp1 à exp2 avec un incrément de 1.

Avec l’option REVERSE, indice varie de exp2 à exp1 avec un incrément de ­1.

Exemple

Création de 10 clients avec numéros successifs :

FOR n IN 100..110 LOOP insert into CLIENTS (NOCLI) values (n) ; END LOOP ; COMMIT ;

L’entrée dans la boucle se fait si la condition est vraie.

Les instructions sont ensuite exécutées tant que cette condition reste vraie.

Syntaxe

[<<LABEL>>] WHILE condition LOOP instructions; ...... END LOOP [LABEL];

La condition est une combinaison d’expressions au moyen d’opérateurs :

<, >, =, !=, AND, OR, LIKE,..

FOR

WHILE

- 4 - © ENI Editions - All rigths reserved

Page 140: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Exemple

Création de 11 clients consécutifs :

x := 200 ; while x <= 210 LOOP insert into CLIENTS (NOCLI) values (x) ; x := x + 1 ; end loop ; COMMIT ;

- 5 -© ENI Editions - All rigths reserved

Page 141: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Utilisation des curseurs

1. Définition

Le curseur est une zone de mémoire de taille fixe, utilisé par le moteur de la base Oracle pour analyser et interpréter tout ordre SQL.

Les statuts d’exécution de l’ordre se trouvent dans le curseur.

Il existe deux types de curseurs :

Le curseur implicite

Curseur SQL généré et géré par ORACLE pour chaque ordre SQL.

Le curseur explicite

Curseur SQL généré et géré par l’utilisateur pour traiter un ordre SELECT qui ramène plusieurs lignes.

2. Étape d’utilisation d’un curseur explicite

a. Déclaration

Tout curseur explicite utilisé dans un bloc PL/SQL doit être déclaré dans la section DECLARE du bloc en donnant :

son nom,

l’ordre SELECT associé.

Syntaxe

CURSOR nom_curseur IS ordre_select;

b. Ouverture

Après avoir déclaré le curseur, on "ouvre" celui­ci pour faire exécuter l’ordre SELECT.

L’ouverture déclenche :

l’allocation mémoire du curseur,

l’analyse syntaxique et sémantique de l’ordre SELECT,

le positionnement de verrous éventuels (si SELECT ... FOR UPDATE).

L’ouverture du curseur se fait dans la section BEGIN du bloc.

Syntaxe

OPEN nom_curseur;

c. Traitement des lignes

Après l’exécution du SELECT, les lignes ramenées sont traitées une par une, la valeur de chaque colonne du SELECT doit être stockée dans une variable réceptrice.

Syntaxe

FETCH nom_curseur INTO liste_variables;

- 1 -© ENI Editions - All rigths reserved

Page 142: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Le FETCH ramène une seule ligne à la fois ; pour traiter n lignes, il faut une boucle.

d. Fermeture

Après le traitement des lignes pour libérer la place mémoire, on ferme le curseur.

Syntaxe

CLOSE nom_curseur;

e. Curseur for

Dans la mesure où l’utilisation principale d’un curseur est le parcours d’un ensemble de lignes ramenées par l’exécution du SELECT associé, il peut être intéressant d’utiliser une syntaxe plus simple pour l’ouverture du curseur et le parcours de la boucle.

Oracle propose une variante de la boucle FOR qui déclare implicitement la variable de parcours, ouvre le curseur, réalise les FETCH successifs et ferme le curseur.

Syntaxe

FOR variable IN cursor LOOP --instructions END LOOP;

Exemple

Définition et parcours d’un CURSOR sur la table CLIENTS. Affichage du dernier client lu dans la table.

SQL> variable NO_CLIENT number SQL> variable NOM_CLIENT char(20) SQL> declare 2 cursor c_cli is select NOCLI, NOMCLI from CLIENTS; 3 begin 4 for V_CLI in C_CLI LOOP 5 :NO_CLIENT := V_CLI.NOCLI; 6 :NOM_CLIENT := V_CLI.NOMCLI; 7 end loop ; 8 end; 9 / Procédure PL/SQL terminée avec succès. SQL> rem Dernier client lu dans la boucle SQL> print NO_CLIENT NO_CLIENT --------- 152 SQL> print NOM_CLIENT NOM_CLIENT ------------ LAROCHE SQL>

Il est également possible de ne pas déclarer le curseur dans la section DECLARE mais de spécifier celui­ci directement dans l’instruction FOR.

SQL> variable NO_CLIENT number SQL> variable NOM_CLIENT char(20) SQL> begin 2 for V_CLI in (select NOCLI, NOMCLI from CLIENTS) LOOP

- 2 - © ENI Editions - All rigths reserved

Page 143: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

3 :NO_CLIENT := V_CLI.NOCLI; 4 :NOM_CLIENT := V_CLI.NOMCLI; 5 end loop ; 6 end; 7 / Procédure PL/SQL terminée avec succès. SQL> rem Dernier client lu SQL> print NO_CLIENT NO_CLIENT --------- 152 SQL> print NOM_CLIENT NOM_CLIENT --------------------- LAROCHE SQL>

3. Les attributs d’un curseur

Les attributs d’un curseur (implicite ou explicite) sont des indicateurs sur l’état d’un curseur.

C’est un attribut de type booléen.

Nom de l’attribut pour un curseur implicite : SQL%FOUND

Il est à TRUE (vrai) si :

la dernière instruction INSERT, UPDATE ou DELETE a traité au moins une ligne,

ou si le dernier SELECT ... INTO a ramené une et une seule ligne.

Nom de l’attribut pour un curseur explicite : nom_curseur%FOUND

Il est à TRUE si le dernier FETCH a ramené une ligne.

C’est un attribut de type booléen.

Nom de l’attribut pour un curseur implicite : SQL%NOTFOUND

Il est à TRUE ( vrai ) si :

la dernière instruction INSERT, UPDATE, ou DELETE n’a traité aucune ligne,

ou si le dernier SELECT ... INTO n’a pas ramené de ligne (dans ce cas une exception est d’abord générée, Cf. E. Gestion des erreurs).

Nom de l’attribut pour un curseur explicite : nom_curseur%NOTFOUND

Il est à TRUE si le dernier FETCH n’a pas ramené de ligne.

C’est un attribut de type booléen.

Nom de l’attribut pour un curseur implicite : SQL%ISOPEN

Toujours à FALSE car ORACLE referme les curseurs après utilisation.

Nom de l’attribut pour un curseur explicite : nom_curseur%ISOPEN

%FOUND

%NOTFOUND

%ISOPEN

- 3 -© ENI Editions - All rigths reserved

Page 144: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Il est à TRUE si le curseur est ouvert.

Il est de type numérique.

Nom de l’attribut pour un curseur implicite : SQL%ROWCOUNT

Il contient le nombre de lignes traitées par le dernier INSERT, UPDATE ou DELETE.

Il est à 0 si le dernier SELECT...INTO n’a ramené aucune ligne, à 1 si le dernier SELECT... INTO a ramené exactement 1 ligne, ou à 2 si SELECT...INTO a ramené plus d’1 ligne.

Nom de l’attribut pour un curseur explicite : nom_curseur%ROWCOUNT

Indique le numéro de la ligne ramenée par le dernier FETCH.

Bien entendu, tous les attributs ne sont pas testables n’importe comment. Le tableau ci­dessous indique la valeur à laquelle on peut s’attendre lorsque l’on teste l’un de ces attributs.

4. ROWNUM

La variable ROWNUM retourne un numéro indiquant l’ordre dans lequel la ligne a été sélectionnée depuis une table. La première ligne sélectionnée porte le numéro 1, la deuxième le numéro 2... Si la commande SELECT, d’extraction des lignes, contient une clause ORDER BY, alors ROWNUM contient le numéro de la ligne avant le tri des données.

Exemple

Utilisation de ROWNUM : dans l’exemple suivant, la variable ROWNUM est utilisée pour extraire les trois premiers clients.

%ROWCOUNT

% ISOPEN % FOUND %NOT FOUND %ROWCOUNT

OPEN

avant

après

FAUX

VRAI

erreur

NULL

erreur

NULL

erreur

0

premier FETCH

avant

après

VRAI

VRAI

NULL

VRAI

NULL

FAUX

0

1

FETCH

avant

après

VRAI

VRAI

VRAI

VRAI

FAUX

FAUX

1

suivant les données

dernier FETCH

avant

après

VRAI

VRAI

VRAI

FAUX

FAUX

VRAI

suivant les données

suivant les données

CLOSE

avant

après

VRAI

FAUX

FAUX

erreur

VRAI

erreur

suivant les données

Erreur

- 4 - © ENI Editions - All rigths reserved

Page 145: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

5. Modification des valeurs d’un curseur

La clause CURRENT OF permet d’accéder directement en modification ou en suppression à la ligne que vient de ramener l’ordre FETCH.

Il faut au préalable réserver les lignes lors de la déclaration du curseur par un verrou d’intention (... FOR UPDATE OF nom_col...).

Cette fonctionnalité est très importante car la clause FOR UPDATE permet de poser un verrou d’intention, c’est­à­dire que les données ne peuvent pas être modifiées, par un autre utilisateur, entre le moment où les données sont lues et le moment où les données sont modifiées. Sans ce verrou d’intention, des modifications peuvent avoir lieu entre la lecture et la mise à jour, ce qui peut avoir des conséquences non négligeables.

De plus, la clause CURRENT OF permet de ne pas manipuler la clé primaire.

Exemple

Utilisation d’un curseur pour la mise à jour de chaque ligne traitée :

Declare CURSOR C1 is Select REFART, PRIXHT from ARTICLES FOR UPDATE OF PRIXHT ; ART C1%ROWTYPE ; BEGIN Open C1 ; fetch C1 into ART ; while C1%FOUND loop update ARTICLES set PRIXHT = ART.PRIXHT * 2 where current of C1 ; fetch C1 into ART ; end loop ; commit ; close C1 ; END ;

6. Passage de paramètres

Il est possible de définir les curseurs avec des paramètres afin de rendre leur utilisation la plus souple possible. Le passage de paramètres s’effectue à l’ouverture du curseur par la commande OPEN.

Syntaxe

Déclaration du curseur avec paramètres :

CURSOR nom_curseur( nom_paramètre type_donnée, ...) IS requête_SELECT;

Ouverture du curseur paramétré et passage de la valeur des paramètres :

OPEN nom_curseur(valeur_parametre1, ...);

Exemple

- 5 -© ENI Editions - All rigths reserved

Page 146: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Utilisation d’un curseur paramétré : dans l’exemple suivant, le curseur accepte en paramètre le numéro du client et permet de connaître les numéros des commandes passées par ce client.

7. Les expressions de type curseur

Une expression de type curseur va pouvoir être retournée par une requête de type SELECT et elle contient un curseur. Chaque ligne de données retournée par la requête SELECT contient des valeurs simples et des curseurs qui correspondent à des requêtes liées à la requête principale.

Ce type de valeur retournée va permettre de diminuer le nombre de tables temporaires et de vues utilisées pour la résolution d’un problème en PL/SQL.

Ces curseurs imbriqués sont ouverts et fermés de façon implicite et l’utilisateur ne doit prendre en charge que la gestion du curseur principal.

Ces types de curseurs ne peuvent être présents que dans la requête SELECT principale. Il n’est donc pas possible de créer des curseurs imbriqués dans les vues.

L’utilisation du package DBMS_OUPUT est abordée dans le chapitre Objets de la base utilisant PL/SQL ­ DBMS_OUTPUT.

- 6 - © ENI Editions - All rigths reserved

Page 147: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Gestion des erreurs

De nombreuses erreurs peuvent survenir au cours de l’exécution. Ces erreurs peuvent être d’origine matérielle, dues à une faute de programmation ou de n’importe quelle autre origine. Avec certains langages de programmation, il n’est pas possible de gérer toute sorte d’erreur, comme la division par zéro.

Le langage PL/SQL fournit un mécanisme d’interception des erreurs afin de donner une réponse logicielle à tout type d’erreur. Bien sûr, toutes les erreurs ne pourront être traitées mais il est possible de prévoir une sortie propre du programme quoi qu’il arrive.

Le traitement des erreurs a lieu dans la partie EXCEPTION du bloc PL/SQL. Cette partie est optionnelle et ne doit être définie que si le bloc intercepte des erreurs.

Structure d’un bloc PL/SQL :

La section EXCEPTION permet d’affecter un traitement approprié aux erreurs survenues lors de l’exécution du bloc PL/SQL.

On distingue deux types d’erreurs :

les erreurs internes Oracle,

les anomalies dues au programme.

Après l’exécution du code correspondant au traitement de l’exception, le bloc en cours d’exécution est terminé, et l’instruction suivante à être exécutée est celle qui suit l’appel à ce bloc PL/SQL dans le bloc maître.

Les avantages de ce mode de gestion des erreurs sont nombreux. Le plus important est représenté par le fait que pour gérer un type d’erreur, le code ne doit être écrit qu’une seule fois. Dans les langages de programmation qui ne possèdent pas ce mécanisme d’interception des erreurs, l’appel à la fonction traitant l’erreur doit être précisé à chaque fois que l’erreur peut se produire.

Schéma résumant le principal avantage d’un mécanisme d’interception des erreurs :

- 1 -© ENI Editions - All rigths reserved

Page 148: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Définir et donner un nom à chaque erreur (différent pour les erreurs utilisateur et les erreurs Oracle).

Associer une entrée dans la section EXCEPTION pour chaque nom d’ereur défini dans la partie DECLARE.

Définir le traitement à effectuer dans la partie EXCEPTION.

La levée des exceptions ne permet pas de continuer normalement le traitement des opérations.

Toutefois, en s’appuyant sur la définition de sous­blocs au sein desquels les exceptions sont gérées, il est possible d’exécuter une suite d’instructions même si une exception est levée au cours de l’exécution d’un sous­bloc.

1. Erreurs prédéfinies

Toutes les erreurs Oracle possèdent un numéro d’identification unique. Mais elles ne peuvent être interceptées dans un bloc PL/SQL que si un nom est associé au numéro de l’erreur Oracle. Dans le langage PL/SQL, les erreurs Oracle les plus courantes sont associées à un nom afin de faciliter leur interception dans les blocs PL/SQL.

La liste de ces exceptions prédéfinies est donnée ci­dessous. Pour traiter les autres erreurs Oracle, il est toujours possible d’utiliser le mot clé OTHERS et de connaître l’exception à l’origine de ce traitement en faisant appel aux fonctions SQLCODE et SQLERRM.

Règles à respecter

Exception Erreur Oracle Valeur de SQLCODE

ACCESS_INTO_NULL ORA­06530 ­6530

CASE_NOT_FOUND ORA­06592 ­6592

COLLECTION_IS_NULL ORA­06531 ­6531

CURSOR_ALREADY_OPEN ORA­06511 ­6511

DUP_VAL_ON_INDEX ORA­00001 ­1

- 2 - © ENI Editions - All rigths reserved

Page 149: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Les exceptions prédéfinies appartiennent au package STANDARD, aussi ces exceptions sont utilisables telles quelles dans les programmes PL/SQL

Les exceptions sont traitées dans la partie EXCEPTION du bloc PL/SQL. À l’intérieur de cette partie, les clauses WHEN permettent de connaître le code à exécuter en réponse à une exception levée.

Exemple

Gestion de l’exception Oracle prédéfinie TOO_MANY_ROWS : dans l’exemple ci­après, la partie exception du bloc PL/SQL permet de traiter les exceptions qui correspondent à une tentative de stocker un ensemble de valeurs dans une seule variable (TOO_MANY_ROWS).

2. Anomalies programme utilisateur

Si le programmeur pense qu’une anomalie peut se produire pendant le traitement (erreur logique ou erreur de données), il peut le prévoir comme une exception qui permettra un traitement supplémentaire si elle se produit.

INVALID_CURSOR ORA­01001 ­1001

INVALID_NUMBER ORA­01722 ­1722

LOGIN_DENIED ORA­01017 ­1017

NO_DATA_FOUND ORA­01403 +100

NOT_LOGGED_ON ORA­01012 ­1012

PROGRAM_ERROR ORA­06501 ­6501

ROWTYPE_MISMATCH ORA­06504 ­6504

SELF_IS_NULL ORA­030625 ­30625

STORAGE_ERROR ORA­06500 ­6500

SUBSCRIPT_BEYOND_COUNT ORA­06533 06533

SUBSCRIPT_OUTSIDE_LIMIT ORA­06532 ­6532

SYS_INVALID_ROWID ORA­01410 ­1410

TIMEOUT_ON_RESOURCE ORA­00051 ­51

TOO_MANY_ROWS ORA­01422 ­1422

VALUE_ERROR ORA­06502 ­6502

ZERO_DIVIDE ORA­01476 ­1476

- 3 -© ENI Editions - All rigths reserved

Page 150: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

À la différence des exceptions prédéfinies, les exceptions définies par l’utilisateur devront être déclarées et levées explicitement par l’intermédiaire de l’ordre RAISE.

Les exceptions peuvent être définies uniquement dans la section DECLARE du bloc PL/SQL. Une exception est définie en précisant son nom, suivi du mot clé EXCEPTION.

DECLARE Depassement EXCEPTION ...

Dans l’exemple ci­dessus l’exception Depassement est définie.

La déclaration des exceptions est similaire à celle des variables.

Syntaxe

DECLARE ... nom_erreur EXCEPTION; ... BEGIN ... IF(anomalie) THEN RAISE nom_erreur; ... EXCEPTION WHEN nom_erreur THEN (traitement); END; => Sortie du bloc après exécution du traitement.

Exemple

Par rapport à l’exemple précédent (curseurs), on prévoit d’arrêter et d’annuler les modifications si un prix dépasse le plafond fixé.

DECLARE CURSOR C1 ... ART ... Dépassement EXCEPTION ; NVPRIX NUMBER ; BEGIN .... while C1%FOUND LOOP NVPRIX := ART.PRIXHT *2 ; if NVPRIX > 10000 then raise dépassement ; update ARTICLES set PRIXHT = NVPRIX ... fetch ... end loop ; ... EXCEPTION When dépassement then rollback ; END ;

Le mot clé RAISE permet bien sûr de lever des erreurs utilisateurs dans la partie traitement du bloc, mais il est également possible de l’utiliser pour propager des exceptions dans le bloc appelant après traitement partiel ou complet d’une exception.

En effet, une exception se propage de bloc en bloc, jusqu’à trouver un traitement qui lui est approprié dans la section exception. Après traitement de l’exception, le bloc courant est quitté pour revenir au bloc de niveau supérieur sans erreur. Il peut parfois être nécessaire de faire remonter une exception après le traitement d’exception. Pour cela, on utilise le mot clé RAISE suivi du nom de l’exception à propager au bloc de niveau supérieur.

Exemple

Utilisation de l’instruction RAISE pour propager une erreur : dans l’exemple suivant, le bloc PL/SQL et son sous­bloc essaient de supprimer une commande.

- 4 - © ENI Editions - All rigths reserved

Page 151: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

3. Erreurs Oracle

Pour capturer une erreur Oracle non prédéfinie il est nécessaire, soit de travailler avec la clause WHEN OTHERS du bloc de traitement des exceptions, soit d’associer un nom au numéro de l’erreur Oracle que l’on souhaite capturer. Cette association, nom d’exception et numéro d’erreur Oracle, est possible grâce à la directive de compilation PRAGMA EXCEPTION_INIT.

Le nom associé à l’erreur Oracle doit être défini au préalable comme étant un nom d’exception.

Syntaxe

PRAGMA EXCEPTION_INIT (nom_exception, numero_erreur_oracle)

Exemple

Interception d’une erreur Oracle non prédéfinie : dans l’exemple ci­après, le bloc PL/SQL traite l’erreur qui correspond à un verrou mortel. Un verrou mortel survient lorsque les verrous posés sur les différentes lignes modifiées par les utilisateurs bloquent tous les utilisateurs. Les verrous mortels sont détectés automatiquement par Oracle qui décide alors de libérer une transaction pour l’autoriser à saisir l’ordre ROLLBACK afin de libérer les ressources et les utilisateurs.

Le traitement de cette exception sera donc simplement l’ordre ROLLBACK.

- 5 -© ENI Editions - All rigths reserved

Page 152: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

PL/SQL déclare des exceptions prédéfinies dans le package standard. Il ne faut surtout pas redéfinir ces exceptions, car la définition locale de l’exception masque la déclaration globale. Par exemple, si l’on définit une

exception invalid_number associée à un code d’erreur Oracle, pour traiter l’exception prédéfinie qui porte ce nom, il faudra préfixer le nom de l’exception par le nom de package, soit standard.invalid_number.

Toutes les erreurs dues au SQL ou au PL/SQL ont un code. Il est possible d’associer ce code à un nom d’exception afin de prendre en compte le traitement de l’erreur au niveau du bloc.

Syntaxe

DECLARE ... nom_erreur EXCEPTION; PRAGMA EXCEPTION_INIT(nom_erreur, code_erreur); ... BEGIN ... =>Dès qu’une erreur Oracle est rencontrée, passage automatique à la section EXCEPTION pour réaliser le trai- tement approprié à l’erreur ... EXCEPTION WHEN nom_erreur THEN (traitement); [WHEN OTHERS THEN (traitement);] END; => Sortie du bloc après exécution du traitement

Exemple

L’erreur 1401 signifie une valeur trop grande pour une colonne. Si elle se produit on veut tout arrêter proprement :

Declare ... Trop_grand EXCEPTION ; PRAGMA EXCEPTION_INIT (Trop_Grand, -1401) ; Begin ... ... Exception When Trop_grand then rollback ; end ;

4. Portée des exceptions

La visibilité des exceptions est similaire à celle des variables. En effet, une exception est visible dans le bloc où elle est définie et dans tous les sousblocs de ce bloc. Toutefois, il est possible de masquer cette exception dans les sous­blocs en redéfinissant une exception qui porte le même nom.

- 6 - © ENI Editions - All rigths reserved

Page 153: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Visibilité des exceptions :

Le sous­bloc ne peut pas lever l’exception définie dans le bloc de niveau supérieur car elle est masquée par la définition locale. Si le bloc de niveau supérieur porte une étiquette, il est possible de lever l’exception définie au niveau supérieur en utilisant la syntaxe suivante : nom_du_bloc.nom_exception

Dans l’exemple ci­avant les deux exceptions depassement sont totalement différentes et il n’existe aucun lien entre elles.

5. Utilisation de raise_application_error

Le package DBMS_STANDARD, qui est installé avec Oracle, fournit un ensemble de fonctions et de procédures qui facilitent le développement sous Oracle. Par exemple, la procédure raise_application_error permet de définir des erreurs utilisateur depuis des sous­programmes.

Syntaxe

raise_application_error (numero_erreur, message[,TRUE|FALSE]);

numero_erreur

représente le numéro de l’erreur utilisateur. Ce numéro doit être compris entre ­20000 et ­20999.

message

chaîne de caractères d’une longueur maximale de 2048 octets qui contient le message associé à l’erreur.

Le troisième paramètre, qui est optionnel, permet de savoir si l’erreur doit être placée sur la pile des erreurs (TRUE) ou bien si l’erreur doit remplacer toutes les autres erreurs. C’est cette dernière solution qui est adoptée par défaut.

Lorsque le bloc PL/SQL appelle la procédure raise_application_error, le déroulement de ce bloc est interrompu et l’erreur est remontée au bloc appelant. Ce dernier doit traiter l’exception comme une erreur Oracle.

Exemples

Utilisation de raise_application_error : dans l’exemple suivant une erreur est levée si le client habite Nantes.

- 7 -© ENI Editions - All rigths reserved

Page 154: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Bloc de suppression d’un client : dans ce second exemple, on utilise le principe de gestion des exceptions pour supprimer un client.

- 8 - © ENI Editions - All rigths reserved

Page 155: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Exemple récapitulatif

L’exemple suivant montre les syntaxes utilisées pour la gestion des variables, des curseurs et les structures de contrôle dans un programme complet.

Ce programme est exécuté via SQL*Plus.

1. Énoncé du traitement

On veut pouvoir mettre à jour la quantité en stock de la table ARTICLES (REFART, DESIGNATION, PRIXHT, QTESTK) à partir des commandes en cours (ETATCDE = ’EC’) stockées dans les tables COMMANDES (NOCDE, NOCLI, DATCDE, ETATCDE) et LIGNESCDE (NOCDE, NOLIG, REFART, QTECDE).

Le traitement doit mettre à jour la colonne QTESTK de ARTICLES en otant les QTECDE de LIGNESCDE pour l’article. Il doit également y avoir mise à jour de ETATCDE à ’LI’ si toutes les quantités peuvent être livrées pour la commande (QTESTK > 0 après décrémentation).

Dans le cas où la quantité en stock de l’article devient négative, les mises à jour pour cette commande sont annulées.

Une table témoin est mise à jour pour chaque article à problème (non livrable) et pour chaque commande livrée entièrement.

2. Exemple

Script majliv.sql.

rem Livraison des commandes et mise à jour des stocks rem Création de la table TEMOIN create table TEMOIN(nocde number(6), texte char(60)); rem Bloc PL/SQL de mise à jour DECLARE cursor ccde is select c.nocde, refart, qtecde from ligcdes l,commandes c where c.nocde=l.nocde and c.etatcde=’EC’ order by c.nocde; vcde ccde%rowtype; vqtestk articles.qtestk%type; vnvqte vqtestk%type; vtexte temoin.texte%type; verr boolean; vcderef commandes.nocde%type; BEGIN open ccde;--Execution du curseur fetch ccde into vcde;--Lecture de la 1re ligne <<Bcde>> while ccde%found loop vcderef:=vcde.nocde;--Debut de commande verr:=false; vtexte:=’Problème sur article(s): ’; commit; <<Blig>> while ccde%found and vcde.nocde=vcderef loop select qtestk into vqtestk from articles where refart=vcde.refart; vnvqte:=vqtestk-vcde.qtecde; if (vnvqte>=0) then --stock OK update articles set qtestk=vnvqte where refart=vcde.refart; else -- stock pas OK verr:=true; vtexte:=rtrim(vtexte)||rtrim(vcde.refart); end if;

- 1 -© ENI Editions - All rigths reserved

Page 156: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

fetch ccde into vcde; --lecture ligne suivante end loop Blig; if verr then rollback; else update commandes set etatcde=’LI’ where nocde=vcderef; vtexte:=’Commande livre’; end if; insert into temoin values (vcde.nocde, vtexte); commit; end loop Bcde; close ccde; END; / rem Consultation de la table témoin select * from temoin; drop table temoin;

3. Exécution par SQL*Plus

SQL> select * from articles; REFA DESIGNATION PRIX CODETVA CATEGORIE QTESTK ---- ------------------------- -------- --------- ---------- ---------- AB22 Tapîs Persan 1250,1 2 IMPORT 40 CD50 2 IMPORT 1 CD21 Platine laser 500 2 IMPORT 100 ZZZZ Article bidon DIVERS 25 AA00 Cadeau 0 DIVERS 8 AB03 Carpette 150 2 SOLDES 30 AB Tapis 2 DIVERS 2 ZZ01 Lot de tapis 500 2 DIVERS 150 AB10 Tapis de chine 1500 2 IMPORT 2 9 ligne(s) sélectionnée(s). SQL> select * from cde; NOCDE ET REFA QTECDE ---------- -- ---- ---------- 1210 EC AB10 3 1210 EC CD50 4 1250 EC AB03 8 1301 EC AB03 5 1230 EC AB10 20 SQL> @majliv SQL> select * from temoin; NOCDE TEXTE ---------- ---------------------------------------------------- 1210 Problème sur article(s):AB10CD50 1230 Problème sur article(s):AB10 1250 Commande livrée 1301 Commande livrée SQL> drop table temoin; Table supprimée. SQL> select * from articles; REFA DESIGNATION PRIX CODETVA CATEGORIE QTESTK

- 2 - © ENI Editions - All rigths reserved

Page 157: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

---- ------------------------ -------- --------- --------- ---------- AB22 Tapîs Persan 1250,1 2 IMPORT 40 CD50 2 IMPORT 1 CD21 Platine laser 500 2 IMPORT 100 ZZZZ Article bidon DIVERS 25 AA00 Cadeau 0 DIVERS 8 AB03 Carpette 150 2 SOLDES 17 AB Tapis 2 DIVERS 2 ZZ01 Lot de tapis 500 2 DIVERS 150 AB10 Tapis de chine 1500 2 IMPORT 2 9 ligne(s) sélectionnée(s). SQL> select * from cde; NOCDE ET REFA QTECDE ---------- -- ---- ---------- 1210 EC AB10 3 1210 EC CD50 4 1250 LI AB03 8 1301 LI AB03 5 1230 EC AB10 20 SQL> spool off

- 3 -© ENI Editions - All rigths reserved

Page 158: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Introduction

En plus des blocs PL/SQL anonymes utilisés par SQL*PLus ou par les outils de développement (Oracle*FORMS, Oracle*Reports...), on peut utiliser le PL/SQL dans des objets de la base, comme les procédures stockées (PROCEDURE, FUNCTION, PACKAGE) et les databases TRIGGER.

- 1 -© ENI Editions - All rigths reserved

Page 159: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Les DATABASES TRIGGERS

Un déclencheur ou trigger est un bloc PL/SQL associé à une table. Ce bloc s’exécutera lorsqu’une instruction du DML (INSERT, UPDATE, DELETE) sera demandée sur la table.

Le bloc PL/SQL qui constitue le trigger peut être exécuté avant ou après vérification des contraintes d’intégrité.

Les triggers offrent une solution procédurale pour définir des contraintes complexes ou qui prennent en compte des données issues de plusieurs lignes ou de plusieurs tables. Par exemple, pour garantir le fait qu’un client ne peut pas avoir plus de deux commandes non payées. Toutefois, les triggers ne doivent pas êtres utilisés lorsqu’il est possible de mettre en place une contrainte d’intégrité. En effet, les contraintes d’intégrité étant définies au niveau de la table et faisant partie de la structure de la table, la vérification du respect de ces contraintes est beaucoup plus rapide. De plus, les contraintes d’intégrité garantissent que toutes les lignes contenues dans la tables respectent ces contraintes, tandis que les triggers ne prennent pas en compte les données déjà présentes dans la table lorsqu’ils sont définis.

Le bloc PL/SQL associé au trigger peut être exécuté pour chaque ligne affectée par l’ordre DML (option FOR EACH ROW), ou bien une seule fois pour chaque commande DML exécutée (option par défaut).

Exécution avant ou après vérification des contraintes d’intégrité pour chaque ligne ou chaque ordre.

Dans les triggers BEFORE et FOR EACH ROW, il est possible de modifier les données qui vont être insérées dans la table pour qu’elles respectent les contraintes d’intégrité. Il est également possible de faire des requêtes de type SELECT sur la table sur laquelle porte l’ordre DML uniquement dans le cadre d’un trigger BEFORE INSERT. Toutes ces opérations sont impossibles dans les triggers AFTER car après vérification des contraintes d’intégrité, il n’est pas possible de modifier les données et comme la modification (ou ajout, ou suppression) de la ligne n’est pas terminée, il n’est pas possible d’effectuer des SELECT sur la table.

Il est également possible de poser des triggers sur les vues (VIEW) afin d’intercepter les ordres DML que l’on peut y exécuter. Ces triggers permettent de maîtriser toutes les opérations qui sont effectuées sur les vues et pour l’utilisateur final, la vue est en tout point similaire à une table puisqu’il peut y faire les opérations INSERT, UPDATE et DELETE. Ces triggers sont de type INSTEAD OF, c’est­à­dire que leur exécution va remplacer celle de la commande DML à laquelle ils sont associés. Ce type de trigger n’est définissable que sur les vues, et seul ce type de trigger peut être mis en place sur les vues.

Pincipe de fonctionnement des triggers instead of

Syntaxe

CREATE [OR REPLACE] TRIGGER nom_trigger BEFORE/AFTER/INSTEAD OF INSERT/UPDATE[OF col,...]/DELETE ON Nom_table [FOR EACH ROW] [WHEN (condition)] Bloc PL/SQL ;

OR REPLACE

Remplace la description du TRIGGER s’il existe déjà.

- 1 -© ENI Editions - All rigths reserved

Page 160: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

BEFORE

Le bloc PL/SQL est exécuté AVANT la vérification des contraintes de tables et la mise à jour des données dans la table.

AFTER

Le bloc PL/SQL est exécuté APRES la mise à jour des données dans la table.

INSTEAD OF

Le bloc PL/SQL qui suit remplace le traitement standard associé à l’instruction qui a déclenché le TRIGGER.

INSERT/UPDATE [OF col, ...]/DELETE

Instruction associée au déclenchement du TRIGGER. Plusieurs instructions peuvent déclencher le même TRIGGER. Elles sont combinées par l’opérateur OR.

FOR EACH ROW

Le TRIGGER s’exécute pour chaque ligne traitée par l’instruction associée.

WHEN (condition)

La condition donnée doit être vérifiée pour que le code s’exécute.

Les données de la table à laquelle est associé le TRIGGER sont inacessibles depuis les instructions du bloc. Seule la ligne en cours de modification est accessible à l’aide de deux variables RECORD, OLD et NEW, qui reprennent la structure de la TABLE ou de la VIEW associée. Ces variables peuvent être utilisées dans la clause WHEN du TRIGGER ou dans le bloc d’instructions. Dans ce dernier cas, elles sont référencées comme des variables hôtes avec le préfixe ":" (:OLD.nom_champs, :NEW.nom_champs).

Le terme OLD permet de connaître la ligne en cours de suppression dans un trigger DELETE ou la ligne avant modification dans un trigger UPDATE. Le terme NEW permet de connaître la nouvelle ligne insérée dans un trigger INSERT ou la ligne après modification dans un trigger UPDATE.

Les termes OLD et NEW sont fixés par défaut et il est possible d’utiliser d’autres termes en précisant la clause REFERENCING OLD AS nouveau_nom NEW AS nouveau_nom. Cette clause prend place juste avant la clause FOR EACH ROW (si elle existe) dans la définition du trigger.

Exemple

Exécution d’un bloc PL/SQL avant une suppression dans la table CLIENTS du user FLORIAN :

CREATE TRIGGER avant_sup_cli BEFORE DELETE ON FLORIAN.CLIENTS DECLARE ... BEGIN ... END ;

Exécution d’un bloc PL/SQL après mise à jour de chaque ligne de la table ARTICLES si l’ancien prix est supérieur au nouveau :

create or replace trigger post_majprix after update of prix on articles for each row when (old.prix > new.prix) declare ... begin ... end;

Pour chaque commande on souhaite connaître le nom de l’utilisateur Oracle qui a réalisé la saisie. La première étape consiste à ajouter une nouvelle colonne à la table des commandes. Cette colonne doit accepter la valeur NULL car pour les lignes de commande existantes, le nom de l’utilisateur Oracle est inconnu.

- 2 - © ENI Editions - All rigths reserved

Page 161: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Modification de la table des commandes :

SQL> alter table commandes 2 add (utilisateur varchar2(30)); Table modifiée. SQL>

Dans le trigger, le nom de la nouvelle ligne est changé, il s’exécute avant vérification des contraintes d’intégrité pour chaque ligne insérée dans la table commandes.

Définition du trigger :

SQL> create or replace trigger bf_ins_commandes 2 before insert 3 on commandes 4 referencing new as nouvelle 5 for each row 6 begin 7 select user into :nouvelle.utilisateur from dual; 8 end; 9 / Déclencheur créé. SQL>

On souhaite connaître le nombre de commandes saisies par utilisateur Oracle. Pour éviter d’écrire une requête qui parcourt la totalité de la table des commandes, ce qui peut être très lourd, une table de statistiques va être alimentée par le trigger.

Création de la table de statistiques :

SQL> create table stat_util( 2 utilisateur varchar2(30), 3 nombre integer); Table créée. SQL>

Le trigger doit s’assurer que l’utilisateur existe dans la table des statistiques, et s’il n’est pas déjà présent alors il faut le créer. Le trigger s’exécute après chaque insertion de ligne, pour des raisons d’optimisation en cas de violation des contraintes d’intégrité.

Le code du trigger :

SQL> create or replace trigger af_ins_commandes 2 after insert 3 on commandes for each row 4 declare 5 vnbre stat_util.nombre%type; 6 begin 7 -- connaitre le nombre actuel pour l’utlisateur courant 8 select nombre into vnbre 9 from stat_util 10 where utilisateur=:new.utilisateur; 11 -- mettre à jour la valeur 12 update stat_util 13 set nombre=vnbre+1 14 where utilisateur=:new.utilisateur; 15 exception 16 when no_data_found then 17 insert into stat_util (utilisateur, nombre) 18 values (:new.utilisateur,1); 19 end; 20 / Déclencheur créé. SQL>

- 3 -© ENI Editions - All rigths reserved

Page 162: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

L’écriture d’un déclencheur peut se compliquer lorsque certains traitements sont communs, par exemple, aux instructions INSERT et UPDATE alors que certaines autres sont spécifiques à l’insertion ou bien à la mise à jour des informations. Une première solution consiste à écrire 2 déclencheurs, l’un pour l’instruction INSERT et l’autre pour l’instruction UPDATE. Il en résulte alors une certaine redondance de codage ce qui n’est jamais souhaitable (maintenance plus lourde du code). Oracle propose les prédicats INSERTING, UPDATING et DELETING qui permettent au sein du déclencheur de savoir si le code PL/SQL est exécuté suite à une instruction INSERT, UPDATE ou bien DELETE. Ces prédicats retournent une valeur booléenne et ils sont utilisés dans la condition de test d’une instruction IF. Il est ainsi possible d’écrire un déclencheur commun aux instructions INSERT et UPDATE, par exemple, tout en conservant l’exécution conditionnelle de certaines instructions.

Exemples

Dans l’exemple suivant, le déclencheur va être commun aux instructions INSERT et DELETE afin de maintenir à jour l’attribut CALCULE qui représente le nombre de commandes d’un client.

L’exemple suivant permet de montrer l’intérêt des déclencheurs instead of. Dans un premier temps la vue CLINANTES est créée. Cette vue permet de connaître les clients qui habitent Nantes. Un client est ensuite inséré au travers de cette vue, mais il ne peut pas y être retrouvé.

Création de la vue et mise en avant de la faille :

- 4 - © ENI Editions - All rigths reserved

Page 163: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Un trigger de type INSTEAD OF va donc être défini pour pallier cette faille et pour garantir que les éléments insérés dans une vue seront visibles au travers de cette vue.

Création du trigger et test :

Trigger INSTEAD OF associé à une VIEW sur les tables COMMANDES et LIGCDES.

SQL> create or replace view vcdelig (nocde, datecde, nolig, refart, qtecde) as 2 select l.nocde, datecde, nolig, refart, qtecde 3 from commandes c, ligcdes l 4 where c.nocde=l.nocde; Vue créée. SQL> create or replace trigger inst_del_vcdelig 2 instead of delete 3 on vcdelig 4 for each row 5 declare 6 vbidon number(5); 7 begin 8 delete from ligcdes 9 where nocde=:old.nocde 10 and nolig=:old.nolig;

- 5 -© ENI Editions - All rigths reserved

Page 164: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

11 -- si dernire ligne alors suprimer la commande 12 select count(*) into vbidon 13 from ligcdes 14 where nocde=:old.nocde; 15 exception 16 when no_data_found then 17 delete from commandes where nocde=:old.nocde; 18 end; 19 / Déclencheur créé. SQL>

- 6 - © ENI Editions - All rigths reserved

Page 165: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Les triggers sur des événements système ou utilisateur

Il est possible d’utiliser les triggers pour suivre les changements d’état du système, tels que l’arrêt et le démarrage. Ces triggers vont permettre d’améliorer la gestion de la base et de l’application. En effet, certains événements systèmes ou utilisateurs ont un impact direct sur les performances de l’application et/ou la cohérence des données.

Les événements système sont l’arrêt et le démarrage de l’instance Oracle (startup et shutdown) et la gestion des erreurs. Les triggers d’arrêt et de démarrage ont comme portée l’ensemble de l’instance Oracle, tandis que le trigger de gestion des erreurs peut être défini soit au niveau du schéma soit au niveau de la base de données.

Au niveau de l’utilisateur, des triggers peuvent exister pour ses opérations de connexion et de déconnexion (logon et logoff), pour surveiller et contrôler l’exécution des ordres du DDL (CREATE, ALTER et DROP) et du DML (INSERT, UPDATE et DELETE).

Les triggers DML sont associés à une table et à un ordre du DML, leur définition et utilisation a été détaillée précédemment dans ce chapitre.

Lors de l’écriture de ces triggers, il est possible d’utiliser des attributs pour identifier précisément l’origine de l’événement et adapter les traitements en conséquence.

1. Les attributs

ora_client_ip_address

Permet de connaître l’adresse IP du poste client à l’origine de la connexion.

ora_database_name

Nom de la base de données.

ora_des_encrypted_password

Permet de connaître les descripitions codées du mot de passe de l’utilisateur qui vient d’être créé ou modifié.

ora_dict_obj_name

Nom de l’objet sur lequel l’opération du DDL vient d’être exécutée.

ora_dict_obj_name_list

Permet de connaître la liste de tous les noms d’objet qui ont été modifiés.

ora_dict_obj_owner

Propriétaire de l’objet sur lequel l’opération du DDL a porté.

ora_dict_obj_owner_list

Permet de connaître la liste de tous les propriétaires des objets qui ont été modifiés.

ora_dict_obj_type

Type de l’objet atteint par la dernière opération DDL.

ora_grantee

Permet de connaître les utilisateurs qui possèdent ce privilège.

ora_instance_num

Numéro de l’instance.

- 1 -© ENI Editions - All rigths reserved

Page 166: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

ora_is_alter_column

Retourne Vrai si la colonne passée en paramètre a été modifiée.

ora_is_creating_nested_table

Permet de savoir si une table de fusion a été créée.

ora_is_drop_column

Permet de savoir si la colonne passée en paramètre a été modifiée.

ora_is_servererror

Retourne Vrai si le numéro de l’erreur passée en paramètre se trouve dans la pile des erreurs.

ora_login_user

Permet de connaître le nom de connexion.

ora_privileges

Permet de connaître la liste des privilèges accordés ou retirés par un utilisateur particulier.

ora_revokee

Permet de connaître les utilisateurs à qui le privilège a été enlevé.

ora_server_error

Retourne le numéro de l’erreur Oracle dans la pile dont la position lui est passée en paramètre (le sommet de la pile occupe la position 1).

ora_sysevent

Nom de l’événement système qui a déclenché le trigger.

ora_with_grant_option

Retourne Vrai si le privilège a été accordé avec une option d’administration.

2. Les événements système

STARTUP

L’événement est déclenché lors de l’ouverture de l’instance.

SHUTDOWN

L’événement est déclenché juste avant que le serveur ne commence le processus d’arrêt de l’instance. Lors d’un arrêt brutal du serveur de base de données, cet événement ne sera pas exécuté.

SERVERERROR

L’événement est déclenché lorsqu’une erreur Oracle se produit. Cependant, ce trigger n’est pas déclenché pour les erreurs ORA­1034, ORA­1403, ORA­1422, ORA­1423 et ORA­4030 qui sont trop importantes pour que le processus puisse continuer à s’exécuter.

Syntaxe

Create trigger nom_trigger AFTER|BEFORE evenement_systeme ONDATABASE|SCHEMA Bloc PL/SQL

- 2 - © ENI Editions - All rigths reserved

Page 167: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Seuls les triggers AFTER existent pour les événements STARTUP et SERVERERROR et seul le trigger BEFORE existe pour l’événement SHUTDOWN.

Exemple

Mise en place d’un trigger de gestion des erreurs : dans l’exemple ci­après, les informations concernant chaque erreur provoquée sur le schéma de l’utilisateur qui crée le trigger sont enregistrées dans la table les_erreurs qui a été créée au préalable.

3. Les événements utilisateur

AFTER LOGON

Après avoir établi une connexion avec le serveur.

BEFORE LOGOFF

Avant de rompre la connexion avec le serveur.

BEFORE CREATE AFTER CREATE

Lorsqu’un objet est créé.

BEFORE ALTER AFTER ALTER

Lorsqu’un objet est modifié.

BEFORE DROP AFTER DROP

Lorsqu’un objet est supprimé.

BEFORE ANALYZE AFTER ANALYZE

Quand un ordre d’analyse est exécuté.

BEFORE ASSOCIATE STATISTICS AFTER ASSOCIATE STATISTICS

Quand une association de statistiques est exécutée.

BEFORE AUDIT AFTER AUDIT

Lorsqu’un audit est mis en place.

BEFORE NOAUDIT AFTER NOAUDIT

Lorsqu’une opération d’audit est annulée.

BEFORE COMMENT AFTER COMMENT

- 3 -© ENI Editions - All rigths reserved

Page 168: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Lors de la pose d’un commentaire.

BEFORE DDL AFTER DDL

Lors de l’exécution de la plupart des ordres du DDL à l’exception des commandes ALTER DATABASE, CREATE CONTROLFILE, CREATE DATABASE ainsi que toutes les commandes du DDL issues d’un bloc PL/SQL.

BEFORE DISSOCIATE STATISTICS AFTER DISSOCIATE STATISTICS

Lors de la dissociation des statistiques d’un objet.

BEFORE GRANT AFTER GRANT

Lors de l’exécution de la commande GRANT.

BEFORE RENAME AFTER RENAME

Lors de l’exécution de la commande RENAME.

BEFORE REVOKE AFTER REVOKE

Lors de l’exécution de la commande REVOKE.

BEFORE TRUNCATE AFTER TRUNCATE

Lors de la troncature d’une table.

Syntaxe

Create trigger nom_trigger AFTER|BEFORE evenement_utilisateur ONDATABASE|SCHEMA Bloc PL/SQL

Il faut consulter la liste ci­dessus pour savoir si l’événement peut être traité en BEFORE et ou en AFTER.

Exemple

Mise en place d’un trigger de surveillance des tables : dans l’exemple suivant, le trigger mis en place permet de scruter toutes les créations de table. Tous les renseignements sont stockés dans la table INFOS_TABLE qui a été créée auparavant.

- 4 - © ENI Editions - All rigths reserved

Page 169: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Les modifications de triggers

Il n’est pas possible de modifier un trigger de base de données. Par contre, il est possible de le supprimer puis de le récréer ou bien de le créer avec l’option OR REPLACE.

La commande ALTER TRIGGER va permettre en réalité de désactiver puis de réactiver les triggers. La désactivation peut être envisagée lors d’un import massif de données ou bien d’une modification de grande envergure.

La désactivation et la réactivation de trigger peuvent être réalisées trigger par trigger ou bien table par table. En effet, la commande ALTER TABLE permet l’activation et la désactivation de tous les triggers posés sur la table.

Syntaxe

ALTER TRIGGER nom_trigger ENABLE|DISABLE; ALTER TABLE nom_trigger ENABLE|DISABLE ALL TRIGGERS;

Exemple

Désactivation puis réactivation de triggers :

Pour obtenir des informations sur les triggers il faut interroger le dictionnaire de données. Les trois vues du dictionnaire à utiliser sont : USER_TRIGGERS, ALL_TRIGGERS et DBA_TRIGGERS.

La colonne BASE_OBJECT_TYPE permet de savoir si le trigger est basé sur une table, une vue, un schéma ou la totalité de la base de données.

La colonne TRIGGER_TYPE permet de savoir s’il s’agit d’un trigger BEFORE, AFTER ou INSTEAD OF, si son mode d’exécution est FOR EACH ROW ou non, s’il s’agit d’un trigger événementiel ou non.

La colonne TRIGGERING_EVENT permet de connaître quel événement est concerné par le trigger.

Exemple

Interrogation du dictionnaire : dans l’exemple suivant, la vue USER_TRIGGERS est interrogée pour connaître les déclencheurs posés sur le schéma de l’utilisateur courant.

- 1 -© ENI Editions - All rigths reserved

Page 170: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

- 2 - © ENI Editions - All rigths reserved

Page 171: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Les procédures stockées

Une procédure stockée est un bloc de code PL/SQL nommé stocké dans la base de données et qui peut être exécuté à partir des applications ou d’autres procédures stockées. Dans un bloc PL/SQL, il suffit de référencer la procédure par son nom pour l’exécuter. À partir de l’outil SQL*Plus, on peut utiliser l’instruction EXECUTE.

Syntaxe

CREATE [OR REPLACE] PROCEDURE nom procédure [(paramètre IN/OUT/IN OUT type, ...)] IS/AS bloc PL/SQL ;

OR REPLACE

Remplace la description si la procédure existe.

paramètre

Variable passée en paramètre, utilisable dans le bloc.

IN

Le paramètre est passé en entrée de procédure.

OUT

Le paramètre est valorisé dans la procédure et renvoyé à l’environnement appelant.

type

Type de variable (SQL ou PL/SQL).

Exemple

Procédure de suppression d’un article :

SQL> create or replace procedure supp_art (numero in char) is 2 begin 3 delete from ligcdes where refart=numero; 4 delete from articles where refart=numero; 5 end; 6 / Procédure créée. SQL>

Utilisation par SQL*Plus :

SQL> EXECUTE supp_art (’AB01’) ; utilisation dans un bloc PL/SQL

Utilisation dans un bloc PL/SQL.

DECLARE x char ; BEGIN ... supp_art (x) ; ... END ;

- 1 -© ENI Editions - All rigths reserved

Page 172: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Les fonctions stockées

Comme les procédures, une fonction est un ensemble de code PL/SQL, mais la fonction renvoie une valeur. Ces fonctions stockées seront utilisées comme les fonctions ORACLE.

Syntaxe

CREATE [OR REPLACE] FUNCTION nom de fonction [(paramètre [IN] type, ...)] RETURN type IS/AS Bloc PL/SQL ;

OR REPLACE

La description est remplacée si la fonction existe.

Paramètre

Paramètre passé en entrée utilisé comme une variable dans le bloc.

type

Type du paramètre (SQL ou PL/SQL).

RETURN type

Type de la valeur retournée par la fonction.

Exemple

Fonction factorielle :

CREATE FUNCTION factorielle (n IN NUMBER) RETURN NUMBER IS BEGIN if n = 0 then return (1) ; else return ((n * factorielle (n-1))) ; end if ; END ;

Utilisation par SQL*Plus :

SQL> Select factorielle (5) from DUAL ; FACTORIELLE (5) --------------- 120 SQL>

- 1 -© ENI Editions - All rigths reserved

Page 173: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Les packages

Un package est un objet du schéma qui regroupe logiquement des éléments PL/SQL liés, tels que les types de données, les fonctions, les procédures et les curseurs.

Les packages se divisent en deux parties : un en­tête ou spécification et un corps (body). La partie spécification permet de décrire le contenu du package, de connaître le nom et les paramètres d’appel des fonctions et des procédures. Mais le code n’est pas présent dans la spécification. On trouve le code dans la partie body du package. Cette séparation des spécifications et du code permet de déployer un package sans que l’utilisateur puisse visualiser le code et permet de plus de faire évoluer simplement le code pour répondre à de nouvelles règles.

Les packages offrent de nombreux avantages :

Modularité

Le fait de regrouper logiquement les éléments PL/SQL liés rend plus facile la compréhension des différents éléments du package et leur utilisation en est simplifiée.

Simplification du développement

Lors de la mise en place d’une application, il est possible dans un premier temps de définir uniquement la partie spécification des packages et réaliser ainsi les compilations. Le corps du package ne sera nécessaire que pour l’exécution de l’application.

Informations cachées

Avec un package, il est possible de rendre certains éléments invisibles à l’utilisateur du package. Cela permet de construire des éléments qui ne peuvent être utilisés qu’à l’intérieur du package et donc l’écriture du package s’en trouve simplifiée.

Ajout de fonctionnalités

Les variables et curseurs publics du package existent durant la totalité de la session, donc, il est possible par cet intermédiaire de partager des informations entre les différents sous­programmes d’une même session.

Amélioration des performances

Le package est présent en mémoire dès le premier appel à un élément qui le compose. L’accès aux différents éléments du package est donc beaucoup plus rapide que l’appel à des fonctions et à des procédures indépendantes.

1. En­tête

La portée de tous les éléments définis dans la spécification du package est globale pour le package et locale pour le schéma de l’utilisateur.

La spécification permet de préciser quelles seront les ressources du package utilisable par les applications. Toutes les informations pour savoir comment utiliser les ressources du package (paramètres d’appel, type de la valeur renvoyée) doivent être présentes dans cette spécification.

Syntaxe

CREATE PACKAGE nom_package AS --Définition de type --Déclarations de variables publiques --Prototypes des curseurs publiques --Prototypes des PROCEDUREs et FUNCTIONs publiques END [nom_package];

Exemple

En­tête d’un package de gestion des clients :

SQL> create or replace package GESTION_CLIENTS as 2 type T_CLIREC is record ( 3 NOCLI number(4), 4 NOM char(20), 5 ADR char(20),

- 1 -© ENI Editions - All rigths reserved

Page 174: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

6 CODPOST number(5), 7 VILLE char(30)); 8 cursor C_CLIENTS return T_CLIREC; 9 function CRE_CLI (NOM char, ADR char, CODPOST number, 10 VILLE char) 11 return number; 12 procedure SUPP_CLI (NOCLIENT number); 13 end GESTION_CLIENTS; 14 / Package créé. SQL>

2. Corps du package

Le corps du PACKAGE contient l’implémentation des procédures et fonctions exposées dans la partie en­tête. Il contient également des définitions de types et des déclarations de variables dont les portées sont limitées au corps du PACKAGE.

La spécification du corps du PACKAGE n’est pas nécessaire si l’en­tête du PACKAGE ne comporte que des définitions de types et des déclarations de variables.

Pour s’assurer que dans le corps du package tous les éléments précisés dans la spécification sont bien définis, PL/SQL effectue une comparaison point par point. Aussi, à l’exception des espaces, la déclaration faite dans la spécification doit trouver son équivalent exact dans le corps. Si ce n’est pas le cas, une exception est levée lors de la compilation.

Le corps du package peut en plus contenir des définitions locales de curseurs, variables, types, fonctions et procédures pour une utilisation à l’intérieur du package. Ces élément ne seront pas accessibles en dehors du package.

Syntaxe

CREATE PACKAGE BODY nom_package AS --Définitions de type locaux au package --Déclarations de variables locales au package --Implémentation des curseurs publics --Corps des PROCEDUREs et FUNCTIONs locales au package --Corps des PROCEDUREs et FUNCTIONs publiques END [nom_package];

Exemple

Corps du package de gestion des clients :

SQL> create or replace package body GESTION_CLIENTS as 2 NOMBRE_CLI integer; -- Définition d’une variable locale 3 4 -- Implémentation du curseur 5 cursor C_CLIENTS return T_CLIREC is 6 select NOCLI, NOMCLI, ADRCLI, CODE_POSTAL, VILLE 7 from CLIENTS 8 order by NOCLI; 9 10 -- Fonction de création d’un nouveau client 11 function CRE_CLI (NOM char, ADR char, CODPOST number 12 , VILLE char) 13 return number 14 is 15 NOUV_NOCLI number; 16 begin 17 select S_NOCLI.nextval into NOUV_NOCLI from DUAL; 18 insert into CLIENTS 19 values(NOUV_NOCLI, NOM, ADR, CODPOST, VILLE); 20 NOMBRE_CLI := NOMBRE_CLI + 1; 21 return NOUV_NOCLI; 22 end;

- 2 - © ENI Editions - All rigths reserved

Page 175: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

23 24 -- Procédure de suppression d’un client 25 procedure SUPP_CLI (NOCLIENT number) 26 is 27 begin 28 delete from CLIENTS where NOCLI = NOCLIENT; 29 end; 30 end GESTION_CLIENTS; 31 / Corps de package créé. SQL>

3. Utilisation

Les éléments d’un package (variables, procédures, fonctions) sont référencés par rapport au nom du PACKAGE à l’aide de l’opérateur ".".

Exemple

Utilisation du package de gestion des clients :

SQL> var V_NOCLI number SQL> begin 2 :V_NOCLI := GESTION_CLIENTS.CRE_CLI 3 (’CESAR’, ’Vieux Port’, 13000, ’MARSEILLE’); 4 end; 5 / Procédure PL/SQL terminée avec succès. SQL> print V_NOCLI V_NOCLI --------- 2003 SQL> select NOCLI, ltrim(NOMCLI) NOMCLI, VILLE 2 from CLIENTS order by NOCLI 3 / NOCLI NOMCLI VILLE --------- ------------------------------ -------------------- 15 DUPONT S.A. NANTES 20 Etb LABICHE NANTES 35 DUBOIS Jean NANTES 36 BERNARD S.A. PARIS 138 DUBOIS Jean TOURS 152 LAROCHE LE MANS 1000 DUPOND et DUPONT LILLE 1001 DURAND et DURANT TOURCOING 2003 CESAR MARSEILLE 9 ligne(s) sélectionnée(s). SQL> begin 2 GESTION_CLIENTS.SUPP_CLI(152); 3 end; 4 / Procédure PL/SQL terminée avec succès. SQL> select NOCLI, ltrim(NOMCLI) NOMCLI, VILLE 2 from CLIENTS order by NOCLI 3 / NOCLI NOMCLI VILLE

- 3 -© ENI Editions - All rigths reserved

Page 176: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

--------- ------------------------------ ------------------- 15 DUPONT S.A. NANTES 20 Etb LABICHE NANTES 35 DUBOIS Jean NANTES 36 BERNARD S.A. PARIS 138 DUBOIS Jean TOURS 1000 DUPOND et DUPONT LILLE 1001 DURAND et DURANT TOURCOING 2003 CESAR MARSEILLE 8 ligne(s) sélectionnée(s). SQL>

4. Les curseurs

Il est possible de séparer la déclaration d’un curseur (sa spécification) de sa définition (son corps). Avec cette technique, il devient alors possible de changer la définition du curseur sans que sa déclaration ne soit modifiée. La déclaration du curseur dans la partie spécification du package doit respecter la syntaxe suivante :

CURSOR nom_curseur [(paramètre, ...)] RETURN type_valeur_renvoyée

La valeur retournée est, soit une valeur simple soit un enregistrement.

Dans le corps du package, il est maintenant obligatoire de définir la clause SELECT associée au curseur. Bien sûr, les colonnes précisées derrière la clause SELECT et le type de données indiqué comme étant retourné dans la partie spécification doivent correspondre exactement.

La définition des curseurs à l’intérieur du package offre plus de souplesse car il est possible de changer leur définition sans pour autant être obligé de modifier la partie spécification du package.

Pour utiliser un curseur défini dans un package, il faut, dans un bloc PL/SQL, faire préfixer le nom du curseur par celui du package. La notation est la même que celle mise en place pour appeler des fonctions ou des procédures définies dans un package.

La portée d’un curseur de package n’est pas limitée au seul bloc dans lequel il est ouvert. Il est ainsi possible de conserver le curseur ouvert pendant toute une session et de le fermer simplement lors de la déconnexion.

- 4 - © ENI Editions - All rigths reserved

Page 177: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Les transactions autonomes

Une transaction est un ensemble d’ordres SQL qui constitue une unité logique de traitement. Soit la totalité des instructions de l’unité est exécutée avec succès soit aucune instruction n’est exécutée. Dans certaines applications, une transaction doit s’exécuter à l’intérieur d’une autre transaction.

Un transaction autonome est une transaction indépendante qui est lancée depuis une autre transaction : la transaction principale. Durant l’exécution de la transaction autonome, la transaction principale est suspendue.

Les transactions autonomes sont totalement indépendantes, et cette indépendance permet de construire des applications plus modulaires. Bien sûr, les transactions autonomes présentent les mêmes caractéristiques que les transactions régulières.

Pour définir une transaction autonome, il faut utiliser la directive de compilation (pragma) AUTONOMOUS_TRANSACTION. Cette directive doit apparaître dans la section de déclaration des variables, des blocs PL/SQL anonymes, des fonctions, des procédures et des triggers. En règle générale, les directives de compilation sont placées en début de la section de déclaration des variables, ce qui facilite la relecture du programme.

Il n’est pas possible de placer la directive de compilation pragma AUTONOMOUS_TRANSACTION au niveau du package. Par contre, chaque fonction et procédure du package peut être déclarée en tant que transaction

autonome.

Exemple

Procédure définissant une transaction autonome : dans l’exemple suivant, la fonction de mise à jour des clients constitue une transaction autonome.

Les modifications réalisées par la transaction autonome sont visibles des autres transactions immédiatement après sa validation (COMMIT), même si la transaction principale qui a appelé la transaction autonome n’est pas terminée. Les modifications seront également visibles par la transaction principale. Pour que la transaction principale ne puisse pas connaître les modifications, il faut préciser le niveau d’isolation de la transaction à l’aide de la commande suivante : SET TRANSACTION ISOLATION LEVEL SERIALIZABLE.

Les transactions autonomes sont contrôlées par les ordres COMMIT, ROLLBACK et SAVEPOINT. À l’intérieur d’un bloc PL/SQL défini comme transaction autonome, il est possible de réaliser plusieurs transactions les unes à la suite des autres. Pour la transaction principale appelante, c’est l’ensemble des transactions du bloc appelé qui est autonome.

Exemple

Procédure définissant une transaction autonome : dans l’exemple ci­après, la procédure de mise à jour des clients est appelée depuis un bloc PL/SQL anonyme, dont la transaction est annulée. On constate que le travail de la procédure reste validé.

- 1 -© ENI Editions - All rigths reserved

Page 178: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Il est également possible de définir les triggers comme réalisant des transactions autonomes. Cette option est intéressante lorsque l’on utilise les triggers pour journaliser les opérations qui interviennent sur une table, même si l’opération n’est pas validée. Le fait que le trigger soit autonome permet d’assurer que le travail réalisé sera enregistré dans la base de données, même si l’opération à l’origine de l’exécution du trigger est annulée (ROLLBACK).

De plus, contrairement aux triggers traditionnels, les triggers autonomes peuvent exécuter des ordres SQL DDL en utilisant des ordres SQL Dynamique.

Dans le cas où l’instruction INSERT est utilisée pour insérer une seule ligne d’informations dans la table, il est possible d’utiliser la clause RETURNING pour connaître par exemple la valeur d’une colonne ou bien le résultat d’un calcul. Cette fonctionnalité s’avère particulièrement pratique lorsqu’une séquence est associée à la colonne et que la valorisation de la colonne à partir de la séquence est réalisée depuis un déclencheur de base de données.

La clause RETURNING permet de connaître la valeur qui a été générée et insérée dans la table. Sans cette clause, les accès à la base sont multipliés pour connaître la valeur affectée à la colonne.

Syntaxe

INSERT INTO table[(colonne, ...)] VALUES (expression, ...) RETURNING colonne INTO variable

Exemple

Dans l’exemple suivant, une fonction de création des clients est mise en place. Cette fonction utilise une séquence oracle pour fixer le numéro de clients. La valeur du numéro de client est retournée par la fonction.

Il est également possible d’utiliser cette clause RETURNING dans une instruction DELETE afin d’obtenir une ou plusieurs informations sur la ligne supprimée.

La clause RETURNING

- 2 - © ENI Editions - All rigths reserved

Page 179: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Syntaxe

DELETE FROM table[WHERE ...] RETURNING colonne INTO variable

Enfin il est possible d’utiliser cette clause RETURNING avec l’instruction de mise à jour UPDATE. Comme pour les instructions INSERT et DELETE, la clause RETURNING n’est concevable que dans le cas où l’instruction UPDATE met à jour une seule ligne d’informations dans la base.

Syntaxe

UPDATE table SET colonne=valeur [,... WHERE ...] RETURNING colonne[,...] INTO variable[,...]

- 3 -© ENI Editions - All rigths reserved

Page 180: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

SQL dynamique

Le SQL dynamique est une technique qui permet de construire des objets SQL de façon dynamique à l’exécution de code PL/SQL. Le SQL dynamique permet de créer des applications plus souples car les noms des objets utilisés par un bloc PL/SQL peuvent être inconnus au moment de la compilation. Par exemple, une procédure peut travailler avec une table dont le nom est inconnu avant l’exécution de la procédure.

Il faut rappeler que dans le SQL statique toutes les informations sont connues au moment de la compilation et bien sûr les ordres SQL statiques ne changent pas d’une exécution à une autre. Toutefois cette solution offre des avantages car le succès de la compilation garantit que les ordres SQL font référence à des objets valides de la base de données. La compilation vérifie également que les privilèges nécessaires sont en place pour accéder et travailler avec les objets de la base de données. De plus, la performance du code SQL statique est de meilleure qualité que celle du SQL dynamique.

À cause de tous ces avantages, le SQL dynamique ne doit être utilisé que si le SQL statique ne peut pas répondre à nos besoins, ou bien si la solution en statique est beaucoup plus compliquée qu’en SQL dynamique.

Cependant, le SQL statique possède certaines limites qui sont dépassées par le SQL dynamique. On choisira le SQL dynamique si par exemple on ne connaît pas à l’avance les ordres SQL qui vont devoir être exécutés par le bloc PL/SQL, ou bien si l’utilisateur doit donner des informations qui vont venir construire les ordres SQL à exécuter.

De plus, par l’intermédiaire du SQL dynamique, il devient possible d’exécuter des instructions du DDL (CREATE, ALTER, DROP, GRANT et REVOKE) ainsi que les commandes ALTER SESSION et SET ROLE à l’intérieur du code PL/SQL, ce qui est impossible avec le SQL statique.

Le SQL dynamique sera donc utilisé pour répondre à l’un des points suivants :

La commande SQL n’est pas connue au moment de la compilation.

L’ordre à exécuter n’est pas supporté par le SQL statique.

Pour exécuter des requêtes construites lors de l’exécution.

Pour référencer un objet de la base de données qui n’existe pas au moment de la compilation.

Pour pouvoir optimiser la requête lors de son exécution.

Pour créer des blocs PL/SQL de façon dynamique.

Pour travailler sur les droits des utilisateurs de façon dynamique.

Le SQL dynamique offre de meilleures performances que le package DBMS_SQL et plus de possibilités.

1. EXECUTE IMMEDIATE

La commande EXECUTE IMMEDIATE permet de vérifier la syntaxe et d’exécuter de façon dynamique un ordre SQL ou un bloc anonyme PL/SQL.

Syntaxe

EXECUTE IMMEDIATE chaîne_dynamique [ INTO variable, ...| enregistrement] [ USING [IN|OUT|IN OUT] argument ...] [ RETURNING|RETURN INTO argument, ...]

chaîne_dynamique

représente l’ordre SQL ou le bloc PL/SQL.

variable

est une variable qui va stocker la valeur issue d’une colonne sélectionnée.

- 1 -© ENI Editions - All rigths reserved

Page 181: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

enregistrement

est une variable structurée qui va contenir une ligne sélectionnée.

argument

valeurs passées à l’ordre SQL ou au bloc PL/SQL. Ces arguments peuvent représenter des valeurs en lecture/écriture.

À l’exception des requêtes qui retournent plusieurs lignes, il est possible d’exécuter n’importe quel ordre SQL ou bloc PL/SQL. Les arguments ne peuvent pas contenir le nom d’objets de la base de données qui vont être utilisés par les ordres SQL ou PL/SQL.

La commande INTO ne doit être utilisée que pour des requêtes SELECT ne retournant qu’une seule ligne de valeur. Pour chaque colonne retournée par la commande SELECT, doit correspondre une variable ou bien un champ dans l’enregistrement.

Les arguments peuvent être tous placés derrière l’instruction USING. Leur mode par défaut est alors IN, c’est­à­dire qu’ils fournissent une valeur à la commande dynamique. Les arguments de type OUT peuvent être précisés derrière le mot clé RETURN INTO ou RETURNING INTO. Les arguments peuvent contenir des valeurs de type numérique ou bien des chaînes de caractères, mais il n’est pas possible d’y passer des valeurs booléennes (TRUE ou FALSE).

Exemple

SQL Dynamique : l’exemple ci­après montre une utilisation possible du SQL dynamique et des différentes possibilités de l’ordre EXECUTE IMMEDIATE.

Lorsqu’un ordre INSERT, UPDATE ou DELETE possède une clause de type RETURNING, il est possible de placer les arguments de sortie soit dans la clause USING, soit dans la clause RETURNING INTO. Dans les nouvelles

applications, il faut utiliser la clause RETURNING INTO.

Utilisation de la clause RETURNING INTO :

- 2 - © ENI Editions - All rigths reserved

Page 182: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

En utilisant la clause USING, il n’est pas nécessaire de préciser le mode d’utilisation pour les paramètres entrants car le mode par défaut est IN. Avec la clause RETURNING INTO, on ne peut pas préciser le mode d’utilisation du paramètre, c’est obligatoirement OUT. Lorsque cela est nécessaire, il faut spécifier le mode d’utilisation des paramètres en OUT ou IN OUT, par exemple lors de l’appel d’une procédure.

Définition d’une procédure avec des paramètres en mode IN, OUT et IN OUT :

Dans l’exemple suivant, la procédure définie ci­dessus va être appelée de façon dynamique. Le mode d’utilisation des différents paramètres sera précisé derrière la clause USING.

Les modes d’utilisation des paramètres :

2. OPEN FOR, FETCH et CLOSE

Ces trois commandes seront utilisées pour traiter les requêtes dynamiques qui vont ramener plusieurs lignes d’information. Comme pour les curseurs traditionnels, dans un premier temps, il faut ouvrir le curseur à l’aide de la commande OPEN FOR qui correspond à une requête de type SELECT. Puis toutes les lignes d’information pourront être ramenées une par une dans le bloc PL/SQL par l’intermédiaire de la commande FETCH. Enfin, lorsque toutes les lignes

- 3 -© ENI Editions - All rigths reserved

Page 183: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

seront traitées, il faudra fermer le curseur par l’intermédiaire de la commande CLOSE.

a. Ouvrir un curseur (OPEN FOR)

La commande OPEN FOR permet d’associer à une variable de type curseur une requête SELECT qui retourne plusieurs lignes d’information. La requête est exécutée et le curseur est placé sur la première ligne d’information. Contrairement au curseur statique, l’instruction OPEN FOR des curseurs dynamiques possède une clause USING optionnelle afin de passer des arguments à la requête.

Syntaxe

OPEN variable_curseur | :variable_hote FOR requête_dynamique [USING argument, ...]

Exemple

Dans l’exemple suivant, une variable de type curseur est déclarée, puis elle est associée à une commande SELECT qui ramène des informations depuis une table.

declare type CliCurTyp is ref cursor; ccli CliCurTyp; -- variable curseur vno clients.nocli%type; vville clients.ville%type:=’Nantes’; begin open ccli for ’Select nocli, ville from clients where ville=:v’ using vville; ... end; /

Tous les arguments de la requête sont évalués uniquement lorsque le curseur est ouvert. Donc, pour ramener des informations correspondant à différentes valeurs de l’argument, il faut rouvrir le curseur en lui passant une nouvelle valeur pour le paramètre.

b. FETCH

La commande FETCH retourne une ligne de données issue du jeu de résultats correspondant à l’exécution de la requête SELECT lors de l’ouverture du curseur. Pour chacune des colonnes précisées derrière le SELECT, il faut prévoir une variable dans l’environnement PL/SQL qui exécute le curseur dynamique.

Syntaxe

FETCH varible_curseur INTO variable, ...|enregistrement

Exemple

Il est possible de compléter l’exemple ci­dessus en ajoutant le code correspondant au traitement des lignes.

declare type CliCurTyp is ref cursor; ccli CliCurTyp; -- variable curseur vno clients.nocli%type; vville clients.ville%type:=’Nantes’; begin open ccli for ’Select nocli, ville from clients where ville=:v’ using vville; loop fetch ccli into vno, vville; --ramener la ligne suivante exit when ccli%notfound; --quitter la boucle si plus de lignes --traiter les informations end loop; ... end;

La variable dans laquelle est stockée une valeur issue d’une colonne doit correspondre en tout point à la définition de la colonne : même type et même précision.

- 4 - © ENI Editions - All rigths reserved

Page 184: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Il est possible d’utiliser des clauses INTO différentes sur des commandes séparées de FETCH travaillant sur le même curseur.

Chaque exécution de la commande FETCH ramène une ligne du jeu de résultats et place le curseur sur la ligne suivante.

Si un FETCH est exécuté sur un curseur fermé ou bien jamais ouvert, alors l’exception INVALID_CURSOR est levée.

c. CLOSE

La commande CLOSE désactive une variable de type curseur. Après cette commande, le jeu de résultats, construit par la commande OPEN FOR n’existe plus.

Syntaxe

CLOSE variable_curseur

Exemple

Dans cet exemple lorsque la dernière ligne a été traitée, alors le curseur est fermé :

declare type CliCurTyp is ref cursor; ccli CliCurTyp; -- variable curseur vno clients.nocli%type; vville clients.ville%type:=’Nantes’; begin open ccli for ’Select nocli, ville from clients where ville=:v’ using vville; loop fetch ccli into vno, vville; --ramener la ligne suivante exit when ccli%notfound; --quitter la boucle si plus de lignes --traiter les informations end loop; close ccli; end;

Lors de la tentative de fermeture d’un curseur qui est déjà fermé, PL/SQL lève l’exception INVALID_CURSOR.

3. Utilisation des curseurs dynamiques

Quelques règles existent pour essayer de tirer le meilleur parti des curseurs dynamiques en terme de performances et de qualité de programmation.

a. Amélioration des performances

Dans le code exposé ci­dessous, Oracle est obligé de mettre en place un nouveau curseur pour chaque nouvelle ouverture. Cette génération de curseurs très similaires peut dégrader les performances du serveur.

create or replace procedure supp_clients(vnocli number) as begin execute immediate ’DELETE FROM clients WHERE nocli=’|| to_char(vnocli); end;

La conversion du numéro de client contenu dans vnocli en chaîne de caractères permet de construire

- 5 -© ENI Editions - All rigths reserved

Page 185: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

proprement la commande dynamique SQL.

L’amélioration des performances passe par l’utilisation d’un argument. Cette solution permet à Oracle de réutiliser le même curseur pour différentes valeurs de l’argument.

create or replace procedure supp_clients(vnocli number) as begin execute immediate ’DELETE FROM clients WHERE nocli= :v’ using vnocli; end;

b. Passer le nom du schéma des différents objets

La procédure suivante se propose de supprimer n’importe quelle table de la base de données. En utilisant le SQL dynamique, le code suivant est saisi :

create or replace procedure supp_table(nom_table in varchar2) as begin execute immediate ’DROP TABLE :t’ using nom_table; end;

Au moment de son exécution, cette procédure lèvera une erreur du type "nom de table invalide". Ceci est dû au fait que les arguments ne peuvent pas servir à passer des noms d’objets de la base de données. À la place de ce code, il faudrait saisir le code suivant :

CREATE PROCEDURE supp_table(nom_table IN VARCHAR2) AS BEGIN EXECUTE IMMEDIATE ’DROP TABLE ’|| nom_table ; END ;

c. Utiliser plusieurs fois le même argument

Les variables qui apparaissent dans les ordres SQL dynamiques sont associées à des arguments présents derrière la clause USING en respectant leur position et non leur nom pour les identifier à un argument. Ainsi, si la même variable apparaît deux fois dans la commande SQL dynamique, alors le même argument devra apparaître deux fois derrière la clause USING.

On obtient alors le code suivant :

requete:=’insert into commandes values (:x, :x, :y, :z)’; execute immediate requete using a,a,b,c;

Cependant, si on utilise un bloc PL/SQL, il n’est pas nécessaire de passer deux fois le même argument. En effet, dans les blocs PL/SQL, les variables sont associées aux arguments en respectant leur ordre de définition bien sûr, mais, si la même variable apparaît plusieurs fois, alors seule la première occurrence sera associée à un argument. D’où le code suivant qui est plus simple à écrire :

bloc_plsql:=’begin ajout_cde(:x, :x, :y, :z); end;’; execute immediate bloc_plsql using a,b,c;

d. Les attributs des curseurs

Les curseurs explicites possèdent les quatre attributs suivants : %FOUND, %NOTFOUND, %ISOPEN et %ROWCOUNT qui permettent d’obtenir des informations concernant la bonne exécution du curseur, qu’il provienne d’un ordre SQL statique ou dynamique. Pour mener à bien l’ensemble de ces traitements, Oracle utilise des curseurs implicites. Il est possible de connaître les attributs de ces curseurs en utilisant le mot clé SQL. Ainsi, l’attribut %ROWCOUNT sur les curseurs implicites va permettre de connaître le bon déroulement ou non du dernier ordre SQL dynamique qui a été exécuté.

Exemple

Fonction utilisant l’attribut du curseur implicite pour connaître le bon déroulement de l’ordre SQL dynamique : dans l’exemple suivant, après la suppression de lignes, l’attribut %ROWCOUNT est utilisé pour connaître le nombre de lignes affectées par cette commande.

- 6 - © ENI Editions - All rigths reserved

Page 186: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Il est nécessaire de tester la fonction depuis un bloc PL/SQL car il est impossible d’exécuter une fonction du DML depuis une requête SELECT.

e. Passer des valeurs NULL

Il peut parfois être nécessaire de passer des valeurs NULL en tant qu’arguments à des ordres SQL dynamiques. L’opération la plus naturelle serait d’écrire la commande suivante :

EXECUTE_IMMEDIATE ’UPDATE clients SET ville= :x’ USING NULL ;

Comme bien souvent, la valeur NULL ne se gère pas aussi simplement. En effet, il n’est pas possible d’utiliser le littéral NULL derrière la clause USING. Pour pouvoir contourner cette limite, l’opération consiste à initialiser une variable avec la valeur NULL et à l’utiliser en tant que paramètre.

declare c_null char(1); --la variable est initialisée à NULL begin execute immediate ’UPDATE clients set ville=:x’ using c_null; end;

f. Utiliser les droits de l’utilisateur

Par défaut, une procédure stockée s’exécute en utilisant les droits de l’utilisateur Oracle qui définit cette procédure et non pas en utilisant les droits de l’utilisateur qui appelle cette procédure. Certaines procédures sont liées au schéma sur lequel elles sont définies.

Par exemple, si la procédure suivante est définie sur le schéma de l’utilisateur livre :

La procédure supprime permet de supprimer n’importe quel objet du schéma, il faut simplement passer en paramètre le type de l’objet à supprimer et son nom. Afin de faciliter la gestion des objets dans chaque schéma, le privilège EXECUTE a été accordé à l’utilisatrice Marie. Lorsque l’utilisatrice Marie souhaite supprimer sa table CLIENTS de son schéma, elle fait appel à la procédure supprime de la façon suivante :

Exécution de la procédure supprime depuis le schéma de Marie :

- 7 -© ENI Editions - All rigths reserved

Page 187: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Comme le nom d’objet est passé sans référence au schéma, c’est en fait la table Clients, située dans la schéma livre, qui est le créateur de cette procédure que Marie tente de supprimer.

Afin de résoudre tous ces problèmes et pour garantir que la procédure stockée va être exécutée en fonction des droits de l’utilisateur qui en fait usage et non pas de ceux de son propriétaire, il faut utiliser la clause AUTHID lors de la définition de la procédure. Ainsi, les noms d’objets sont résolus dans le schéma de l’utilisateur de la procédure et non pas dans celui de son propriétaire.

Redéfinition de la procédure en utilisant la clause AUTHID :

g. La directive de compilation RESTRICT_REFERENCES

Une fonction appelée depuis une commande SQL doit obéir à un certain nombre de règles pour contrôler les effets de bords. Pour outrepasser ces contraintes, il est possible d’utiliser la directive de compilation RESTRICT_REFERENCES. La commande pragma assure que la fonction ne va pas travailler en lecture/écriture avec une table de la base ou une variable d’un package.

Cependant, si le corps de la fonction contient un ordre dynamique de type INSERT, UPDATE ou DELETE, alors la fonction viole les règles de non­écriture dans la base (Write No Database State : WNDS) et de non­lecture de la base (Read No Database State : RNDS). C’est pourquoi les règles concernant les ordres dynamiques ne sont vérifiées qu’au moment de leur exécution. Pour un ordre EXECUTE_IMMEDIATE, seule la clause INTO permet de détecter une violation de RNDS au moment de la compilation.

h. Éviter les verrous mortels

Il n’est pas possible de supprimer tous les verrous mortels qui peuvent se produire. Néanmoins, il est possible de prendre certaines précautions pour éviter de se bloquer soi­même. Ainsi, il ne faut jamais essayer de modifier (ALTER) ou de supprimer (DROP) un sous­programme ou un package que l’on est en train d’utiliser, comme dans l’exemple suivant :

create procedure calcul_ca (nocli number) as begin ... execute immediate ’DROP PROCEDURE calcul_ca’; ... end;

4. Le package DBMS_SQL

En plus du SQL dynamique, Oracle fournit le package DBMS_SQL pour exécuter de façon dynamique des ordres SQL.

Pour utiliser le SQL dynamique la base de données doit être compatible avec la version 8.1.0 ou supérieure au serveur de base de données.

Le package DBMS_SQL est une librairie PL/SQL afin d’autoriser l’exécution d’ordres SQL construits dynamiquement.

- 8 - © ENI Editions - All rigths reserved

Page 188: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Les principaux avantages du SQL dynamique par rapport au package DBMS_SQL sont :

la facilité d’utilisation,

de meilleures performances d’exécution,

le support de types de données définis par l’utilisateur.

Néanmoins, le package DBMS_SQL possède quelques avantages par rapport au SQL Dynamique :

il est supporté par les applications clientes,

il supporte la procédure DESCRIBE_COLUMNS qui permet de connaître les informations relatives aux colonnes d’un curseur ouvert au travers de DBMS_SQL,

il supporte la copie de données par blocs pour transférer les données issues d’une requête de type SELECT vers une collection.

- 9 -© ENI Editions - All rigths reserved

Page 189: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Collections et enregistrements

Dans le chapitre précédent, la déclaration et l’initialisation des collections et des enregistrements ont été abordées. Ce type de variable est très pratique et une bonne connaissance de leur utilisation permet souvent de gagner du temps lors de l’écriture de traitements en PL/SQL.

L’utilisation des tableaux en PL/SQL n’est pas forcément évident au premier abord. En effet, pourquoi s’obliger à utiliser une telle structure alors que pour stocker un ensemble d’informations, il est très facile de créer une table temporaire.

La raison est très simple : en stockant l’ensemble des données sous forme de collection directement dans le bloc PL/SQL, tous les traitements peuvent être effectués par le moteur PL/SQL. En limitant les requêtes SQL, on limite les accès à la base, ce qui permet d’accélérer le temps de traitement du bloc PL/SQL, mais on limite également l’occupation du moteur SQL et les requêtes des autres utilisateurs peuvent donc être traités plus rapidement.

On voit donc qu’il existe des bénéfices à travailler avec les collections même si dans un premier temps le code PL/SQL à mettre en place est un peu plus compliqué. Il est à noter que l’instruction FORALL (vue plus loin dans ce chapitre) permet de faciliter considérablement les étapes de codages nécessaire pour pouvoir travailler avec les collections dans un bloc PL/SQL.

1. Référencer un élément d’une collection

Pour pouvoir travailler avec une collection, il faut d’abord savoir comment accéder à un élément d’une collection. Toutes les références possèdent la même structure : le nom de la collection suivi d’un indice entre parenthèses.

nom_collection (indice)

L’indice doit être un nombre valide compris entre ­231 et 231.

Pour les collections de type nested table, la plage normale des indices va de 1 à 231 et pour les tableaux (VARRAY) elle va de 1 à la taille maximale du tableau.

Il est possible de faire référence à un élément d’une collection partout où il est possible d’utiliser une variable PL/SQL.

Exemple

Déclaration et utilisation d’une collection :

DECLARE TYPE liste IS TABLE OF VARCHAR2(15); lesnoms liste:=liste(’B Martin’,’MP Macraigne’,’S Guegan’,’ T Groussard’); i BINARY_INTEGER; BEGIN ... IF lesnoms(i) =’G Viaud’ THEN ... END IF; ... END;

Lorsqu’une fonction retourne une collection, il est possible de faire référence à un élément de la collection en utilisant la syntaxe suivante : nom_fonction(paramètre)(indice)

2. Assigner une valeur et comparer des collections

Il est possible d’assigner une collection à une autre à condition qu’elles soient toutes les deux de même type. L’assignation peut être réalisée par l’opérateur :=, les commandes INSERT, UPDATE FETCH et SELECT ou par l’appel d’un sous­programme.

De plus, il est important de respecter certaines contraintes comme l’illustre l’exemple suivant :

DECLARE TYPE Clientele IS VARRAY(100) OF Client ; TYPE Fidele IS VARRAY(100) OF Client ; grp1 Clientele :=Clientele(...) ;

- 1 -© ENI Editions - All rigths reserved

Page 190: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

grp2 Clientele :=Clientele(...) ; grp3 Fidele :=Fidele(...) ; BEGIN grp2 :=grp1 ; grp3 :=grp2 ;-- Illégale car de types différents ... END ;

Si on assigne la collection NULL à une autre collection, alors cette seconde devient NULL et il faudra la réinitialiser.

Il est possible d’assigner une valeur précise à un élément d’une collection en utilisant la syntaxe suivante :

nom_collection(indice) :=expression

L’expression contient une valeur de même type que la collection.

Si l’indice est NULL ou si ce n’est pas un entier, alors PL/SQL lève l’exception VALUE_ERROR.

Lorsque l’on tente d’accéder à un élément en dehors de la collection, alors PL/SQL lève l’exception SUBSCRIPT_BEYOND_COUNT.

Si l’on tente d’accéder à un élément d’une collection NULL alors PL/SQL lève l’exception COLLECTION_IS_NULL.

L’exemple suivant illustre les différents cas dans lesquels peuvent être levées les exceptions énumérées ci­dessus.

DECLARE TYPE tableau IS TABLE OF INTEGER ; montab tableau ; BEGIN montab(1) :=5 ;-- exception COLLECTION_Is_NULL montab :=tableau(10,5,3,6) ; montab(1) :=length(’Hello’) ; montab(2) :=montab(3)*2 ; montab(’H’) :=10 ;-- exception VALUE_ERROR montab(10) :=1 ;--excpion SUBSCRIPT_BEYOND_COUNT ; END ;

Les collections de type nested table et varray sont automatiquement assignées à NULL lors de leur déclaration. Il est donc possible de tester leur nullité.

DECLARE TYPE tableau IS TABLE OF INTEGER ; montab tableau ; BEGIN ... IF montab IS NULL THEN ... END IF ; ... END ;

Toutefois, les collections ne peuvent pas être comparées globalement à l’idée d’une égalité (=) ou d’une inégalité (<,>, <=, >=, <>). Par exemple, le test de l’instruction If ci­après pose une erreur de compilation.

DECLARE TYPE tableau IS TABLE OF INTEGER ; montab tableau :=tableau(5,6,7) ; montab2 tableau :=tableau(1,2,3) ; BEGIN ... -- la ligne suivante provoque une erreur de compilation IF montab=montab2 THEN ... END IF ; ... END ;

3. Travailler avec les collections

- 2 - © ENI Editions - All rigths reserved

Page 191: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Les collections ajoutent une certaine souplesse au langage procédural PL/SQL pour manipuler et travailler simplement avec des données issues de la base.

a. Travailler avec les collections de type NESTED TABLE

À l’aide de SQL*Plus, définissons le type Typestock :

Il faut ensuite définir le type Tabstock comme étant une collection d’éléments de type Typestock.

Définition du tableau tabstock :

Il est maintenant possible de définir la table Depot de la façon suivante :

Chaque élément présent dans la colonne stock est une collection de type nested table, qui va permettre de conserver le stock de chaque dépôt. La clause NESTED TABLE est nécessaire lors de la création de la table Depot car la colonne stock est une collection.

Ajout de données dans la table à l’aide de la commande INSERT : il est possible d’insérer des valeurs dans cette table Depot de la façon suivante :

La modification des données de la table Depot est également possible par l’intermédiaire d’une clause UPDATE :

- 3 -© ENI Editions - All rigths reserved

Page 192: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Afin de rendre le travail avec les collections encore plus facile, il est possible de s’appuyer sur l’instruction %ROWTYPE pour définir une collection qui possède exactement la même structure qu’une table.

Dans l’exemple ci­dessus une collection de type identique à la table des clients est déclarée.

b. Travailler avec les tableaux

Il est également possible de définir des colonnes basées sur un tableau à l’intérieur d’une table. Pour illustrer ce cas de figure, la table Facture va être créée. Chaque facture correspond à un seul client, et une facture peut être établie pour plusieurs commandes. Le numéro et le montant de chaque commande présents sur la facture sont enregistrés dans une colonne de type tableau.

La première étape consiste à construire un type, composé du numéro de commande et du montant de la commande.

Création du type LaCommande :

Ensuite, le type correspondant à un tableau de 50 commandes (numéro et montant) est créé.

Création du type TabCommandes :

Enfin, la table Facture est mise en place.

- 4 - © ENI Editions - All rigths reserved

Page 193: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Création de la table Facture :

Pour travailler avec les colonnes de type tableau, il est bien sûr possible d’utiliser les ordres SQL INSERT et UPDATE comme illustré dans l’exemple ci­après.

Exemple d’utilisation des ordres INSERT et UPDATE :

4. Manipuler les éléments des collections

Jusqu’à maintenant les instructions montrées permettent simplement de manipuler des collections dans leur globalité, mais rien ne permet de manipuler un élément précis d’une collection.

Pour réaliser ces opérations à l’aide du langage SQL, il faut utiliser la clause TABLE dont la sous­requête retourne une seule colonne dont on va manipuler les données à l’aide des opérations SQL classiques. Dans l’exemple ci­après, une ligne d’informations est ajoutée à la collection stock dans la table dépôt puis la collection Lescommandes de la table Facture est interrogée pour connaître le montant total d’une facture.

Manipuler une ligne de la collection :

- 5 -© ENI Editions - All rigths reserved

Page 194: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Il est également possible de définir des collections non pas dans des tables mais localement dans un bloc PL/SQL, pour faciliter la manipulation et le traitement des données à l’intérieur de ce bloc. Même si la logique de manipulation des collections reste la même, il faut utiliser le mot réservé CAST afin de convertir la collection locale en un type bien précis. Dans l’exemple suivant, le but est de comparer deux collections, l’une est définie localement dans le bloc PL/SQL et l’autre provient d’une table. La valeur retournée correspond au nombre d’écarts entre les deux collections.

Manipuler une collection définie dans le bloc PL/SQL :

5. Les méthodes

Il existe un certain nombre de méthodes qui facilitent le travail avec les collections. Les méthodes sont des fonctions ou des procédures qui travaillent uniquement sur les collections et dont l’appel s’effectue en préfixant le nom de la méthode par le nom de la collection.

Syntaxe

nom_collection.nom_methode[(paramètre, ...)]

Les méthodes ne peuvent pas être utilisées à l’intérieur de commandes SQL.

Seule la méthode EXISTS peut être utilisée sur une collection NULL. L’utilisation de n’importe quelle autre méthode sur une collection NULL provoque la levée de l’exception COLLECTION_IS_NULL.

a. EXISTS

Cette méthode accepte en paramètre l’indice de la collection dont on cherche l’existence. Ainsi nom_collection.EXISTS

- 6 - © ENI Editions - All rigths reserved

Page 195: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

(15) retourne la valeur TRUE si le quinzième élément de la collection existe et retourne FALSE dans le cas contraire. La méthode EXISTS va être utilisée afin d’être sûr de réaliser des opérations conformes sur la collection. Par exemple, pour éviter de supprimer un élément de la collection qui n’existe pas.

Lorsque l’on teste l’existence d’un élément en dehors de la collection, alors la méthode EXISTS retourne FALSE au lieu de lever l’exception SUBSCRIPT_OUTSIDE_LIMIT.

IF MesCommandes.EXISTS(5) THEN MesCommandes(5):=nouvelle_commande; END IF

b. COUNT

La méthode COUNT permet de connaître le nombre d’éléments présents dans la collection. Il est fréquent d’utiliser cette méthode, car le nombre d’éléments contenus dans une collection n’est pas connu a priori, par exemple lorsque la collection est stockée dans la base Oracle.

Attention, dans le cas où l’on applique cette méthode sur une collection de type NESTED TABLE, le nombre d’éléments peut être inférieur à l’indice du plus grand élément, car les collections de ce type acceptent des éléments NULL suite à des suppressions. Avant d’accéder à un élément il faudra donc tester son existence à l’aide de EXISTS.

parcours:=1; i:=1 WHILE(i<MesCommandes.COUNT) LOOP IF MesCommandes.EXISTS(parcours) THEN ... i:=i+1; END IF; parcours:=parcours+1 END LOOP;

c. LIMIT

Pour les collections de type NESTED TABLE, qui n’ont pas de nombre maximum d’éléments, cette méthode retourne NULL. Pour les collections de type VARRAYS, la méthode LIMIT permet de connaître le nombre maximum d’éléments possibles dans la collection.

Par exemple, le type TabCommandes est une collection de 50 élements de type LaCommande, donc, si une collection est définie de type TabCommandes, il est possible d’écrire le code suivant :

i:=1 FOR parcours IN 1 .. MesCommandes.LIMIT LOOP WHILE(i<MesCommandes.COUNT) LOOP IF MesCommandes.EXISTS(parcours) THEN ... i:=i+1; END IF; END LOOP; END LOOP;

d. FIRST, LAST

Les méthodes FIRST et LAST permettent de connaître le plus petit indice de la collection ainsi que le plus grand. Si la collection est vide, alors les méthodes FIRST et LAST retournent la valeur NULL. Bien sûr, si l’indice retourné par ces deux méthodes est le même, cela signifie que la collection ne contient qu’un seul élément.

Pour une collection de type VARRAY, la méthode FIRST retourne toujours 1 et la valeur retournée par LAST est la même que celle retournée par COUNT.

e. PRIOR, NEXT

La méthode PRIOR(i) permet de connaître l’indice de l’élément précédant l’élément d’indice i dans la collection. La

- 7 -© ENI Editions - All rigths reserved

Page 196: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

méthode NEXT(i) permet de connaître l’indice de l’élement suivant. Si l’élément d’indice i est le premier, alors l’appel à PRIOR(i) retourne la valeur NULL. Le résultat est le même lors de l’appel de la méthode NEXT sur le dernier élément de la collection.

L’exemple suivant montre comment il est possible de parcourir tous les éléments d’une collection :

i:=MesCommandes.FIRST; WHILE (i IS NOT NULL) LOOP ... i:=MesCommandes.NEXT(I); END LOOP;

f. EXTEND

Il est possible de modifier la taille d’une collection, en l’agrandissant, par l’intermédiaire de la méthode EXTEND. Cette méthode possède trois formes différentes d’appel :

MaCollection.EXTEND

un élément NULL est ajouté à la collection.

MaCollection.EXTEND(n)

n éléments NULL sont ajoutés à la collection.

MaCollection.EXTEND(n,i)

n éléments sont ajoutés à la collection. Chaque élément contient une copie des valeurs contenues dans l’élément d’indice i.

Exemple d’utilisation de EXTEND :

g. TRIM

Cette méthode, qui permet de supprimer un ou plusieurs éléments à la fin de la collection, peut être utilisée sous les deux formes suivantes :

MaCollection.TRIM

Le dernier élément de la collection est supprimé.

MaCollection.TRIM(n)

Les n derniers éléments de la collection sont supprimés.

Si le nombre d’élément que l’on tente de supprimer est plus important que le nombre d’éléments présents dans la collection (cette valeur est connue par la méthode COUNT), alors l’exception SUBSCRIPT_ BEYOND_COUNT est

levée.

Exemple

- 8 - © ENI Editions - All rigths reserved

Page 197: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Utilisation de TRIM : dans l’exemple ci­après, la méthode TRIM est utilisée pour supprimer les deux derniers éléments de la collection.

h. DELETE

Cette méthode, qui possède trois formes d’appels, permet de supprimer un élément, plusieurs éléments ou la totalité d’une collection.

MaCollection.DELETE

Supprime tous les éléments de la collection.

MaCollection.DELETE(n)

Supprime l’élément numéro n de la collection.

MaCollection.DELETE(n,m)

Supprime tous les éléments dont les indices sont compris entre n et m. Les indices numéros n et m sont inclus. Si n est plus grand que m, alors aucun élément n’est supprimé.

Dans les collections de type VARRAY, il n’est pas possible de supprimer des éléments à l’intérieur de la collection. La seule possibilité est de supprimer le dernier élément.

Si un élément à supprimer n’existe pas, alors la méthode DELETE saute simplement cet élément. Aucune erreur n’est levée.

PL/SQL conserve l’espace mémoire des éléments supprimés, il est donc possible de les remplacer en assignant simplement une nouvelle valeur.

Exemple d’utilisation de DELETE :

i. COLLECT

- 9 -© ENI Editions - All rigths reserved

Page 198: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Cette fonction de calcul d’agrégat permet d’extraire les données d’une colonne et de stocker le résultat sous forme d’une collection. Il est ainsi facile de travailler avec ces données depuis un bloc PL/SQL. Avec cette fonction, il n’est plus nécessaire de passer par un curseur pour travailler avec des informations issues d’une requête d’extraction.

Pour avoir la possibilité de travailler avec le résultat de cette fonction, il est nécessaire d’inclure la fonction COLLECT comme paramètre de la fonction CAST.

Création du tableau destiné à être alimenté par COLLECT :

Valorisation du tableau par la fonction COLLECT :

6. Les exceptions

Dans la plupart des cas, lorsque l’on tente d’accéder à un élément qui n’existe pas dans une collection, PL/SQL lève une exception prédéfinie. Il est intéressant de citer les principales exceptions qui peuvent être levées :

COLLECTION_IS_NULL

La collection n’est pas initialisée.

NO_DATA_FOUND

L’élément accédé n’existe plus.

SUBSCRIPT_BEYOND_COUNT

L’indice de l’élément accédé a été supprimé.

SUBSCRIPT_OUTSIDE_LIMIT

L’indice est en dehors des valeurs autorisées.

- 10 - © ENI Editions - All rigths reserved

Page 199: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

VALUE_ERROR

L’indice est NULL ou n’est pas convertible en un entier.

L’exemple suivant illustre la levée de ces exceptions par PL/SQL.

DECLARE TYPE LaListe IS TABLE OF VARCHAR2(50); LesCourses LaListe; -- initialisé à NULL BEGIN LesCourses(1):=’Carotte’;-- exception COLLECTION_IS_NULL LesCourses:=LaListe(’Tomates’,’Melon’,’Salade’);--initialise la collection LesCourses(NULL):=’Pommes’;-- exception VALUE_ERROR LesCourses(0):=’Poires’;-- exception SUBSCRIPT_OUTSIDE_LIMIT LesCourses(4):=’Kiwis’;-- exception SUBSCRIPT_BEYOND_COUNT LesCourses.DELETE(1);--Suppression de l’élément 1 IF LesCourses(1)=’Choux’ THEN-- Exception NO_DATA_FOUND ... END IF; END;

- 11 -© ENI Editions - All rigths reserved

Page 200: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

La copie des données par blocs

Complètement intégré au SGBDR Oracle, le moteur procédural PL/SQL traite toutes les commandes procédurales et le moteur SQL s’occupe de traiter toutes les commandes SQL. L’interaction entre les deux moteurs est fréquente car le code PL/SQL travaille avec des données issues de la base de données, et extraites par l’intermédiaire de commandes SQL.

Lors de chaque passage du moteur PL/SQL au moteur SQL, et inversement, une charge de travail supplémentaire est demandée au serveur. Afin d’améliorer les performances, il est important de réduire ce nombre de changements de moteur. Les copies de données par blocs offrent une solution pour réduire le nombre d’interactions entre ces deux moteurs.

Répartition du travail entre les deux moteurs :

Avec les copies par blocs, les ordres SQL vont pouvoir concerner toute la collection et non seulement les éléments les uns après les autres.

L’exemple suivant, qui concerne l’insertion de lignes dans une table, permet de comparer le gain de temps entre le traitement classique des ordres SQL dans les blocs PL/SQL et le traitement par blocs.

Création de la table Composants :

La table créée ci­dessus va être remplie par l’intermédiaire d’un bloc PL/SQL. Pour chacune des deux méthodes d’insertion, le temps d’exécution sera mesuré.

Les avantages du traitement par blocs :

- 1 -© ENI Editions - All rigths reserved

Page 201: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Pour traiter tous les éléments d’une collection, il faut utiliser le mot clé FORALL. Son utilisation est détaillée ultérieurement.

L’utilisation du package DBMS_OUTPUT est traité plus loin dans cet ouvrage. Pour pouvoir exécuter ce script correctement, il faut commencer par positionner la variable d’environnement SERVEROUTPUT à On dans SQL*Plus

par l’intermédiaire de la commande : SET SERVEROUTPUT ON.

1. FORALL

Le mot clé FORALL indique au moteur PL/SQL de travailler par blocs avec la collection avant d’envoyer la commande SQL au moteur SQL. Bien que le mot clé FORALL propose une borne de début et de fin, il ne permet pas de mettre en place une boucle FOR.

Syntaxe

FORALL index IN borne_inférieur..borne_supérieur commande_SQL;

La commande SQL doit être un ordre INSERT, UPDATE ou DELETE, qui travaille avec une collection. L’ordre SQL peut tout à fait travailler avec plusieurs collections comme c’est le cas dans l’exemple précédent. Il faut alors utiliser les mêmes indices d’éléments dans les différentes collections.

Exemple

Dans l’écran ci­dessous, on retrouve différents cas d’utilisation de la commande FORALL.

- 2 - © ENI Editions - All rigths reserved

Page 202: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Les copies d’informations par blocs peuvent être effectuées directement dans des collections d’enregistrement. Cette fonctionnalité est offerte à partir d’Oracle 9i. Elle permet de gagner en souplesse au niveau de l’utilisation des données dans un bloc PL/SQL.

L’exemple suivant montre différentes utilisations possibles du travail avec les collections d’enregistrements et plus particulièrement la mise en place de la collection avec des données issues de la base avec les commandes FOR..IN et FORALL.

create table table1(col1 number, col2 char(30)); create table table2(col1 number, col2 char(30)); declare type tableauRec is table of table1%rowtype; type tableauNumerique is table of number; type tableauCaracteres is table of char(30); cursor ctable2 is select col1, col2 from table2; tabrec tableauRec; tabnum tableauNumerique:=tableauNumerique(2,3,5); tabCar tableauCaracteres:=tableauCaracteres(’Godel’,’Escher’,’Bach’); begin -- ajouter des données dans la table1 forall i in 1..3 insert into table1 values (tabnum(i), tabcar(i)); -- ajouter des données dans le tableau des enregistrements select col1, col2 bulk collect into tabrec from table1; -- insérer des données dans la table2 forall i in tabrec.first..tabrec.last insert into table2 values tabrec(i); -- mettre à jour les données dans le tableau des enregistrements for i in tabrec.first..tabrec.last loop tabrec(i).col1:=tabrec(i).col1*2; end loop; -- utilisation du curseur open ctable2; fetch ctable2 bulk collect into tabrec; close ctable2; end; / select * from table1; select * from table2; drop table table1; drop table table2;

a. Limitations

- 3 -© ENI Editions - All rigths reserved

Page 203: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Il n’est possible d’utiliser la commande FORALL que dans les programmes coté serveur.

Les commandes INSERT, UPDATE ou DELETE doivent faire référence à au moins une collection pour pouvoir bénéficier de la commande FORALL.

Il doit exister des éléments dans la collection, pour toutes les valeurs d’indice précisées dans la commande FORALL.

Il n’est pas possible d’exprimer l’indice sous forme d’un calcul.

b. Les transactions et la commande FORALL

À l’intérieur d’une commande FORALL, si l’une des commandes SQL provoque une erreur d’exécution, c’est alors la totalité des instructions réalisées à l’intérieur de la commande FORALL qui est annulée (ROLLBACK).

Cependant, si l’exception qui est levée par un ordre SQL est traitée dans le bloc PL/SQL, alors les opérations réalisées par la commande FORALL sont annulées jusqu’à un point de transaction (SAVEPOINT) qui est marqué de façon implicite après chaque commande SQL. C’est­à­dire que seule la commande SQL qui est à l’origine de l’exception est annulée de façon automatique. C’est dans le code de traitement de l’exception qu’il faudra décider, si l’on conserve les modifications déjà effectuées (COMMIT) ou si l’on annule toute l’instruction FORALL (ROLLBACK).

c. Les clauses INDICES OF et VALUES OF

Le parcours des listes n’est pas toujours aussi facile que dans l’exemple précédent.

Pour pouvoir parcourir une liste sans avoir à tenir compte de l’indice du premier et du dernier élément, il est possible d’utiliser la clause INDICES OF. Cette clause s’avère d’autant plus intéressante que l’on va retrouver uniquement les éléments de la collection même s’il existe des emplacements non valorisés. La clause INDICES OF permet de garantir le parcours complet de la collection sans qu’une exception ne soit levée.

Au contraire, si l’on souhaite parcourir simplement un sous­ensemble d’une collection alors il est nécessaire d’utiliser la clause VALUES OF. Cette clause permet de récupérer les indices depuis une autre collection qui doit être de type NESTED TABLE ou bien un tableau associé à un index numérique. Cette collection est donc une collection de parcours.

2. L’attribut %BULK_ROWCOUNT

Lors de l’exécution des ordres SQL, un curseur est ouvert implicitement par le moteur. Il est possible de tester les attributs %FOUND, %ISOPEN, %NOTFOUND et %ROWCOUNT, pour s’assurer du bon déroulement de la commande SQL.

Le curseur implicite (SQL) possède un attribut supplémentaire : %BULK_ROWCOUNT, qui est utilisé avec une commande FORALL. Cet attribut est en fait une collection de type index by table, pour lequel l’élément numéro i contient le nombre de lignes affectées par l’exécution de l’ordre SQL numéro i. Si aucune ligne n’a été affectée par l’instruction numéro i alors l’attribut SQL%BULK_ROWCOUNT(i) retourne la valeur 0.

Exemple d’utilisation de l’attribut %BULK_ROWCOUNT :

- 4 - © ENI Editions - All rigths reserved

Page 204: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

3. BULK COLLECT

Le mot clé BULK COLLECT indique au moteur SQL que les données seront retournées dans une collection, avant de retourner dans le moteur PL/SQL. Il est possible d’utiliser cette commande avec les clauses SELECT INTO, FETCH INTO et RETURNING INTO.

Syntaxe

... BULK COLLECT INTO nom_collection [,nom_collection, ...]

Exemple

Utilisation de BULK COLLECT : dans l’exemple suivant, les informations extraites depuis la table clients sont conservées dans la collection les Clients.

Il est bien sûr possible de réaliser le même genre d’opération avec un curseur.

Les gains de temps d’exécution des blocs PL/SQL sont spectaculaires pour les volumes de données importants, si l’on travaille avec les collections. Il est facile de ramener les données depuis la table par l’intermédiaire de l’instruction BULK COLLECT. Puis, le traitement des données est effectué directement dans la collection et enfin les modifications sont propagées dans la table en utilisant l’instruction FORALL pour parcourir la collection.

4. LIMIT

La clause optionnelle LIMIT qui est limitée à la copie par blocs depuis un curseur, permet de limiter le nombre de lignes d’informations ramenées lors de chaque FETCH.

Syntaxe

FETCH ... BULK COLLECT INTO ... [LIMIT nombre_lignes]

Le nombre de lignes doit être un nombre entier.

- 5 -© ENI Editions - All rigths reserved

Page 205: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Exemple

Utilisation de LIMIT : dans l’exemple suivant, les lignes sont ramenées par paquets de 10.

5. Comparer les collections

Le travail avec une collection est relativement aisé. Mais très rapidement, il va être nécessaire de travailler avec deux ou plusieurs collections afin de comparer leurs contenus. Avant la version 10g d’oracle, pour pouvoir réaliser ce type de travail, il était nécessaire d’écrire ses propres fonctions de comparaisons. Ce travail, en plus d’être rébarbatif, représente l’inconvénient que la solution optimale est rarement trouvée rapidement, surtout que les parcours de liste et les tests de comparaisons sont des sources d’erreurs communes même pour les programmeurs chevronnés. En introduisant des instructions permettant de travailler avec les collections comme avec des ensembles, Oracle facilite le travail avec ce type de structure.

Les instructions introduites sont : MULTISET UNION, MULTISET UNION DISTINCT, MULTISET INTERSECT, MULTISET EXCEPT et SET. Ces instructions représentent les opérateurs disponibles sur les ensembles pour effectuer l’union, l’intersection, la différence et extraire les éléments distincts.

Pour illustrer le fonctionnement de chacune de ces instructions et comprendre ainsi leur intérêt, on va travailler sur un petit exemple.

Exemples

Un package pkg_test va être créé. Ce package va contenir deux collections et une procédure qui permet d’afficher le contenu de la collection passée en paramètre.

La première étape consiste à définir le type qui va servir de base à la collection.

Ensuite, il est nécessaire de définir l’en­tête du package.

- 6 - © ENI Editions - All rigths reserved

Page 206: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Puis, il faut définir le corps du package afin de donner la définition de la procédure affichée. Cette procédure correspond à un simple parcours de collection en demandant l’affichage de chacune des valeurs.

Maintenant que la base est posée, il est possible d’illustrer les instructions.

Par exemple pour connaître l’ensemble de nos amis il est nécessaire de réaliser une union entre les deux collections. Pour cela, on dispose des instructions MULTISET UNION et MULTISET UNION DISTINCT. La distinction entre ces 2 instructions provient du fait que la première, MULTISET UNION, va retourner l’ensemble des valeurs contenues dans les deux collections sans chercher à éliminer les doublons tandis que la seconde, MULTISET UNION DISTINCT, va permettre d’éliminer les doublons dans la collection résultante.

L’exemple ci­après illustre le résultat de l’exécution de l’instruction MULTISET UNION. On remarque que Dupont apparaît deux fois, en première et en quatrième position.

Au contraire, avec l’instruction MULTISET UNION DISTINCT, les doublons sont éliminés.

Cette fonctionnalité est illustrée par l’exemple ci­dessous dans lequel le nom Dupont n’apparaît qu’une seule fois.

- 7 -© ENI Editions - All rigths reserved

Page 207: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Pour connaître les éléments communs aux deux collections, il faut utiliser MULTISET INTERSECT afin de définir la collection d’intersection.

L’exemple ci­dessus permet d’obtenir la liste des amis communs.

Pour pouvoir faire la différence entre deux collections, il va être nécessaire d’utiliser l’instruction MULTISET EXCEPT.

L’exemple ci­dessus permet de connaître parmi la collection mesAmis ceux qui ne sont connus que par l’autre collection (sesAmis).

Il est bien sûr évident que pour cette instruction l’ordre, dans lequel les collections sont introduites par rapport à l’instruction, possède une influence directe sur le résultat.

Enfin, lorsque l’on travaille avec des collections de grande importance, il est possible d’éliminer les doublons en produisant une nouvelle collection par l’intermédiaire de l’instruction SET.

- 8 - © ENI Editions - All rigths reserved

Page 208: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

La collection résultant de l’union des deux collections initiales possède des doublons. La collection résultante produite par l’instruction SET ne possède quant à elle aucune redondance.

- 9 -© ENI Editions - All rigths reserved

Page 209: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Fonctions et ensemble de lignes

Il est maintenant possible de définir en PL/SQL des fonctions qui acceptent en paramètres d’entrée et/ou qui retournent, non pas une valeur simple mais un ensemble de lignes. L’avantage de ces fonctions est qu’il n’est alors plus nécessaire de stocker les données dans une table temporaire avant d’appeler l’exécution de la fonction. Il est possible d’utiliser de telles fonctions à tous les endroits où il est possible de faire référence à un nom de table et notamment avec la clause FROM d’une requête SELECT.

Afin d’améliorer les temps de réponses de ces fonctions qui retournent un ensemble de données, l’instruction pipelined précise que les données vont être retournées au fur et à mesure de l’exécution de la fonction. C’est d’ailleurs avec ce type de fonction que la gestion des ensembles de valeurs renvoyées est la plus simple.

Lors de la déclaration de la fonction, le mot clé PIPELINED est ajouté dans l’en­tête et les informations sont retournées à l’aide de la commande PIPE ROW.

Ces fonctions peuvent accepter en paramètre d’entrée un ensemble de lignes sous la forme d’une collection (comme un tableau de type VARRAY) ou bien sous la forme d’un REF CURSOR (référence à un curseur).

Exemple

L’exemple suivant montre la mise en place d’une fonction qui retourne une collection de chiffres en mode pipelined c’est­à­dire au fur et à mesure de l’exécution de la fonction.

SQL> -- création du type SQL> create type MtLigne as object( 2 nolig number(2), 3 montant number(12,2) 4 ); 5 / Type créé. SQL> -- création de la table SQL> create type MtLignesTab as table of MtLigne; 2 / Type créé. SQL> -- exemple de fct pipelined SQL> create or replace function LigneVal (clig in SYS_REFCURSOR) 2 return MtLignesTab pipelined is 3 out_mt MtLigne:=MtLigne(NULL, NULL); 4 vlig ligcdes%rowtype; 5 vprix number(12,2); 6 vmontant number(12,2); 7 BEGIN 8 loop 9 fetch clig into vlig; 10 exit when clig%notfound; 11 -- prix de chaque article 12 select prix into vprix 13 from articles 14 where refart=vlig.refart; 15 -- calcul du montant de la ligne 16 vmontant:=vlig.qtecde*vprix; 17 -- construire la valeur à retourner 18 out_mt.nolig:=vlig.nolig; 19 out_mt.montant:=vmontant; 20 -- retourner la valeur 21 pipe row(out_mt); 22 end loop; 23 return; 24 END; 25 / Fonction créée. SQL> -- utilisation de la fct pipelined SQL> select sum(montant) as total 2 from table(LigneVal(CURSOR(select * from ligcdes where

- 1 -© ENI Editions - All rigths reserved

Page 210: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

nocde=1301))); TOTAL ---------- 750

- 2 - © ENI Editions - All rigths reserved

Page 211: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

L’utilitaire Wrap

L’utilitaire Wrap est un programme qui permet de coder le code source PL/SQL. Il est ainsi possible de distribuer du code PL/SQL sans que les utilisateurs puissent avoir accès au code source.

Wrap va donc permettre de masquer l’algorithme utilisé mais en aucun cas les chaînes de caractères, les nombres, le nom des variables, des colonnes et des tables ne sont codés. L’utilitaire ne permet donc pas de masquer les mots de passe ou bien les noms des tables.

Cet utilitaire est entièrement compatible avec Oracle. La compatibilité descendante n’est pas assurée.

Cet utilitaire accepte deux paramètres :

iname

Permet de préciser le fichier qui contient le code PL/SQL qui va être codé.

oname (optionnel)

Permet de spécifier le nom du fichier qui va contenir la version codée du fichier précisé à l’aide de iname. Par défaut, ce fichier de sortie porte l’extension plb.

Syntaxe

wrap iname=fichier_entrée [oname=fichier_sortie]

Exemple d’utilisation de l’utilitaire Wrap

Quelques éléments de la nouvelle syntaxe SQL ne sont pas supportés en standard. Pour que tous les éléments de la nouvelle syntaxe soit supportés, il faut utiliser le paramètre edebug=wrap_new_sql.

- 1 -© ENI Editions - All rigths reserved

Page 212: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

DBMS_OUTPUT

Le package DBMS_OUTPUT permet d’envoyer des messages depuis une procédure, une fonction, un package ou un déclencheur (trigger) de base de données. Les procédures PUT et PUT_LINE de ce package permettent de placer des informations dans un tampon qui pourra être lu par un autre bloc PL/SQL qui utilisera la procédure GET_LINE pour récupérer l’information.

Si la récupération et l’affichage des informations placées dans le tampon ne sont pas gérés et si l’exécution ne se déroule pas sous SQL*Plus, alors les informations sont ignorées. Le principal intérêt de ce package est de faciliter

la mise au point des programmes.

Enterprise Manager et SQL*Plus possèdent le paramètre SERVEROUTPUT qu’il faut activer à l’aide de la commande SET SERVEROUTPUT ON pour connaître les informations qui ont été écrites dans le tampon après l’exécution d’une

commande INSERT, UPDATE, DELETE, d’une fonction, d’une procédure ou d’un bloc PL/SQL anonyme.

1. ENABLE

Cette procédure permet d’activer les appels aux procédures PUT, PUT_LINE, NEW_LINE, GET_LINE et GET_LINES. L’appel à cette procédure sera ignoré si le package DBMS_OUTPUT n’est pas activé.

Il n’est pas nécessaire de faire appel à cette procédure lorsque le paramètre SERVEROUTPUT est fixé depuis Enterprise Manager ou SQL*Plus.

Syntaxe

DBMS_OUTPUT.ENABLE (taille_tampon IN INTEGER DEFAULT 20000) ;

La taille du tampon est au maximum de 1 000 000 d’octets et au minimum de 2 000 octets.

Si plusieurs appels à cette procédure sont effectués, alors c’est la taille maximale du tampon qui est retenue.

2. DISABLE

Cette procédure permet de désactiver les appels aux procédures PUT, PUT_LINE, NEW_LINE, GET_LINE et GET_LINES et vide le tampon de toutes les informations qu’il contient.

Il n’est pas nécessaire de faire appel à cette procédure lorsque le paramètre SERVEROUTPUT est fixé depuis Enterprise Manager ou SQL*Plus.

Syntaxe

DBMS_OUTPUT.DISABLE

Cette procédure ne possède aucun paramètre.

3. PUT et PUT_LINE

Il est possible de placer directement une ligne d’informations dans le tampon à l’aide de PUT_LINE, ou bien de construire petit à petit la ligne d’informations en plaçant les informations les unes à la suite des autres dans le tampon par l’intermédiaire de la commande PUT. Ces deux procédures permettent de placer indifféremment dans le tampon des données de type caractère (VARCHAR2), de type numérique (NUMBER) ou de type DATE.

Dans tous les cas, les données sont converties au format chaîne de caractères. Les données de type numérique ou date sont formatées en utilisant la fonction de conversion TO_CHAR et en utilisant les formats de conversion par défaut. Si l’on souhaite obtenir d’autres formats de conversion, alors il faut convertir les données en chaîne de caractères avant de placer ces données dans le tampon.

- 1 -© ENI Editions - All rigths reserved

Page 213: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

La procédure PUT_LINE permet d’insérer automatiquement le marqueur de fin de ligne après chaque ajout d’informations dans le tampon. Au contraire, avec l’utilisation de la procédure PUT, il faudra insérer les marqueurs de fin de ligne par l’appel à la procédure NEW_LINE. En effet, les procédures GET_LINE et GET_LINES, qui permettent de lire les informations placées dans le tampon, ne sont capables de lire que les lignes d’informations qui se terminent par un marqueur de fin de ligne.

Si le volume des données à placer dans le tampon est supérieur à la taille du tampon alors une erreur est levée.

Syntaxe

DBMS_OUTPUT.PUT(element IN NUMBER) ; DBMS_OUTPUT.PUT(element IN VARCHAR2) ; DBMS_OUTPUT.PUT(element IN DATE) ; DBMS_OUTPUT.PUT_LINE(element IN NUMBER) ; DBMS_OUTPUT.PUT_LINE(element IN VARCHAR2) ; DBMS_OUTPUT.PUT_LINE(element IN DATE) ;

4. NEW_LINE

Cette procédure permet de placer un marqueur de fin de ligne dans le tampon.

Syntaxe

DBMS_OUTPUT.NEW_LINE ;

5. GET_LINE et GET_LINES

Il est possible de lire depuis le tampon une ligne simple d’informations en utilisant la procédure GET_LINE, ou bien de ramener un tableau de lignes par l’intermédiaire de la procédure GET_LINES.

Après la lecture du tampon par les procédures GET_LINE ou GET_LINES, toutes les lignes non lues encore présentes dans le tampon lors de l’appel suivant à PUT, PUT_LINE ou NEW_LINE sont supprimées afin d’éviter

toute confusion possible d’informations.

Syntaxe

DBMS_OUTPUT.GET_LINE( ligne OUT VARCHAR2, état OUT INTEGER) DBMS_OUTPUT.GET_LINES(lignes OUT CHARARR, nb_lignes OUT INTEGER)

Les paramètres sont les suivants :

ligne

Contient une seule ligne d’informations en provenance du tampon. Le marqueur de fin de ligne n’est pas contenu dans la ligne retournée. La longueur maximale de cette ligne est de 255 caractères.

état

Si l’appel a été un succès, alors l’état contient la valeur 0 et il contient 1 lorsque le tampon ne contient plus aucune ligne d’informations.

lignes

C’est un tableau de VARCHAR2(255).

nb_lignes

Nombre de lignes d’informations contenues dans le tableau.

Le package DBMS_OUTPUT est, en règle générale, utilisé pour la mise au point des fonctions et des procédures

- 2 - © ENI Editions - All rigths reserved

Page 214: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

stockées, car l’affichage des informations placées dans le tampon est automatique depuis SQL*Plus.

Exemple

Fonction utilisant le package DBMS_OUTPUT : dans l’exemple suivant, on souhaite mettre au point cette fonction qui permet de calculer le montant d’une commande à partir de son numéro.

Puis il faut exécuter cette fonction depuis SQL*Plus :

- 3 -© ENI Editions - All rigths reserved

Page 215: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Le package UTL_FILE

Le package PL/SQL UTL_FILE permet aux programmes PL/SQL de travailler en lecture et écriture avec des fichiers texte du système de fichiers. Le flux d’entré/sortie ouvert vers le système d’exploitation est limité au seul travail avec ces fichiers.

Ce package est utilisable pour du code PL/SQL écrit aussi bien côté client que sur le serveur. L’exécution côté client est soumise aux règles de sécurité du système d’exploitation côté client pour accéder et utiliser le système de fichiers. Côté serveur, l’exécution du programme PL/SQL qui travaille avec le package UTL_FILE, doit être réalisée dans un mode de sécurité privilégié, et d’autres options de sécurité limitent la possibilité des actions menées au travers de UTL_FILE.

En effet, côté serveur, les répertoires accessibles par UTL_FILE doivent être précisés dans le fichier des paramètres (INIT.ORA) par l’intermédiaire du paramètre UTL_FILE_DIR.

Syntaxe

UTL_FILE_DIR=c:\temp.

Pour rendre tous les répertoires accessibles par UTL_FILE côté serveur, il faut préciser le paramètre suivant dans le fichier INIT.ORA : UTL_FILE_DIR=*

À partir la version 9i il est préférable d’utiliser la commande CREATE DIRECTORY pour gérer les répertoires accessibles depuis le package UTL_FILE à la place du paramètre d’initialisation UTL_FILE_DIR.

Il est possible de connaître la liste des répertoires définis sur le serveur à l’aide de la vue ALL_DIRECTORIES.

Syntaxe

CREATE OR REPLACE DIRECTORY nom_repertoire AS ’chemin’;

Un exemple d’utilisation de cette instruction est donné dans l’exemple récapitulatif du package.

1. FOPEN, FOPEN_NCHAR

Cette fonction permet d’ouvrir un fichier en vue d’effectuer des opérations de lecture ou d’écriture. Le chemin d’accès au fichier doit correspondre à un répertoire valide et accessible, c’est­à­dire tel que précisé par le paramètre UTL_FILE_DIR, ou bien à un répertoire défini à l’aide de CREATE DIRECTORY.

Le chemin complet d’accès doit exister, et FOPEN ne peut pas créer de répertoires.

La fonction FOPEN retourne un pointeur sur le fichier. Ce pointeur devra être précisé pour l’ensemble des opérations de lecture/écriture qui seront effectuées par la suite.

Il n’est pas possible d’ouvrir plus de 50 fichiers de façon simultanée.

Syntaxe

UTL_FILE.FOPEN( chemin IN VARCHAR2, nom_fichier IN VARCHAR2, mode_ouverture IN VARCHAR2) RETURN UTL_FILE.FILE_TYPE ;

chemin

Chemin d’accès au répertoire du système d’exploitation qui contient le fichier à ouvrir.

nom_fichier

Nom du fichier avec son extension, sans aucune information concernant le chemin d’accès.

mode_ouverture

- 1 -© ENI Editions - All rigths reserved

Page 216: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Chaîne de caractères précisant le mode d’ouverture du fichier. Les valeurs possibles peuvent être :

­ r ouverture du fichier en lecture seule.

­ w ouverture du fichier en mode écriture.

­ a ouverture d’un fichier existant en mode ajout.

Lors de l’ouverture en mode a (ajout) d’un fichier qui n’existe pas, alors il est créé et ouvert en mode w (écriture).

La fonction FOPEN peut lever les exceptions suivantes : INVALID_PATH, INVALID_MODE ou INVALID_OPERATION.

Le fonction FOPEN_NCHAR qui accepte les mêmes paramètres que la fonction FOPEN permet d’ouvrir un fichier en mode UNICODE pour les lectures et les écritures. Avec cette méthode il est alors possible de lire et d’écrire un fichier en UNICODE au lieu d’utiliser le jeu de caractères de la base de données.

2. IS_OPEN

La fonction IS_OPEN a pour but de tester si un pointeur de fichier correspond à un flux vers un fichier qui a bien été ouvert et non encore fermé. La fonction IS_OPEN permet de tester la validité au niveau du package UTL_FILE et ne permet en aucun cas d’être sûr que l’opération se déroulera sans problème de la part du système d’exploitation.

Si le pointeur de fichier passé en paramètre correspond à un flux ouvert, alors la fonction IS_OPEN retourne la valeur TRUE, sinon elle retourne FALSE.

Syntaxe

UTL_FILE.IS_OPEN( ptr_fichier IN FILE_TYPE) RETURN BOOLEAN ;

3. FCLOSE

Cette procédure permet de fermer proprement un flux vers un fichier, et de s’assurer que les données situées dans le tampon d’écriture sont bien enregistrées dans le fichier avant de fermer le flux vers celui­ci. Si des données sont encore présentes dans le tampon au moment de la fermeture du fichier, alors la fonction FCLOSE lève l’erreur WRITE_ERROR.

Syntaxe

UTL_FILE.FCLOSE(ptr_fichier IN OUT FILE_TYPE) ;

4. FCLOSE_ALL

Cette procédure permet de fermer tous les flux vers des fichiers qui ont été ouverts au cours de la session actuelle. Cette procédure ne doit être exécutée qu’avec parcimonie, par exemple lorsque l’on sort du bloc PL/SQL suite à une levée d’exception.

De plus, la fonction FCLOSE_ALL n’affecte pas l’état des autres pointeurs de fichiers détenus par le même utilisateur. C’est­à­dire que la fonction IS_OPEN, continuera à retourner vrai (TRUE) lors du test du flux, mais que toute tentative d’utilisation de ce flux, soit en lecture, soit en écriture, est vouée à l’échec.

Syntaxe

ULT_FILE.FCLOSE_ALL ;

5. GET_LINE, GET_LINE_NCHAR, GET_RAW

Cette procédure permet de lire une ligne entière de texte depuis le fichier identifié par le pointeur qui lui est passé en paramètre, et retourne cette ligne d’informations dans une variable tampon qui lui est également passée en

- 2 - © ENI Editions - All rigths reserved

Page 217: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

paramètre. On trouve dans cette variable tampon, l’intégralité du texte sans le marqueur de fin de ligne ou de fin de fichier (pour la lecture de la dernière ligne).

Cette procédure n’est autorisée que si le fichier a été ouvert en mode lecture (r). Dans tous les autres cas, l’exception INVALID_OPERATION est levée.

Si la ligne est trop grande pour être contenue intégralement dans la variable tampon, alors une exception VALUE_ERROR est levée. Au contraire, si l’on tente de lire le texte situé après la marque de fin de fichier, alors une exception de type NO_DATA_FOUND est levée.

Comme le marqueur de fin de ligne n’est pas contenu dans la variable tampon, lors de la lecture, une ligne blanche se traduit par une chaîne vide.

Syntaxe

UTL_FILE.GET_LINE( ptr_fichier IN FILE_TYPE, tampon OUT NVARCHAR2, longuer_ligne IN NUMBER, octets_a_lire IN PLS_INTEGER DEFAULT NULL);

L’opération GET_LINE_NCHAR permet de lire du texte au format UNICODE depuis un fichier ouvert à l’aide de FOPEN_NCHAR.

Syntaxe

UTL_FILE.GET_LINE_NCHAR( ptr_fichier IN FILE_TYPE, tampon OUT NVARCHAR2, octets_a_lire IN PLS_INTEGER DEFAULT NULL);

L’opération GET_RAW va, quant à elle, permettre de lire des données de type RAW depuis un fichier.

Syntaxe

UTL_FILE.GET_LINE_RAW( ptr_fichier IN FILE_TYPE, tampon OUT NOCOPY RAW, octets_a_lire IN PLS_INTEGER DEFAULT NULL);

6. PUT, PUT_NCHAR, PUT_RAW

La procédure PUT permet d’écrire le texte contenu dans une variable tampon vers le fichier. Le fichier doit bien entendu avoir été ouvert en mode écriture (w ou a). Aucun marqueur de fin de ligne n’est ajouté de façon automatique. Il faudra faire appel à la procédure NEW_LINE pour ajouter ce caractère de fin de ligne ou bien à la procédure PUT_LINE pour compléter la ligne en cours et la terminer.

Syntaxe

UTL_FILE.PUT ( ptr_fichier IN FILE_TYPE, tampon IN VARCHAR2) ;

La procédure PUT_NCHAR permet d’écrire une chaîne de caractères UNICODE dans un fichier. La taille maximum du tampon est de 32767 octets. La syntaxe de cette procédure est identique à celle de PUT à l’exception du fait que le tampon est de type NVARCHAR2.

La procédure PUT_RAW donne la possibilité d’inscrire des données de type RAW dans un fichier. Il est possible de réclamer un vidage automatique du tampon à l’aide du troisième paramètre.

Syntaxe

UTL_FILE.PUT_RAW( ptr_fichier IN FILE_TYPE, tampon IN RAW, vidageauto IN BOOLEAN DEFAULT FALSE);

- 3 -© ENI Editions - All rigths reserved

Page 218: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

7. NEW_LINE

Cette procédure permet d’ajouter un ou plusieurs caractères de fin de ligne au fichier. Cette procédure est à utiliser pour terminer une ligne écrite à l’aide de la procédure PUT. Le nombre de caractères de fin de ligne ajoutés par défaut est un.

Syntaxe

UTL_FILE.NEW_LINE( ptr_fichier IN FILE_TYPE, nombre IN NATURAL :=1) ;

8. PUT_LINE

Contrairement à la procédure PUT, cette procédure permet d’ajouter une ligne d’informations et son marqueur de fin au fichier. Cette procédure peut être utilisée pour écrire une ligne dans sa totalité ou pour continuer et terminer une ligne dont l’écriture a commencé avec la procédure PUT.

Syntaxe

UTL_FILE.PUT_LINE( ptr_fichier IN FILE_TYPE, tampon IN VARCHAR2) ;

9. PUTF, PUTF_NCHAR

Cette procédure correspond à la procédure PUT, mais il est possible de formater les données. Son fonctionnement est similaire à celui de la fonction printf du langage C. Il est possible d’écrire dans le fichier n’importe quel texte, mais les caractères suivants possèdent un sens particulier :

%s : Ce caractère est remplacé par le paramètre de type caractère qui lui correspond.

\n : Ce caractère permet de marquer la fin d’une ligne.

Syntaxe

UTL_FILE.PUTF( ptr_fichier IN FILE_TYPE, tampon_formaté IN VARCHAR2[, param1 IN VARCHAR2 DEFAULT NULL, ... param5 IN VARCHAR2 DEFAULT NULL]);

Les paramètres sont optionnels. Ils sont au maximum au nombre de cinq. Le premier paramètre vient se substituer à la première occurrence du caractère %s trouvée dans la chaîne tampon, le deuxième à la deuxième occurrence et ainsi de suite.

Exemple

Utilisation de PUTF :

- 4 - © ENI Editions - All rigths reserved

Page 219: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

L’exemple suivant effectue le même travail mais il utilise un objet de type DIRECTORY pour accéder au système de fichiers.

create directory "file_dir" as ’c:\temp’; DECLARE -- TYPE ptr_fichier IS RECORD (id BINARY_INTEGER); f_out UTL_FILE.FILE_TYPE; BEGIN -- ouvrir le ficchier f_out:=UTL_FILE.FOPEN(’file_dir’,’test.txt’,’w’); -- ecrire une ligne UTL_FILE.PUT(f_out,’Ceci est un exemple’); -- positionner une fin de ligne UTL_FILE.NEW_LINE(f_out); -- ecrire une ligne complète UTL_FILE.PUT_LINE(f_out,’ligne2’); -- écriture formatée de 2 lignes UTL_FILE.PUTF(f_out,’Bonjour\n Exemple de %s\n’,’la procédure PUTF’); UTL_FILE.FFLUSH(f_out); -- fermer le fichier UTL_FILE.FCLOSE(f_out); END; /

La procédure PUTF_NCHAR permet, quant à elle, l’écriture de chaînes de caractères UNICODE dans le fichier de destination.

10. FFLUSH

Cette procédure permet d’écrire physiquement les données dans les fichiers, notamment celles qui se trouvent dans le tampon d’écriture. En effet, normalement toutes les écritures vers les fichiers sont buffeurisées afin d’optimiser les performances du disque. La procédure FFLUSH, permet de vider ce buffeur. Naturellement les données doivent se terminer par un caractère de fin de ligne.

11. FSEEK, FGETPOS

La procédure FSEEK permet de se déplacer dans le fichier, en avant ou en arrière, du nombre d’octets désiré. Le déplacement peut être absolu, le paramètre offset_absolu prend alors l’adresse sur laquelle il faut se positionner, la valeur par défaut est null.

Dans le cas d’un déplacement relatif, c’est le troisième paramètre (offset_ relatif) qui contient le nombre d’octets dont il faut se déplacer. Si ce nombre est positif, alors le déplacement a lieu vers l’avant, si le nombre est négatif alors le déplacement a lieu vers l’arrière.

Syntaxe

- 5 -© ENI Editions - All rigths reserved

Page 220: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

UTL_FILE.FSEEK( ptr_fichier IN FILE_TYPE, offset_absolu IN PL_INTEGER DEFAULT NULL, offset_relatif IN PL_INTEGER DEFAULT NULL);

La fonction FGETPOS permet de connaître l’offset de la position courante dans le fichier.

Syntaxe

UTL_FILE.FGETPOS(ptr_fichier IN FILE_TYPE) RETURN PLS_INTEGER;

12. FREMOVE, FCOPY, FRENAME

Ces procédures permettent de réaliser un certain nombre d’opérations sur les fichiers du système d’exploitation lorsque l’accès au répertoire a été accordé.

Ces procédures apportent une certaine souplesse dans la gestion des fichiers extérieurs à la base de données et complètent la notion de DIRECTORY (répertoire) qui est introduite à partir de la version 9i.

L’emplacement est le nom d’un objet de type DIRECTORY qui a été créé à l’aide de la méthode CREATE DIRECTORY.

Syntaxe

UTL_FILE.FRENAME( emplacement IN VARCHAR2, nom_fichier IN VARCHAR2); UTL_FILE.FCOPY( repertoire_origine IN VARCHAR2, nom_fichier_origine IN VARCHAR2, repertoire_destination IN VARCHAR2, nom_fichier_destination IN VARCHAR2, numero_ligne_debut IN PLS_INTEGER DEFAULT 1, numero_ligne_fin IN PLS_INTEGER DEFAULT NULL); UTL_FILE_FRENAME( repertoire_origine IN VARCHAR2, nom_fichier_origine IN VARCHAR2, repertoire_destination IN VARCHAR2, nom_fichier_destination IN VARCHAR2, ecraser IN BOOLEAN DEFAULT FALSE);

13. FGETATTR

Cette procédure permet de lire et de retourner les attributs courants d’un fichier.

Syntaxe

UTL_FILE.FGETATTR( ptr_fichier IN FILE_TYPE, existe OUT BOOLEAN, taille_fichier OUT NUMBER, taille_block OUT NUMBER);

14. Les exceptions

Les principales exceptions qui peuvent être levées lors de l’exécution de ce package sont :

INVALID_PATH

Chemin d’accès ou nom de fichier incorrect.

INVALID_MODE

- 6 - © ENI Editions - All rigths reserved

Page 221: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Le mode d’ouverture du fichier précisé dans FOPEN est incorrect.

INVALID_FILEHANDLE

Le pointeur vers le fichier est invalide.

INVALID_OPERATION

Il est impossible de travailler avec le fichier.

READ_ERROR

Une erreur du système d’exploitation est survenue durant la lecture du fichier.

WRITE_ERROR

Une erreur du système d’exploitation est survenue durant une opération d’écriture sur le fichier.

INTERNAL_ERROR

Ereur PL/SQL non spécifiée.

CHARSETMISMATCH

Un fichier a été ouvert au moyen de la méthode FOPEN_NCHAR mais les opérations suivantes n’utilisent pas forcement les chaînes de caractères comme PUTF ou GET_LINE.

FILE_OPEN

Echec de l’opération car le fichier est ouvert.

INVALID_MAXLINESIZE

La valeur du paramètre MAX_LINESIZE lors de l’exécution de FOPEN est incorrecte. Ce paramètre doit être compris entre 1 et 32767.

INVALID_FILENAME

Le nom du fichier n’est pas correct.

ACCESS_DENIED

Permission d’accès au fichier refusée.

INVALID_OFFSET

Position incorrecte. La position passée en paramètre de la méthode FSEEK doit être plus grande que 0 est inférieure au nombre total d’octets dans le fichier.

DELETE_FAILED

Échec de suppression du fichier.

RENAME_FAILED

Échec lors de la tentative de changement de nom du fichier.

Les procédures du package vont également lever des exceptions Oracle prédéfinies comme NO_DATA_FOUND ou VALUE_ERROR.

- 7 -© ENI Editions - All rigths reserved

Page 222: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Le package DBMS_LOB

Les initiales LOB permettent d’identifier les objets de grande dimension (Large OBject).

Le travail avec les éléments de grande dimension (BLOB : Binary LOB, CLOB : Character LOB, NCLOB : uNicode CLOB et BFILE: fichier binaire) n’est pas aussi facile qu’avec les données de type plus classique (caractère, nombre, date). Le langage PL/SQL permet de travailler avec ces données à partir du moment où elles sont présentes dans la base mais les opérations de chargement depuis un fichier du système d’exploitation de comparaison ou de modification ne peuvent être réalisées qu’à l’aide du package DBMS_LOB.

1. Les constantes

Les constantes suivantes sont définies dans le package DBMS_LOB. Leur utilisation permet de clarifier l’utilisation des différentes fonctions et procédures du package.

file_readonly CONSTANT BINARY_INTEGER :=0; lob_readonly CONSTANT BINARY_INTEGER :=0; lob_readwrite CONSTANT BINARY_INTEGER :=1; lobmaxsize CONSTANT INTEGER :=4294967295; call CONSTANT PLS_INTEGER :=12; session CONSTANT PLS_INTEGER :=10;

2. APPEND

Cette procédure permet d’ajouter la totalité de la variable LOB d’origine à la variable LOB de destination.

Syntaxe

DBMS_LOB.APPEND( destination IN OUT NOCOPY BLOB, source IN BLOB); DBMS_LOB.APPEND( destination IN OUT NOCOPY CLOB CHARACTER SET ANY_CS, source IN CLOB CHARACTER SET destination%CHARSET);

3. CLOSE

Cette procédure permet de fermer un élément LOB interne ou externe qui a été ouvert précédemment.

Syntaxe

DBMS_LOB.CLOSE( lob_origine IN OUT NOCOPY BLOB | lob_origine IN OUT NOCOPY CLOB CHARACTER SET ANY CS | fichier_origine IN OUT NOCOPY BFILE);

4. COMPARE

Cette fonction permet de comparer deux LOB dans leur totalité ou partiellement. Il est uniquement possible de comparer des LOB de même type (BLOB, CLOB ou BFILE). Pour les fichiers (BFILE) les éléments doivent être ouverts avec FILEOPEN, avant leur comparaison.

La fonction COMPARE retourne 0 si les deux éléments à comparer sont parfaitement identiques et une valeur différente de zéro dans le cas contraire.

Syntaxe

DBMS_LOB.COMPARE( lob1 IN BLOB|CLOB CHARACTER SET ANY_CS|BFILE, lob2 IN BLOB|CLOB CHARACTER SET ANY_CS|BFILE, nombre_octets_a_comparer NUMBER :=4294967295, octet_origine1 IN INTEGER:=1,

- 1 -© ENI Editions - All rigths reserved

Page 223: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

octet_origine2 IN INTEGER:=1);

5. COPY

Cette procédure permet de réaliser la copie totale ou partielle depuis un LOB d’origine vers un LOB de destination. Dans le cas d’une copie partielle il est possible de préciser la longueur (en nombre d’octets) à copier ainsi que les adresses dans le LOB d’origine et de destination.

Syntaxe

DBMS_LOB.COPY( lob_destination IN OUT NOCOPY BLOB|CLOB CHARACTER SET ANY_CS, lob_origine INBLOB|CLOB CHARACTER SET lob_destination%CHARSET, octets_a_copier IN INTEGER, adr_destination IN INTEGER:=1, adr_origine IN INTEGER:=1);

6. CREATETEMPORARY, FREETEMPORARY, ISTEMPORARY

La procédure CREATETEMPORARY permet de créer un CLOB ou un BLOB temporaire. L’espace nécessaire est pris sur le tablespace temporaire.

Le paramètre cache permet de dire si le LOB doit être lu ou non depuis le tampon mémoire.

Le troisième paramètre permet d’indiquer si l’élément est temporaire à la session (par défaut) ou bien à l’appel.

Syntaxe

DBMS_LOB.CREATETEMPORARY( lob_origine IN OUT NOCOPY BLOB|CLOB CHARACTER SET ANY_CS, cache IN BOOLEAN, validite IN PLUSIEURS_INTEGER:=10);

La procédure FREETEMPORARY permet de libérer un objet temporaire de type CLOB ou BLOB créé à l’aide de CREATETEMPORARY. Il est bien sûr recommandé de ne pas attendre la fin de la session ou de l’appel pour que l’objet temporaire soit supprimé mais de libérer l’espace qu’il occupe sur le tablespace temporaire le plus rapidement possible à l’aide de la procédure FREETEMPORARY.

Syntaxe

DBMS_LOB.FREETEMPORARY( lob_origine IN OUT NOCOPY BLOB|CLOB CHARACTER SET ANY_CS);

Enfin la fonction ISTEMPORARY qui retourne un booléen permet de savoir si l’élément LOB passé en paramètre est temporaire ou non.

Syntaxe

DBMS_LOB.ISTEMPORARY( lob_origine IN OUT NOCOPY BLOB|CLOB CHARACTER SET ANY_CS) return INTEGER;

Exemple

L’exemple ci­dessous montre la mise en place de ces trois méthodes concernant les éléments LOB temporaires.

SQL> declare 2 b blob; 3 c clob; 4 begin 5 -- creation des éléments temporaires 6 dbms_lob.createtemporary(b, true); 7 dbms_lob.createtemporary(c,true); 8 -- test et suppression 9 if (dbms_lob.istemporary(b)=1) then 10 dbms_lob.freetemporary(b); 11 end if; 12

- 2 - © ENI Editions - All rigths reserved

Page 224: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

13 if (dbms_lob.istemporary(c)=1) then 14 dbms_lob.freetemporary(c); 15 end if; 16 end; 17 / Procédure PL/SQL terminée avec succès.

7. ERASE

Cette procédure a pour but d’effacer totalement ou partiellement un objet LOB. Dans le cas d’une suppression partielle il est nécessaire de préciser le nombre d’octets à supprimer ainsi que l’adresse de départ.

Syntaxe

DBMS_LOB.ERASE( lob_origine IN OUT NOCOPY BLOB|CLOB CHARACTER SET ANAY_CS, octets_a effacer IN OUT NOCOPY INTEGER, adr_depart IN INTEGER:=1);

La taille d’un LOB n’est pas réduite lorsqu’une partie seulement est effacée. Pour réduire cette taille, il faut utiliser la procédure TRIM.

8. FILEOPEN, FILECLOSE, FILECLOSEALL et ISOPEN

La procédure FILEOPEN permet d’ouvrir un fichier afin d’y effectuer des lectures. Il n’est pas possible d’écrire dans un fichier ouvert à l’aide de cette procédure.

Syntaxe

DBMS_LOB.FILEOPEN( ptr_fichier IN OUT NOCOPY BFILE, mode_ouverture IN BINARY_INTEGER:=file_readonly);

Les procédures FILECLOSE et FILECLOSEALL permettent de fermer un fichier particulier ou tous les fichiers qui ont été utilisés dans le cadre du travail avec les éléments de grande dimension à l’aide du package DBMS_LOB.

Syntaxe

DBMS_LOB.FILECLOSE(fichier IN OUT NOCOPY BFILE); DBMS_LOB.FILECLOSEALL();

Enfin, la fonction ISOPEN qui retourne un entier, permet de savoir si un élément LOB est ouvert ou non.

Syntaxe

DBMS_LOB.ISOPEN( element_lob IN BLOB|CLOB CHARACTER SET ANY_CS|BFILE) RETURN INTEGER;

9. FILEEXIST, FILEISOPEN

Cette fonction retourne un entier indiquant si le fichier existe ou non. Il est intéressant de faire appel à cette fonction avant de commencer à travailler avec le fichier, car on peut ainsi éviter de lever un certain nombre d’exceptions. Cette fonction vérifie simplement l’existence physique du fichier.

La fonction retourne 0 si le fichier n’existe pas physiquement et 1 dans le cas contraire.

Syntaxe

DBMS_LOB.FILEEXISTS(ptr_fichier IN BFILE) RETURN INTEGER;

- 3 -© ENI Editions - All rigths reserved

Page 225: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

La fonction FILEISOPEN permet de déterminer si un pointeur de fichier (objet BFILE) correspond à un fichier ouvert (la valeur 1 est retournée) ou non (la valeur 0 est retournée).

Syntaxe

DBMS_LOB.FILEISOPEN(ptr_fichier IN BFILE) RETURN INTEGER;

10. FILEGETNAME

Cette procédure permet de connaître l’emplacement et le nom du fichier correspondant à un objet de type BFILE. Cette procédure n’indique en aucun cas si le répertoire et le fichier existent physiquement.

Syntaxe

DBMS_LOB.FILEGETNAME( fichier IN BFILE, repertoire OUT VARCHAR2, nomfichier OUT VARCHAR2);

11. GETLENGTH, GETCHUNKSIZE

La fonction GETLENGTH permet de connaître la taille de l’élément LOB, BLOB ou BFILE passé en paramètre. La taille est un nombre entier qui correspond au nombre d’octets de l’élément passé en paramètre.

Syntaxe

DBMS_LOB.GETLENGTH( lob_loc IN BLOB | lob_loc IN CLOB CHARACTER SET ANY_CS | file_loc IN BFILE) RETURN INTEGER;

La fonction GETCHUNKSIZE permet quant à elle de connaître la taille réellement utilisée pour le stockage des informations de l’élément LOB à l’intérieur des morceaux (CHUNCK) d’espace physique accordés au LOB. Cette taille est exprimée en octets.

Syntaxe

DBMS_LOB.GETCHUNCKSIZE( lob_loc IN BLOB | lob_loc IN CLOB CHARACTER SET ANY_CS | file_loc IN BFILE) RETURN INTEGER;

12. INSTR

Cette fonction retourne un entier correspondant à la nième occurrence de l’élément cible recherché. Le numéro de l’occurrence est indiqué par le paramètre nième, et la cible est contenue dans le paramètre cible. La recherche commence dans l’élément LOB à partir d’une adresse de départ absolue contenue dans le paramètre adr_depart et qui correspond à un nombre d’octets ou de caractères suivant la nature de l’élément LOB.

Syntaxe

DBMS_LOB.INSTR( element_lob IN BLOB, cible IN RAW, adr_depart IN INTEGER:=1, nieme IN INTEGER:=1); DBMS_LOB.INSTR( element_lob IN CLOB CHARACTER SET ANY_CS, cible IN VARCHAR2 CHARACTER SET element_lob%CHARSET, adr_depart IN INTEGER:=1, nieme IN INTEGER:=1); DBMS_LOB.INSTR( element_lob IN BFILE,

- 4 - © ENI Editions - All rigths reserved

Page 226: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

cible IN RAW, adr_depart IN INTEGER:=1, nieme IN INTEGER:=1);

13. LOADFROMFILE, LOADBLOBFROMFILE, LOADCLOBFROMFILE

Ces procédures permettent de charger des éléments LOB actuellement contenus dans des fichiers, à l’intérieur d’éléments LOB de la base de données. Il est bien sûr possible de préciser les adresses absolues du début de la copie dans la cadre d’un chargement partiel par l’intermédiaire des paramètres depart_origine et depart_destination. Ces adresses sont exprimées en octets.

Dans tous les cas, il est nécessaire d’indiquer le nombre d’octets à lire depuis le fichier pour construire l’élément LOB en mémoire.

Syntaxe

DBMS_LOADFROMFILE( lob_destiniation IN OUT NOCOPY BLOB, fichier_origine IN BFILE, nombre_octets IN INTEGER, depart_destination IN INTEGER:=1, depart_origine IN INTEGER:=1); DBMS_LOADBLOBFROMFILE( lob_destiniation IN OUT NOCOPY BLOB, fichier_origine IN BFILE, nombre_octets IN INTEGER, depart_destination IN INTEGER:=1, depart_origine IN INTEGER:=1); DBMS_LOADCLOBFROMFILE( lob_destiniation IN OUT NOCOPY BLOB, fichier_origine IN BFILE, nombre_octets IN INTEGER, depart_destination IN INTEGER:=1, depart_origine IN INTEGER:=1, jeu_caractere_org IN NUMBER, contexte_langue IN OUT INTEGER, avertissement OUT INTEGER);

Exemple

L’exemple ci­dessous illustre comment il est possible d’utiliser les différentes méthodes du package pour charger des images dans une table.

SQL> -- creation de la table de destinations SQL> create table mesphotos ( 2 id number, 3 img blob); Table créée. SQL> create sequence seq_id_photos; Séquence créée. SQL> SQL> -- mise en place du répertoire SQL> create or replace directory "O9i_dir" as ’C:\O9i’; Répertoire créé. SQL> SQL> -- chargement des données SQL> declare 2 fic_in BFILE; 3 taille number; 4 dest_blob BLOB; 5 vid number;

- 5 -© ENI Editions - All rigths reserved

Page 227: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

6 begin 7 fic_in:= bfilename(’O9i_dir’,’BPR.gif’); 8 9 -- ouvrir le fichier 10 dbms_lob.fileopen(fic_in, dbms_lob.file_readonly); 11 12 if (dbms_lob.fileexists(fic_in)=1) then 13 14 -- taille du fichier 15 taille:=dbms_lob.getlength(fic_in); 16 insert into mesphotos values (seq_id_photos.nextval, empty_blob()) 17 return id,img into vid,dest_blob; 18 19 -- lire les données et mémoriser dans une variable 20 dbms_lob.loadfromfile(dest_blob,fic_in, taille); 21 22 -- insérer dans la table 23 update mesphotos set img=dest_blob where id=vid; 24 commit; 25 26 -- fermer le fichier 27 dbms_lob.fileclose(fic_in); 28 29 end if; 30 31 exception 32 33 when dbms_lob.invalid_argval then 34 raise_application_error(-20001,’Mauvais argument’); 35 36 when dbms_lob.access_error then 37 raise_application_error(-20002,’Dépassement capacité’); 38 39 when dbms_lob.noexist_directory then 40 raise_application_error(-20003,’Répertoire inexistant’); 41 42 when dbms_lob.nopriv_directory then 43 raise_application_error(-20004,’Privilèges insuffisant sur le répertoire’); 44 45 when dbms_lob.unopened_file then 46 raise_application_error(-20007,’Fichier non ouvert’); 47 48 when others then 49 dbms_lob.fileclose(fic_in); 50 raise_application_error(-20008,’ERR’||SQLCODE||’ ’||SQLERRM); 51 52 end; 53 / Procédure PL/SQL terminée avec succès. SQL>

14. OPEN

Cette procédure permet d’ouvrir un élément LOB dans le mode indiqué (lob_readonly ou lob_readwrite) à l’aide du second paramètre.

Syntaxe

DBMS_LOB.OPEN( lob_origine IN OUT NOCOPY BLOB|CLOB CHARACTER SET ANY_CS, mode_ouverture IN BINARY_INTEGER);

- 6 - © ENI Editions - All rigths reserved

Page 228: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

15. READ

Cette procédure permet de lire en totalité ou en partie un élément LOB et de placer le résultat de cette lecture en mémoire tampon.

Syntaxe

DBMS_LOB.READ( lob_origine IN BLOB|BFILE, nombre_octets IN OUT NOCPY BINARY_INTEGER, adr_depart INT INTEGER, tampon OUT RAW); DBMS_LOB.READ( lob_origine IN CLOB CHARACTER SET ANY_CS, nombre_octets IN OUT NOCPY BINARY_INTEGER, adr_depart INT INTEGER, tampon OUT VARCHAR2 CHARACTER SET lob_ origine%CHARSET);

16. SUBSTR

Cette fonction offre la possibilité d’extraire une sous­chaîne depuis l’élément LOB. C’est en fait l’ensemble des octets lus à partir de l’adresse de départ passé en paramètre ainsi que le nombre d’octets à lire qui est retourné.

Syntaxe

DBMS_LOB.SUBSTR( lob_origine IN BLOB, nombre_octets IN INTEGER:=32767, adr_depart IN INTEGER:=1) RETURN RAW; DBMS_LOB.SUBSTR( lob_origine IN CLOB CHARACTER SET ANY_CS, nombre_octets IN INTEGER:=32767, adr_depart INT INTEGER:=1) RETURN VARCHAR2 CHARACTER SET lob_origine%CHARSET;

17. TRIM

Cette procédure permet de réduire la taille d’un élément LOB au nombre d’octets ou de caractères précisé dans le paramètre nouvelle_taille.

Syntaxe

DBMS_LOB.TRIM( lob_origine IN OUT NOCOPY BLOB|CLOB CHARACTER SET ANY_CS, nombre_octets IN INTEGER);

18. WRITE, WRITEAPPEND

La procédure WRITE permet de d’écrire un nombre d’octets dans un élément LOB interne, à partir d’une adresse de départ. La procédure WRITE remplace toutes les informations qui existent déjà dans l’élément LOB cible à partir de l’adresse de départ.

Syntaxe

DBMS_LOB.WRITE( lob_destination IN OUT NOCOPY BLOB, nombre_octets IN BINARY_INTEGER, adr_depart IN INTEGER, tampon IN RAW); DBMS_LOB.WRITE( lob_destination IN OUT NOCOPY CLOB CHARACTER SET ANY_CS, nombre_octets IN BINARY_INTEGER,

- 7 -© ENI Editions - All rigths reserved

Page 229: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

adr_depart IN INTEGER, tampon IN VARCHAR2 CHARACTER SET lob_origine%CHARSET);

La procédure WRITEAPPEND permet d’écrire les données de type LOB actuellement dans le tampon à la fin de l’élément LOB de destination.

Syntaxe

DBMS_LOB.WRITE( lob_destination IN OUT NOCOPY BLOB, nombre_octets IN BINARY_INTEGER, adr_depart IN INTEGER, tampon IN RAW); DBMS_LOB.WRITE( lob_destination IN OUT NOCOPY CLOB CHARACTER SET ANY_CS, nombre_octets IN BINARY_INTEGER, adr_depart IN INTEGER, tampon IN VARCHAR2 CHARACTER SET lob_origine%CHARSET);

19. Les exceptions

Les principales exceptions du package DBMS_LOB sont :

INVALID_ARGVAL

Les arguments des fonctions et des procédures attendent des valeurs non NULL, mais un argument a reçu la valeur NULL ou bien une valeur en dehors du domaine de définition de l’argument.

ACCESS_ERROR

Tentative d’écriture sur un LOB qui dépasse la taille limite. Cette limite est de 4 Go.

NOEXIST_DIRECTORY

L’élément de type DIRECTORY n’existe pas pour le fichier actuel.

NOPRIV_DIRECTORY

L’utilisateur ne possède pas les droits nécessaires sur le DIRECTORY (répertoire) ou sur les fichiers pour mener à bien ses opérations.

INVALID_DIRECTORY

La référence au répertoire (DIRECTORY) n’est pas valide dans le cas d’un premier accès ou sa définition a été modifiée par l’administrateur de bases de données depuis la dernière utilisation.

OPERATION_FAILED

Échec de l’opération.

UNOPENED_FILE

Le fichier n’est pas ouvert.

OPEN_TOOMANY

Le nombre de fichiers ouverts simultanément a atteint la limite supérieure. Il est donc nécessaire de fermer des fichiers pour pouvoir continuer.

- 8 - © ENI Editions - All rigths reserved

Page 230: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Introduction

À partir de la version 8i du SGBDR Oracle, le langage Java est totalement intégré au moteur de la base de données. Il va donc être possible d’écrire du code en Java qui sera stocké et exécuté directement dans la base de données.

La machine virtuelle Java intégrée dans le moteur Oracle, est totalement compatible avec le JDK de Sun.

La version du JDK est fixée suivant la version Oracle utilisée.

Cette machine virtuelle s’exécute dans le même processus et partage le même espace mémoire que le moteur de la base de données. Cette solution offre de très bons temps d’accès aux données. La machine virtuelle est un environnement d’exécution Java qui supporte toutes les structures, les méthodes et la gestion des erreurs propres à Java.

Choisir Java pour développer du code côté serveur, c’est obtenir une solution applicative écrite entièrement en Java et donc limiter le nombre de langages différents à apprendre.

Le langage Java peut intervenir pour l’écriture de procédures, de fonctions et de déclencheurs (triggers) de base de données.

Les avantages des procédures stockées sont nombreux. Les plus importants sont :

la performance : car le code exécutable est géré par le serveur et il y est maintenu en mémoire.

la facilité de mise en place et de déploiement : tous les utilisateurs accèdent au même code.

la sécurité : il est possible, en utilisant la sécurité Oracle, d’obliger les utilisateurs à manipuler les données au travers des procédures stockées et de ne leur accorder aucun droit sur les tables accédées par les procédures.

Le développement d’applications Java en lien avec la base Oracle n’entre pas dans le cadre de cet ouvrage.

La présentation suivante permet d’explorer les capacités d’Oracle à travailler avec des procédures stockées Java. Ce chapitre ne peut pas être considéré comme un apprentissage de Java et suppose d’avoir déjà quelques

notions de langage Java.

- 1 -© ENI Editions - All rigths reserved

Page 231: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Chargement des procédures stockées

Avant de pouvoir utiliser les procédures, elles doivent être chargées dans la base de données. Le chargement des procédures et leur publication sont deux étapes distinctes. De nombreuses classes Java sont chargées mais ne sont jamais publiées car elles ne présentent pas d’interface utilisateur.

Ici un utilisateur représente un programmeur PL/SQL.

Pour charger les classes Java dans la base de données, nous utiliserons l’utilitaire en ligne de commandes loadjava.

1. Généralités

Pour chaque classe chargée dans la base de données par loadjava, un objet est créé et le nom de cet objet est issu du nom complet de la classe Java. Dans cet objet sont conservés le code source, le code exécutable et les différentes ressources nécessaires à la bonne exécution de la classe. Load­java conserve également les différentes valeurs des options dans une table.

Le programme Java peut être mis au point par un outil de développement externe à la base de données, puis le fichier .class est chargé par loadjava. Mais on peut tout à fait charger le fichier source (.java) et le code est alors compilé dans la base de données.

Le nom de l’objet créé reprend le nom complet de la classe Java, c’est­à­dire le nom du package et le nom de la classe. Ces noms peuvent avoir une longueur maximum de 4000 caractères dans la base de données. Mais Oracle autorise des identifiants d’une longueur maximum de 30 caractères pour les objets de la base de données. Il faut donc mettre en place une résolution de nom afin de pouvoir manipuler ces objets depuis PL/SQL.

2. Les droits d’utilisation

Par défaut, les procédures stockées Java utilisent les privilèges accordés à l’utilisateur Oracle qui exécute la procédure. Ce type de résolution de droits permet de personnaliser au mieux les privilèges accordés à chaque utilisateur. De plus, le code peut être centralisé en un point précis de la base de données et être utilisé de différentes façons.

- 1 -© ENI Editions - All rigths reserved

Page 232: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Ce problème est expliqué par l’exemple suivant :

Dans cet exemple les deux utilisateurs Pierre et Anne utilisent la même procédure stockée Java (Analyse) qui intervient sur la table Ventes. Comme la procédure stockée s’exécute en utilisant les droits accordés à l’utilisateur qui l’exécute, elle accède aux tables que l’utilisateur possède. Donc dans ce cas le même code est partagé pour analyser deux tables totalement différentes.

3. L’utilitaire Loadjava

Syntaxe

loadjava -user| -u nom_utilisateur /mot_de_passe[@service] [ andresolve | a | debug | definer | d nom_du_schéma_d’encodage | encoding | e schéma_codage | force | f | grant | g utilisateur|role | oci8 | o | oracleresolver | resolve | r | resolver | R "spécification" | schema | S nom_schema | synonym | s | thin | t | verbose | v ] nom_de_fichier ...

andresolve

Avec cette option, chaque classe chargée est marquée comme valide, c’est­à­dire que toutes les classes auxquelles elle fait référence sont censées être dans la base.

resolve

Avec cette option, la classe est chargée dans la base puis une résolution est effectuée pour savoir si toutes les classes

- 2 - © ENI Editions - All rigths reserved

Page 233: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Java utilisées sont présentes dans la base. Si c’est le cas, alors la classe chargée est marquée comme valide.

Les options resolve et andresolve sont mutuellement exclusives. Si aucune des deux options n’est précisée, alors la résolution des classes est effectuée au moment de l’exécution.

resolver

Cette option permet d’indiquer un chemin (ensemble de schémas) à utiliser pour trouver les objets référencés dans la classe nouvellement chargée. Cette option s’apparente à la variable CLASSPATH que l’on utilise dans une programmation Java classique.

oracleresolver

Cherche les objets dans le schéma de l’utilisateur courant et dans le schéma public. Si les classes demandées n’y sont pas, alors l’objet nouvellement chargé est marqué comme invalide.

debug

Permet de générer des informations de débogage. Cette option est similaire à javac ­g.

definer

Permet d’utiliser la méthode avec les droits de l’utilisateur qui a créé cette méthode et non pas ceux accordés à l’utilisateur qui utilise la méthode.

encoding

Cette option permet de fixer la table de caractères utilisée par le JDK pour encoder les fichiers. Par défaut, la page de caractères utilisée est latin1.

force

La classe va être chargée dans la base même si elle y existe déjà. Sans cette option, l’action de chargement est rejetée. Cette option est particulièrement intéressante dans les opérations de mise à jour des classes.

grant

Permet d’accorder le droit d’exécution de la procédure dès son chargement. Cette action est similaire à celle de l’ordre SQL GRANT.

oci8

Autorise loadjava à communiquer avec la base en utilisant le pilote OCI JDBC. C’est le mode de communication par défaut.

thin

Loadjava utilise dans ce cas le pilote thin JDBC pour communiquer avec la base.*

Les options oci8 et thin sont mutuellement exclusives.

schema

Les objets Java nouvellement créés sont affectés au schéma précisé par ce paramètre. Par défaut ils sont créés dans le schéma de l’utilisateur courant.

synonym

Un synonyme public est créé pour rendre les classes facilement accessibles.

verbose

- 3 -© ENI Editions - All rigths reserved

Page 234: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Active le mode "bavard", des messages de progression sont affichés.

Exemple

Le code source

La classe est chargée dans la base de données.

Utilisation de loadjava pour charger la classe dans le schéma livre

4. L’utilitaire Dropjava

À l’inverse de l’utilitaire Loadjava, Dropjava permet de supprimer un objet Java depuis la base de données. Cet outil permet de supprimer aussi bien des fichier source (.java), des fichiers .class, ou bien de ressources .jar ou .zip.

Syntaxe

dropjava -user| -u nom_utilisateur /mot_de_passe[@service] [oci8 | o | schema | S nom_schema | thin | t | verbose | v ] nom_de_fichier ....

Les options disponibles pour cet outil ont la même signification que dans l’utilitaire Loadjava.

Exemple

Suppression de la classe depuis le schéma livre

- 4 - © ENI Editions - All rigths reserved

Page 235: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

5. L’accès aux données

Que le programme Java s’exécute sur le poste client ou sur le serveur de base de données comme c’est le cas ici, le problème de l’accès aux données se pose toujours. Avec Java, Oracle offre deux solutions distinctes d’accès aux données. Il est possible d’utiliser la solution classique JDBC qui est déjà bien connue et c’est son principal avantage. Une alternative à cette solution est proposée par l’intermédiaire de SQLJ. Avec cette technique, les commandes SQL sont saisies directement dans le programme Java. Puis le fichier est enregistré avec l’extension sqlj au lieu de java.

La compilation du fichier SQLJ peut avoir lieu sur le poste client sur lequel est développé le code Java ou bien sur le serveur. Il est préférable de réaliser une compilation sur le poste de développement car cela permet une mise au point plus facile si des erreurs de compilation sont présentes.

Les fichiers .class ou .jar peuvent alors être chargés sur le serveur par l’intermédiaire de la commande loadjava.

a. JDBC

La mise en place d’une solution JDBC va permettre d’utiliser des outils connus et indépendants de la base Oracle. Cette méthode est particulièrement bien adaptée dans le développement d’outils clients en Java qui ne doivent pas être liés de façon trop contraignante à la base de données Oracle. Pour l’écriture de procédures stockées, la syntaxe JDBC peut s’avérer un peu lourde comparée au SQLJ.

Dans cet ouvrage, de nombreux exemples Java utilisent la technologie JDBC pour travailler avec les données issues de la base de données.

b. SQLJ

SQLJ est une solution d’accès aux données, spécifique à Oracle, qui est bien adaptée dans le cadre des développements Java étroitement liés à la base Oracle. En effet, grâce à SQLJ il est possible de faire référence à des variables Java directement dans les instructions SQL, et pour les applications s’exécutant sur le serveur de base de données, la gestion de la connexion est implicite, ce qui simplifie encore le code.

Pour que le précompilateur SQLJ transforme les instructions SQLJ en appels de méthodes, les instructions SQLJ doivent obligatoirement commencer par #SQLJ et l’instruction SQL est entre accolades .

Exemple

Le code Java ci­dessous montre comment il est possible d’intégrer les commandes SQLJ dans le code Java.

import java.sql.*; class Comptes public static int CompteClients() int nombre=0; try #sqlSELECT COUNT(*) INTO :nombre FROM CLIENTS; return nombre; catch(SQLException e) finally return nombre;

Il est ensuite nécessaire de compiler le fichier sqlj afin de générer le fichier class.

sqlj Comptes.sqlj

Enfin, le fichier class doit être chargé dans la base à l’aide de l’utilitaire loadjava.

loadjava -user scott/tiger@bdeni -v Comptes.class

- 5 -© ENI Editions - All rigths reserved

Page 236: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Publication des procédures stockées

Avant de pouvoir utiliser une procédure stockée Java directement depuis SQL, il faut inscrire les références de cette procédure dans le dictionnaire de données. Cette opération n’est pas automatique car le moteur Oracle ne peut pas savoir quelles méthodes seront accessibles depuis le SQL.

Pour une méthode Java, il faut créer une fonction (méthode de type void) ou une procédure PL/SQL à l’aide des ordres CREATE FUNCTION et CREATE PROCEDURE. Ces fonctions et procédures peuvent éventuellement être regroupées dans un package. Le corps de ces fonctions et procédures contiendra la clause LANGUAGE JAVA afin d’enregistrer le nom complet de la méthode, la valeur de retour et les paramètres.

1. Correspondance des types de données

La correspondance entre les types de données SQL et Java est régie par le tableau page suivante.

Type SQL Classe Java

CHAR ­ NCHAR ­ LONG ­ VARCHAR2 ­ NVARCHAR2

oracle.sql.CHAR

java.lang.String

java.sql.Date

java.sql.Time

java.sql.Timestamp

java.lang.Byte

java.lang.Short

java.lang.Integer

java.lang.Long

java.lang.Float

java.lang.Double

java.lang.BigDecimal

byte ­ short ­ int ­ long ­ float ­ double

DATE

oracle.sql.DATE

java.sql.Date

java.sql.Time

java.sql.Timestamp

java.lang.String

NUMBER

oracle.sql.NUMBER

java.lang.Byte

java.lang.Short

java.lang.Integer

java.lang.Long

java.lang.Float

java.lang.Double

java.lang.BigDecimal

byte ­ short ­ int ­ long ­ float ­ double

RAW ­ LONG RAW oracle.sql.RAW

byte[]

- 1 -© ENI Editions - All rigths reserved

Page 237: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

2. Création d’une fonction Java ou d’une procédure Java

Syntaxe

CREATE [OR REPLACE] PROCEDURE nom_procédure [(paramètre, ...)] | FUNCTION nom_fonction [(paramètre, ...)] RETURN type_sql [AUTHID DEFINER|CURRENT_USER] [PARALLEL_ENABLE] [DETERMINISTIC] AS | IS LANGUAGE JAVA NAME ’nom_méthode_java (paramètre_java,...)’;

AUTHID

Permet de définir le type de privilèges à utiliser lors de l’exécution de la méthode, soit ceux de l’auteur de la méthode, soit ceux de l’utilisateur de la méthode (par défaut).

Il n’est pas possible d’écraser un choix réalisé avec Loadjava.

PARALLEL_ENABLE

La méthode peut s’exécuter dans un environnement parallèle car elle ne fait référence à aucune valeur de type static.

DETERMINISTIC

Lorsque le résultat de la fonction ne dépend pas de variables de session, alors l’optimiseur peut réutiliser le résultat déjà obtenu lors d’un appel précédent avec les mêmes paramètres.

Exemples

Définition de la procédure associée à la méthode Supprime :

ROWID

oracle.sql.CHAR

oracle.sql.ROWID

java.lang.String

BFILE oracle.sql.BFILE

BLOB oracle.sql.BLOB

oracle.jdbc2.Blob

CLOB ­ NCLOB oracle.sql.CLOB

oracle.jdbc2.Clob

OBJECT oracle.sql.STRUCT

oracle.jdbc2.Struct

REF oracle.sql.REF

oracle.jdbc2.Ref

TABLE ­ VARRAY oracle.sql.ARRAY

oracle.jdbc2.ArrayArray

- 2 - © ENI Editions - All rigths reserved

Page 238: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

L’exemple ci­après définit une fonction qui retourne le nombre d’éléments dans la table dont le nom est passé en paramètre.

Le code java

Par l’intermédiaire de l’utilitaire Loadjava, la classe est chargée dans la base.

Puis une fonction de type PL/SQL est créée afin de pouvoir utiliser la fonction Java dans la base.

Définition de la fonction associée à la méthode Compte

- 3 -© ENI Editions - All rigths reserved

Page 239: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

3. CREATE JAVA

L’instruction DDL CREATE JAVA permet de créer une procédure, une fonction ou une ressource Java depuis l’invite SQL sans passer par l’utilitaire loadjava. L’utilisation d’une telle commande est réservée au code java pour lequel le risque d’erreurs de compilation est rare car la mise au point est plus difficile.

Comme toutes les commandes du DDL il est nécessaire d’avoir un privilège particulier (ici CREATE PROCEDURE) pour pouvoir exécuter cette instruction.

Syntaxe

CREATE [OR REPLACE] [AND COMPILE|RESOLVE] JAVA SOURCE|RESOURCENAMED nom_procedure | CLASS AS code_source_java|USING BFILE(repertoire,fichier);

La syntaxe ci­dessus est un extrait de la syntaxe complète de la commande CREATE JAVA. C’est cette syntaxe qui servira le plus souvent mais il possible de la compléter lors de l’utilisation de données de type BLOB, CLOB ou BFILE ou lorsque la procédure doit être créée sur un schéma différent de l’utilisateur courant.

Exemple

L’exemple ci­dessous montre la mise en place d’une fonction Java à l’aide de la commande CREATE JAVA.

create or replace and compile java source named "Compte" as public class Compte public static int Compte(int a, int b) int resultat; resultat=a+b; return resultat; ; /

Dans l’exemple suivant c’est, cette fois, un fichier class qui est chargé dans la base à l’aide de la commande CREATE JAVA.

create or replace directory bfile_dir as ’c:\O9i’; create or replace java class using bfile (bfile_dir,’Comptes.class’); /

- 4 - © ENI Editions - All rigths reserved

Page 240: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Utilisation des procédures stockées

Après avoir chargé et publié les procédures stockées écrites en Java, il faut les utiliser. Le but de cette section est de montrer les différents moyens possibles pour appeler les procédures Java.

1. Appel d’une procédure Java depuis SQL*Plus

L’instruction CALL permet d’appeler depuis le prompt PL/SQL une procédure stockée Java qui a été publiée en tant que fonction, procédure ou élément d’un package.

Syntaxe

CALL [nom_schéma.][nom_package.] nom_procedure(paramètre,...)|nom_fonction(paramètre,...)

Les paramètres sont définis dans SQL*Plus et peuvent être des littéraux ou bien des variables hôtes.

Exemple

Utilisation de la fonction Compte pour connaître le nombre de clients présents dans la table.

Création de la table TTEST puis suppression par la procédure Java Supprime_le.

Certaines procédures stockées Java utilisent le flux standard d’erreur (System.err) ou de sortie (System.out) pour afficher certaines informations. Il est possible de rediriger ces flux vers SQL*Plus en utilisant simplement les deux commandes suivantes :

SET SERVEROUTPUT ON [SIZE taille] CALL dbms_java.set_output(taille)

Avec ce principe, les données sont affichées dès que la procédure est terminée. Le paramètre taille, dont la valeur par défaut est 2000 octets permet de préciser la taille du tampon. Cette taille ne peut pas être supérieure à 1 000 000 d’octets.

L’instruction CALL

Rediriger les sorties

- 1 -© ENI Editions - All rigths reserved

Page 241: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Exemple

Le code source. La procédure Java est utilisée pour afficher directement le nom des différents clients.

La classe va être chargée dans la base par l’intermédiaire de Loadjava. Une procédure PL/SQL est associée à la méthode Java.

La publication dans la base.

Utilisation de la procédure depuis SQL*Plus.

- 2 - © ENI Editions - All rigths reserved

Page 242: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

2. Appel d’une procédure Java depuis un déclencheur de base de données

Un déclencheur de base de données est un programme associé à une table ou une vue. Ce programme est exécuté automatiquement par Oracle lorsque l’opération DML (INSERT, UPDATE ou DELETE) à laquelle le déclencheur est lié, est exécutée sur la table ou sur la vue. Après la définition du trigger : nom, table ou vue associée, ordre DML déclencheur, avant ou après vérification des contraintes d’intégrité, la procédure liée à la méthode Java est appelée à l’aide de la fonction CALL. Le corps déclencheur est alors réduit au maximum.

Exemple

La classe Declencheurs propose une méthode qui permet de réduire le stock à chaque nouvelle commande d’articles. La classe est chargée dans la base à l’aide de l’utilitaire Loadjava. Création de la procédure MAJStock.

Le déclencheur est posé sur la table LIGNESCDE et il est associé à l’ordre INSERT. Le déclencheur est exécuté pour chaque ligne créee. Création du déclencheur.

3. Appel d’une procédure Java depuis une instruction SQL DML ou un bloc PL/SQL

Comme une fonction ou une procédure de type PL/SQL est associée à la méthode Java, l’utilisation de cette fonction ou procédure est similaire à celle d’une fonction ou procédure écrite entièrement en PL/SQL.

La mise en place de méthodes Java n’est pas toujours évidente et de plus il est aberrant de créer autant de classe Java que de méthodes. Au niveau Java, toutes les méthodes traitant d’un même sujet, par exemple la gestion des commandes, sont regroupées dans la même classe. Pour maintenir cette cohérence de regroupement au niveau de la programmation dans la base de données, les fonctions et les procédures associées aux méthodes sont regroupées dans un package.

Bien sûr, un tel package ne diffère pas d’un package PL/SQL et se comporte de la même façon. Le point le plus important étant que le package reste entièrement en mémoire et permet ainsi d’offrir de meilleurs temps de réponse

Les packages

- 3 -© ENI Editions - All rigths reserved

Page 243: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

que si les fonctions et les procédures étaient indépendantes les unes des autres.

Exemple

Création de la classe Commandes.

import java.sql.*; import java.io.*; import oracle.jdbc.driver.*; public class Commandes public static float montant(int nocde) throws SQLException Connection conn=new OracleDriver().defaultConnection(); String requete="Select sum(qtecde*prix) from lignescde l, articles a where a.refart=l.refart and l.nocde="+nocde; float mt=0; try Statement stmt=conn.createStatement(); ResultSet rs=stmt.executeQuery(requete); while (rs.next())mt=rs.getFloat(1); rs.close(); stmt.close(); catch(SQLException e)System.err.println(e.getMessage()); return mt; public static void livrer(int nocde) throws SQLException changeEtat(nocde,"LI"); public static void solder(int nocde) throws SQLException changeEtat(nocde,"SO"); private static void changeEtat(int nocde, String etat) throws SQLException Connection conn=new OracleDriver().defaultConnection(); String requete="Update commandes set etat=’"+etat+"’ where nocde="+nocde; try Statement ordre=conn.createStatement(); ordre.executeQuery(requete); ordre.close(); catch (SQLException e) System.err.println(e.getMes- sage());

La classe est chargée dans la base par l’intermédiaire de la commande Loadjava. Le package lui correspondant sera créé en deux étapes. Tout d’abord l’en­tête du package est défini :

Puis le corps du package est défini.

- 4 - © ENI Editions - All rigths reserved

Page 244: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

L’utilisation d’une procédure ou d’une fonction de ce package est en tout point identique à celle d’un package écrit entièrement en PL/SQL.

Exemple

Utilisation de la fonction Montant pour connaître le montant de la commande n°1.

- 5 -© ENI Editions - All rigths reserved

Page 245: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Introduction

Le parser (analyseur) XML permet de manipuler des fichiers XML depuis le langage PL/SQL. Il est ainsi possible de lire et de générer des fichiers au format XML. Pour pouvoir mettre en place ces éléments, le langage PL/SQL utilise le package xmldom afin de connaître et d’analyser la structure du document XML.

Le langage PL/SQL, qui est couramment utilisé par les développeurs Oracle, voit ainsi ses possibilités évoluer vers le XML. Le parser XML pour PL/SQL a été écrit en PL/SQL et en Java. Il supporte toutes les spécifications émises par le W3C pour la norme 1.0 de XML. En plus du respect total de la norme, le parser XML pour PL/SQL permet une analyse simplifiée du document par le respect des consignes du W3C concernant le modèle de document (DOM : Document Object Model). Il respecte également les recommandations concernant XSLT (les feuilles de styles) et Xpath.

Le parser est situé dans le répertoire $ORACLE_HOME\xdk\plsql\parser. Il est inclus en standard à partir de la version 9i.

Le schéma suivant résume simplement comment fonctionne le parser pour l’analyse d’un document. Cette arborescence est ensuite mise en œuvre dans les exemples qui suivent afin de connaître la structure d’un document ainsi que les données contenues dans ce document.

Ainsi, tous les programmes possèdent la même structure pour pouvoir analyser un document XML, qui est la suivante :

Créer un nouvel objet de type Parser à l’aide de la fonction newParser et commencer l’analyse du document XML ainsi que de sa DTD si elle est disponible.

Ensuite, il faut utiliser la source XML ou DTD qui peut être de type varchar2, CLOB (Character Large Object Binary) ou un fichier.

Suivant le type de la source, les méthodes possibles sont parse() ou parseDTD() si les informations sont contenues dans un fichier, parseBuffer() ou parseDTDBuffer si les informations sont contenues dans un élément de type varchar2 et enfin parseClob() ou bien parseDTDClob() si les informations sources sont conservées dans un élément de type CLOB.

Pour les documents XML uniquement qui sont analysés à l’aide d’une des fonctions parse, parseBuffer ou parseClob, le résultat de l’exécution de ces méthodes est placé dans un document accessible par getDocument().

- 1 -© ENI Editions - All rigths reserved

Page 246: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

La méthode getDocument() va permettre d’obtenir le résultat de l’analyse et permet également d’appliquer les autres méthodes du modèle DOM.

La méthode freeDocument va permettre de libérer les ressources actuellement détenues par le parser sur le document actif afin de rendre possible l’analyse d’un autre document.

Enfin, l’instruction freeParser() permet de libérer toutes les ressources.

- 2 - © ENI Editions - All rigths reserved

Page 247: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Lire un fichier XML

La première étape consiste a être capable de lire un fichier au format XML depuis le langage PL/SQL et de bien interpréter les données issues de ce fichier. Pour bien comprendre comment fonctionne le parser, la méthode la plus simple consiste sans doute à passer par un petit programme d’exemple. Toutes les fonctionnalités du parser ne seront pas illustrées mais à partir d’un exemple qui fonctionne, il est toujours possible de compléter les éléments manquants de façon relativement simple.

Le script suivant va donc permettre la création d’une procédure qui accepte en paramètre un nom de fichier xml et qui va l’ouvrir afin d’interpréter les données qu’il contient.

rem Cette procédure permet d’afficher les différents éléments du document XML create or replace procedure afficherElements(doc xmlDom.DOMDocument) is lesNoeuds xmlDom.DOMNodeList; longueur number; noeud xmlDom.DOMNode; begin -- obtenir tous les éléments du document lesNoeuds:=xmlDom.getElementsByTagName(doc,’*’); longueur:=xmlDom.getLength(lesNoeuds); -- parcourir tous les éléments à l’aide d’une boucle for i in 0 ..longueur-1 loop noeud:=xmlDom.item(lesNoeuds, i); dbms_output.put(xmlDom.getNodeName(noeud)||’ ’); end loop; -- passer à la ligne suivante dbms_output.put_line(’ ’); end; / show errors; create or replace procedure afficherAttributs(doc xmlDom.DOMDocument) is lesNoeuds xmlDom.DOMNodeList; lg1 number; lg2 number; noeud xmlDom.DOMNode; element xmlDom.DOMElement; lesAttributs xmlDom.DOMNamedNodeMap; nomAttr varchar2(100); valeurAttr varchar2(100); begin -- obtenir tous les éléments lesNoeuds:=xmlDom.getElementsByTagName(doc,’*’); lg1:=xmlDom.getLength(lesNoeuds); -- parcourir tous les éléments for i in 0..lg1-1 loop noeud:=xmldom.item(lesNoeuds, i); element:=xmldom.makeElement(noeud); -- nom de la balise dbms_output.put_line(xmldom.getTagName(element)||’:’); -- obtenir tous les attributs de cet élément lesAttributs:=xmldom.getAttributes(noeud); if (xmldom.isNull(lesAttributs)= FALSE) then lg2:=xmldom.getLength(lesAttributs); -- parcourir tous les attributs for j in 0..lg2-1 loop noeud:=xmldom.item(lesAttributs,j); nomAttr := xmldom.getNodeName(noeud); valeurAttr := xmldom.getNodeValue(noeud); dbms_output.put(’ ’||nomAttr||’=’||valeurAttr); end loop; dbms_output.put_line(’ ’);

- 1 -© ENI Editions - All rigths reserved

Page 248: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

end if; end loop; end; / show errors; create or replace procedure lirexml(repertoire in varchar2, fichier in varchar2, fichier_erreur in varchar2) is p xmlparser.parser; doc xmldom.DOMDocument; begin -- nouveau parser p:=xmlparser.NewParser; -- fixer quelques caractéristiques du parser xmlParser.SetValidationMode(p,FALSE); xmlParser.SetErrorLog(p, repertoire||’\’||fichier_erreur); xmlParser.setBaseDir(p, repertoire); --analyser le fichier XML xmlParser.Parse(p,repertoire||’\’||fichier); -- obtenir le document doc:=xmlParser.GetDocument(p); -- afficher les différents éléments dbms_output.put_line(’Les éléments du documents sont :’); afficherElements(doc); -- afficher les attributs de chaque élément dbms_output.put_line(’Les attributs des éléments sont:’); afficherAttributs(doc); -- libérer le document xmlDom.freeDocument(doc); -- libérer le parser xmlParser.freeParser(p); end; / show errors;

C’est la procédure lireXml qui va permettre de lire et d’analyser un document XML. Le document XML va être fourni en paramètre de la procédure :

<?xml version ="1.0" standalone="no"?> <!DOCTYPE equipe SYSTEM "equipe.dtd"> <equipe nom="US Postal" pays="USA"> <coureur numero="001">ARMSTRONG</coureur> <coureur numero="002">EKIMOV</coureur> <coureur numero="003">HERAS</coureur> <coureur numero="004">HINCAPIE</coureur> <coureur numero="005">JOACHIM</coureur> <coureur numero="006">LANDIS</coureur> <coureur numero="007">PADRNOS</coureur> <coureur numero="008">PENA</coureur> <coureur numero="009">RUBIERA</coureur> </equipe>

L’exécution de la procédure et le résultat de cette exécution sont les suivants :

SQL> set serveroutput on SQL> execute lireXml(’c:\xml’,’equipe.xml’,’erreurs.txt’); Les éléments du documents sont : equipe coureur coureur coureur coureur coureur coureur coureur coureur coureur Les attributs des éléments sont: equipe: nom=US Postal pays=USA coureur: numero=001

- 2 - © ENI Editions - All rigths reserved

Page 249: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

coureur: numero=002 coureur: numero=003 coureur: numero=004 coureur: numero=005 coureur: numero=006 coureur: numero=007 . coureur: numero=008 coureur: numero=009 Procédure PL/SQL terminée avec succès. SQL>

- 3 -© ENI Editions - All rigths reserved

Page 250: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Appliquer une feuille de style à un document XML

L’un des grands avantages du langage XML est de pouvoir séparer de façon très distincte les données de la présentation, ce qu’il est plus ou moins possible de faire en HTML. L’exemple suivant, qui utilise les fonctionnalités de l’analyseur XML pour PL/SQL, va permettre de produire un fichier de sortie.

set serveroutput on; create or replace procedure appliqueXSL( repertoire varchar2, fichierXml varchar2, fichierXsl varchar2, fichierResultat varchar2, fichierErreur varchar2) is -- les variables p xmlParser.Parser;-- l’analyseur documentXML xmlDom.DOMDocument; -- document noeud xmlDom.DOMNode; ---- les éléments pour la feuille de style moteur xslProcessor.Processor; feuilleStyle xslProcessor.Stylesheet; documentXSL xmlDom.DOMDocument; elementXsl xmlDom.DOMElement; espaceNom varchar2(50); -- les éléments pour produire le résultat documentF xmlDom.DOMDocumentFragment; elementF xmlDom.DomNode; begin -- création d’un nouveau parser p:=xmlParser.newParser; -- fixer quelques caractéristiques de fonctionnement xmlParser.setValidationMode(p,FALSE); -- pas de validation du document xmlParser.setErrorLog(p,repertoire||’\’||fichierErreur); -- fichier des erreurs xmlParser.setPreserveWhiteSpace(p, TRUE); -- conserver les espaces xmlParser.setBaseDir(p, repertoire); -- repertoire de travail -- analyser le document XML xmlParser.parse(p,repertoire || ’\’ || fichierXml); -- obtenir le document documentXml:=xmlParser.getDocument(p); -- analyser le document XML xmlParser.parse(p,repertoire||’\’||fichierXsl); -- obtenir le document documentXsl:=xmlParser.getDocument(p); -- obtenir les noeuds de la feuille de style elementXsl:= xmlDom.getDocumentElement(documentXsl); -- obtenir l’espace de nom espaceNom:=xmlDom.getNamespace(elementXsl); -- fabriquer la feuille de style feuilleStyle:=xslProcessor.newStylesheet(documentXsl,repertoire||’\’||fichierX sl); -- appliquer la feuille de style moteur :=xslProcessor.newProcessor; xslProcessor.showWarnings(moteur, true); xslProcessor.setErrorLog(moteur,repertoire||’\’||fichierErreur); -- production du document final documentF:=xslProcessor.processXSL(moteur, feuilleStyle, documentXML); elementF:=xmlDom.makeNode(documentF); xmlDom.writeTofile(elementF,repertoire||’\’||fichierResultat);

- 1 -© ENI Editions - All rigths reserved

Page 251: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

end; / show errors

L’utilisation de cette procédure permet d’appliquer une feuille de style (XSL) à un document XML et le résultat est fourni sous la forme d’un troisième document. Le fichier des erreurs est passé en paramètre et c’est à l’intérieur de celui­ci que sont consignées toutes les erreurs trouvées lors de l’application de la feuille de style.

L’appel de la procédure peut s’effectuer de la façon suivante :

execute appliqueXsl(’c:\xml’,’equipe.xml’,’equipe.xsl’,’equipe.out’, ’erreurs.txt’);

- 2 - © ENI Editions - All rigths reserved

Page 252: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

XSU

L’API XSU (Xml SQL utility) pour PL/SQL permet la génération et le stockage de documents XML depuis et dans la base de données. Ce sont les packages DBMS_XMLQueryet DBMS_XMLSavequi permettent de mettre en œuvre ces fonctionnalités.

1. Génération de code XML avec DBMS_XMLQuery

Pour pouvoir générer un document XML qui va contenir le résultat d’une requête simple à l’aide de DBMS_XMLQuery, il est nécessaire de suivre les cinq étapes suivantes :

Créer un pointeur vers un contexte en appelant la méthode DBMS_XMLQuery.getCtx et en lui passant en paramètre la requête.

Saisir les valeurs des différents paramètres possibles de la requête à l’aide de DBMS_XMLQuery.bind.

Fixer les arguments optionnels comme le nom de la balise ROW ou ROWSET, le nombre de lignes à ramener...

Écrire les données XML dans un élément CLOB (Caractère LOB) à l’aide de la fonction DBMS_XMLQuery.getXML. Cette fonction peut travailler avec ou sans un fichier DTD ou un schéma.

Fermer le contexte.

a. Génération de code XML depuis une requête

L’exemple ci­dessous illustre de façon très simple comment générer des informations au format XML à partir de ce qui est contenu dans la base.

set serveroutput on -- Mise au format XML du résultat d’une requête declare contexteRqt DBMS_XMLQuery.ctxType; resultat CLOB; begin -- mise en place du constexte de requête contexteRqt:=DBMS_XMLQuery.newContext(’select * from clients’); -- obtenir le résultat resultat:= DBMS_XMLQuery.getXML(contexteRqt); -- afficher le résultat afficheCLOB(resultat); -- fermer le contexte de requête DBMS_XMLQuery.closeContext(contexteRqt); end; /

Afin de faciliter l’affichage des éléments au format CLOB, la méthode afficheCLOB a été écrite.

create or replace procedure afficheClob(chaine in out nocopy CLOB) is chaineXml varchar2(32767); ligne varchar2(2000); begin -- copier le document CLOB dans un VARCHAR2 chaineXml:=dbms_lob.SUBSTR(chaine, 32767); loop exit when chaineXml is null; -- A la recherche des fins de ligne ligne:=substr(chaineXml,1,instr(chaineXml,chr(10))-1); dbms_output.put_line(’| ’||ligne); chaineXml:=substr(chaineXml, instr(chaineXml,chr(10))+1);

- 1 -© ENI Editions - All rigths reserved

Page 253: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

end loop; end; /

L’exécution de ce script donne alors le résultat suivant :

<?xml version = ’1.0’?> <ROWSET> <ROW num="1"> <NOCLI>1</NOCLI> <NOM>ROUSSEL</NOM> <PRENOM>Gilles</PRENOM> <ADRESSE>rue ENI</ADRESSE> <TEL>0240731696</TEL> </ROW> <ROW num="2"> <NOCLI>2</NOCLI> <NOM>MACRAIGNE</NOM> <PRENOM>Marie Pierre</PRENOM> <ADRESSE>rue Crebillon</ADRESSE> <TEL>0240731696</TEL> </ROW> <ROW num="3"> <NOCLI>3</NOCLI> <NOM>MARTIN</NOM> <PRENOM>Bruno</PRENOM> <ADRESSE>Rue Charron</ADRESSE> <TEL>0240731696</TEL> </ROW> <ROW num="4"> <NOCLI>4</NOCLI> <NOM>GABILLAUD</NOM> <PRENOM>Jerome</PRENOM> <ADRESSE>rue Charron</ADRESSE> <TEL>02407316*96</TEL> </ROW> </ROWSET>

Le résultat est bien sûr satisfaisant sur de nombreux points mais n’est pas encore un document XML utilisable tel quel.

b. Modifier les noms des balises ROW et ROWSET

L’API XSU pour PL/SQL permet de modifier le nom des balises ROW et ROWSET. Dans le cadre de notre exemple, la balise ROW devrait prendre le nom de CLIENT et la balise ROWSET celle de CLIENTS. En modifiant légèrement le script précédent et en utilisant les méthodes setRowTag et set­ RowSetTag il est possible d’effectuer ces modifications.

Le script de génération de code XML devient alors :

set serveroutput on -- Mise au format XML du résultat d’une requête declare contexteRqt DBMS_XMLQuery.ctxType; resultat CLOB; begin -- mise en place du constexte de requête contexteRqt:=DBMS_XMLQuery.newContext(’select * from clients’); --modification du nom de la balise ROW DBMS_XMLQuery.setRowTag(contexteRqt,’CLIENT’); --modification du nom de la balise ROWSET DBMS_XMLQuery.setRowSetTag(contexteRqt,’CLIENTS’); -- obtenir le résultat resultat:= DBMS_XMLQuery.getXML(contexteRqt); -- afficher le résultat afficheCLOB(resultat); -- fermer le contexte de requête

- 2 - © ENI Editions - All rigths reserved

Page 254: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

DBMS_XMLQuery.closeContext(contexteRqt); end;

Le résultat de l’exécution du script est alors :

<?xml version = ’1.0’?> <CLIENTS> <CLIENT num="1"> <NOCLI>1</NOCLI> <NOM>ROUSSEL</NOM> <PRENOM>Gilles</PRENOM> <ADRESSE>rue ENI</ADRESSE> <TEL>0240731696</TEL> </CLIENT> <CLIENT num="2"> <NOCLI>2</NOCLI> <NOM>MACRAIGNE</NOM> <PRENOM>Marie Pierre</PRENOM> <ADRESSE>rue Crebillon</ADRESSE> <TEL>0240731696</TEL> </CLIENT> <CLIENT num="3"> <NOCLI>3</NOCLI> <NOM>MARTIN</NOM> <PRENOM>Bruno</PRENOM> <ADRESSE>Rue Charron</ADRESSE> <TEL>0240731696</TEL> </CLIENT> <CLIENT num="4"> <NOCLI>4</NOCLI> <NOM>GABILLAUD</NOM> <PRENOM>Jerome</PRENOM> <ADRESSE>rue Charron</ADRESSE> <TEL>0240731696</TEL> </CLIENT> </CLIENTS>

c. Limiter le nombre de lignes

Les lignes de données extraites à partir de la requête peuvent être mises en page à l’aide des procédures setMaxRowset setSkiprows. La procédure setMaxRows permet de fixer le nombre maximum de lignes de données qui seront converties au format XML, la procédure setSkipRows permet quant à elle de préciser le nombre de lignes de données à ne pas prendre en compte avant de commencer la conversion au format XML.

Ces procédures peuvent être utilisées pour, par exemple, limiter le nombre de lignes de données présentées dans chaque document XML.

L’exemple suivant permet de limiter à 10 le nombre de clients présents dans chaque document XML généré. Afin qu’aucune exception ne soit levée lorsque toutes les lignes sont traitées, il faut faire appel à la méthode setRaiseNoRowsException.

set serveroutput on -- Mise au format XML du résultat d’une requête declare contexteRqt DBMS_XMLQuery.ctxType; resultat CLOB; begin -- mise en place du constexte de requête contexteRqt:=DBMS_XMLQuery.newContext(’select * from clients’); --modification du nom de la balise ROW DBMS_XMLQuery.setRowTag(contexteRqt,’CLIENT’); --modification du nom de la balise ROWSET DBMS_XMLQuery.setRowSetTag(contexteRqt,’CLIENTS’); -- fixer le nombre de lignes par document XML DBMS_XMLQuery.setMaxRows(contexteRqt,10); DBMS_XMLQuery.setRaiseNoRowsException(contexteRqt, true); -- extraction des informations

- 3 -© ENI Editions - All rigths reserved

Page 255: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

begin loop -- boucle infinie -- obtenir le résultat resultat:= DBMS_XMLQuery.getXML(contexteRqt); -- afficher le résultat afficheCLOB(resultat); end loop; exception when others then null; --sortir du bloc en cas d’erreur end; -- fermer le contexte de requête DBMS_XMLQuery.closeContext(contexteRqt); end; /

d. Les feuilles de styles

L’API XSU permet, bien sûr, l’utilisation des feuilles de styles dans la génération des documents XML.

La procéduresetStyleSheetHeader() permet d’ajouter la référence à la feuille de style dans l’en­tête du document résultant.

La procédureuseStyleSheet() permet, quant à elle, d’appliquer la feuille de style directement au document résultant. La seconde solution est de meilleure qualité que la première car cela évite de retravailler le document pour appliquer la feuille de style dans un deuxième temps.

2. Les requêtes paramétrées

Lors de la création du contexte il est nécessaire de fournir la requête SQL qui sera utilisée pour extraire l’information. Toutefois, cette requête peut contenir des paramètres qui seront valorisés juste avant l’exécution de la requête. En effet la requête n’est exécutée que lors de la demande de construction du document XML final par l’intermédiaire de la méthode getXMLClob.

Lors de l’écriture de la requête, les variables sont considérées comme des variables externes et sont donc préfixées par deux points (:).

La méthode setBindValue permet de fixer la valeur qui sera utilisée par un paramètre. Il est bien sûr nécessaire d’initialiser l’ensemble des paramètres avant la première demande de génération de document XML. Cependant, entre deux demandes de génération de document, il n’est pas nécessaire de réinitialiser tous les paramètres mais simplement ceux pour lesquels la valeur a changé.

Exemple

L’exemple suivant permet d’illustrer la mise en place de requêtes paramétrées pour travailler avec l’API XSU. Deux documents XML vont être générés, chacun d’eux correspondant à la définition d’un client particulier, mais pourtant un seul contexte XSU sera établi car les données sont issues de la même requête à un paramètre de restriction prêt.

set serveroutput on -- Mise au format XML du résultat d’une requête declare contexteRqt DBMS_XMLQuery.ctxType; resultat CLOB; begin -- mise en place du constexte de requête contexteRqt:=DBMS_XMLQuery.newContext(’select * from clients where nocli=:numero’); -- fixer la valeur du paramètre DBMS_XMLQuery.setBindValue(contexteRqt,’numero’,15); -- obtenir le résultat resultat:= DBMS_XMLQuery.getXML(contexteRqt); -- afficher le résultat afficheCLOB(resultat); -- fixer un autre valeur pour la paramètre

- 4 - © ENI Editions - All rigths reserved

Page 256: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

DBMS_XMLQuery.setBindValue(contexteRqt,’numero’,20); -- obtenir le résultat resultat:= DBMS_XMLQuery.getXML(contexteRqt); -- afficher le résultat afficheCLOB(resultat); -- fermer le contexte de requête DBMS_XMLQuery.closeContext(contexteRqt); end; /

3. Stocker les informations au format XML avec DBMS_XMLSave

L’API XSU pour PL/SQL est également constitué du package DBMS_XMLSave qui permet d’enregistrer dans des tables de la base de données Oracle des données qui se trouvent initialement dans des documents au format XML. Avec ce second package, XSU permet de montrer que XML est un véritable format d’échange des données qui peut être utilisé pour effectuer des transferts de données entre des bases de données.

Il sera possible de travailler avec les données fournies au format XML pour réaliser des commandes Insert, Update ou Delete.

D’une façon générale, tous les scripts PL/SQL utilisant le package DBMS_XMLSave respectent la structure suivante :

Créer un contexte d’exécution par l’intermédiaire de la fonction DBMS_XMLSave.getCtx. Cette fonction admet en paramètre le nom de la table sur laquelle seront effectuées les opérations Insert, Delete ou Update.

Si le document XML est utilisé comme support à l’ajout de données (INSERT) dans la table, alors il est possible de préciser les colonnes pour lesquelles des valeurs vont être fournies par l’intermédiaire de la fonction setUpadetColNames. Par défaut les valeurs sont fournies pour toutes les colonnes de la table.

Si le document XML est un support à une opération de mise à jour des données (UPDATE), alors il faut fournir la ou les colonnes qui vont être utilisées pour identifier de façon exacte les données à modifier. Il peut également être possible de préciser la ou les colonnes qui seront mises à jour.

Si le document XML sert de support à une opération de suppression (DELETE), alors il est possible de préciser quelles seront la ou les colonnes qui seront utilisées pour identifier précisément les données à supprimer. Par défaut toutes les informations du document XML servent à identifier les données qui seront supprimées.

Fournir un document XML à l’une des méthodes insertXML, updateXML ou deleteXML suivant l’utilisation que l’on souhaite faire du document XML.

Fermer le contexte.

a. Ajouter des données

Pour utiliser les données présentes dans le document XML afin de les ajouter dans une table, il suffit simplement de préciser le nom de la table ou de la vue, ainsi que le document XML. XSU se charge de générer les commandes INSERT. Par défaut, la commande INSERT concerne toutes les colonnes de la table ou de la vue et la valeur NULL est utilisée lorsque rien n’est précisé dans le document XML.

Exemple

L’exemple ci­après illustre l’utilisation de la fonction insertXML :

create or replace procedure ajouter(documentXML in CLOB, nomTable in varchar2) is contexteAjout DBMS_XMLSave.ctxType; nbreLignes number; begin -- créer le contexte d’insertion contexteAjout:=DBMS_XMLSave.newContext(nomTable); -- ajouter les lignes nbreLignes:=DBMS_XMLSave.insertXML(contexteAjout, documentXML);

- 5 -© ENI Editions - All rigths reserved

Page 257: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

-- fermer le contexte DBMS_XMLSave.closeContext(contexteAjout); end; /

Le document XML utilisé pour ajouter des données est :

<?xml version = ’1.0’?> <ROWSET> <ROW num="1"> <NOCLI>200</NOCLI> <NOMCLI>Etb LEROY</NOMCLI> <CODE_POSTAL>37000</CODE_POSTAL> <VILLE>TOURS</VILLE> </ROW> </ROWSET>

L’appel à la procédure est effectué de la façon suivante :

-- mise en place du répertoire create or replace directory "xml_dir" as ’C:\xml’; -- chargement des données declare dest_clob CLOB; fic_in BFILE; taille number; depart_destination integer:=1; depart_origine integer:=1; jeu_caractere number:=0; contexte_langue number:=0; avertissement number:=0; vid number; begin fic_in:= bfilename(’xml_dir’,’donees.xml’); -- ouvrir le fichier dbms_lob.fileopen(fic_in, dbms_lob.file_readonly); if (dbms_lob.fileexists(fic_in)=1) then -- taille du fichier taille:=dbms_lob.getlength(fic_in); -- lire les données et mémoriser dans une variable contexte_langue:=1; dbms_lob.createtemporary(dest_clob, true); dbms_lob.loadclobfromfile(dest_clob, fic_in, taille, depart_destination, depart_origine, jeu_caractere, contexte_langue, avertissement); -- fermer le fichier dbms_lob.fileclose(fic_in); -- appeler la procédure d’ajout des données ajouter(dest_clob, ’CLIENTS’); -- valider les transformations commit; end if; end;

- 6 - © ENI Editions - All rigths reserved

Page 258: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

/

Il est également possible d’utiliser cette méthode d’insertion pour ne renseigner que certaines colonnes de la table de destination. Il est alors nécessaire de faire appel à la méthode setUpdateColumn afin de préciser le nom des colonnes qui vont contenir des valeurs à insérer. Pour éliminer tout risque de paramètre mal défini, la méthode clearUpdateColumnList permet d’enlever toute référence qui aurait déjà pu être faite sur des colonnes.

Exemple

L’exemple suivant va lire les données au format XML dans un fichier puis charge les données dans la table des clients :

declare -- la variables nécessaires à la lecture d’un fichier documentXML CLOB; fic_in BFILE; taille number; depart_destination integer:=1; depart_origine integer:=1; jeu_caractere number:=0; contexte_langue number:=0; avertissement number:=0; -- les variables pour l’ajout des données contexteAjout DBMS_XMLSave.ctxType; nombreLignes number; begin fic_in:= bfilename(’xml_dir’,’donees2.xml’); -- ouvrir le fichier dbms_lob.fileopen(fic_in, dbms_lob.file_readonly); -- taille du fichier taille:=dbms_lob.getlength(fic_in); -- lire les données et mémoriser dans une variable contexte_langue:=1; dbms_lob.createtemporary(documentXML, true); dbms_lob.loadclobfromfile(documentXML, fic_in, taille, depart_destination, depart_origine, jeu_caractere, contexte_langue, avertissement); -- fermer le fichier dbms_lob.fileclose(fic_in); -- ajouter les données au format XML dans la table contexteAjout:=DBMS_XMLSave.newContext(’CLIENTS’); -- effacer les paramètres DBMS_XMLSave.clearUpdateColumnList(contexteAjout); -- les colonnes pour lesquelles il exite une valeur DBMS_XMLSave.setUpdateColumn(contexteAjout,’NOCLI’); DBMS_XMLSave.setUpdateColumn(contexteAjout,’NOMCLI’); -- effectuer les insertions nombreLignes:=DBMS_XMLSave.insertXML(contexteAjout,documentXML); --fermer le contexte DBMS_XMLSave.closeContext(contexteAjout); -- valider les transformations commit; end; /

- 7 -© ENI Editions - All rigths reserved

Page 259: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

b. Mettre à jour des données

La mise à jour est une opération légèrement plus délicate car il est nécessaire cette fois d’indiquer la ou les colonnes servant à l’identification de la ligne ainsi que la ou les colonnes dont les valeurs vont être mises à jour.

Les colonnes servant à l’identification seront indiquées par l’intermédiaire de la procédure setKeyColumnet celles qui vont être mises à jour par l’intermédiaire desetUpdateColumn. En l’absence de cette dernière indication ce sont toutes les colonnes de la table qui sont mises à jour.

Exemple

L’exemple ci­dessous va permettre de fixer la ville et le code postal pour les clients n°200 et 201 (ajoutés dans les exemples précédents) :

declare -- la variables nécessaires à la lecture d’un fichier documentXML CLOB; fic_in BFILE; taille number; depart_destination integer:=1; depart_origine integer:=1; jeu_caractere number:=0; contexte_langue number:=0; avertissement number:=0; -- les variables pour la mise à jour contexteMAJ DBMS_XMLSave.ctxType; nombreLignes number; begin fic_in:= bfilename(’xml_dir’,’donees3.xml’); -- ouvrir le fichier dbms_lob.fileopen(fic_in, dbms_lob.file_readonly); -- taille du fichier taille:=dbms_lob.getlength(fic_in); -- lire les données et mémoriser dans une variable contexte_langue:=1; dbms_lob.createtemporary(documentXML, true); dbms_lob.loadclobfromfile(documentXML, fic_in, taille, depart_destination, depart_origine, jeu_caractere, contexte_langue, avertissement); -- fermer le fichier dbms_lob.fileclose(fic_in); -- création du contexte de mise à jour contexteMAJ:=DBMS_XMLSave.newContext(’CLIENTS’); -- effacer les paramètres DBMS_XMLSave.clearUpdateColumnList(contexteMAJ); -- Colonne d’identifications DBMS_XMLSave.setKeyColumn(contexteMAJ,’NOCLI’); -- Colonnes à mettre à jour DBMS_XMLSave.setUpdateColumn(contexteMAJ,’CODE_POSTAL’); DBMS_XMLSave.setUpdateColumn(contexteMAJ,’VILLE’); -- effectuer les mises à jour nombreLignes:=DBMS_XMLSave.updateXML(contexteMAJ,documentXML); --fermer le contexte DBMS_XMLSave.closeContext(contexteMAJ); -- valider les transformations commit; end; /

Le fichier XML servant de base à la mise à jour :

- 8 - © ENI Editions - All rigths reserved

Page 260: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

<?xml version = ’1.0’?> <ROWSET> <ROW> <NOCLI>200</NOCLI> <CODE_POSTAL>49000</CODE_POSTAL> <VILLE>ANGERS</VILLE> </ROW> <ROW> <NOCLI>201</NOCLI> <CODE_POSTAL>74000</CODE_POSTAL <VILLE>ANNECY</VILLE> </ROW> </ROWSET>

c. Supprimer des données

Enfin, il est possible de se servir d’un document XML comme support à la suppression de données. Les colonnes présentes dans le document XML vont servir à la construction de la clause WHERE. Il est possible de restreindre le nombre de colonnes participant à la restriction des lignes en faisant appel à la procédure setKeyColumn.

L’exemple suivant permet de supprimer les clients n° 200 et 201. Ces informations sont stockées dans un fichier XML nommé donnees4.xml.

declare -- la variables nécessaires à la lecture d’un fichier documentXML CLOB; fic_in BFILE; taille number; depart_destination integer:=1; depart_origine integer:=1; jeu_caractere number:=0; contexte_langue number:=0; avertissement number:=0; -- les variables pour la suppression contexteSupp DBMS_XMLSave.ctxType; nombreLignes number; begin fic_in:= bfilename(’xml_dir’,’donees4.xml’); -- ouvrir le fichier dbms_lob.fileopen(fic_in, dbms_lob.file_readonly); -- taille du fichier taille:=dbms_lob.getlength(fic_in); -- lire les données et mémoriser dans une variable contexte_langue:=1; dbms_lob.createtemporary(documentXML, true); dbms_lob.loadclobfromfile(documentXML, fic_in, taille, depart_destination, depart_origine, jeu_caractere, contexte_langue, avertissement); -- fermer le fichier dbms_lob.fileclose(fic_in); -- création du contexte de suppression contexteSupp:=DBMS_XMLSave.newContext(’CLIENTS’); -- effacer les paramètres DBMS_XMLSave.clearUpdateColumnList(contexteSupp); -- Colonne d’identifications

- 9 -© ENI Editions - All rigths reserved

Page 261: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

DBMS_XMLSave.setKeyColumn(contexteSupp,’NOCLI’); -- effectuer la suppression nombreLignes:=DBMS_XMLSave.deleteXML(contexteSupp,documentXML); --fermer le contexte DBMS_XMLSave.closeContext(contexteSupp); -- valider les transformations commit; end; /

L’utilisation telle quelle du package DBMS_XMLSave est un peu fastidieuse dans l’écriture des procédures, notamment au niveau de l’initialisation du contexte. Etant donné que le contexte est lié à une table, il est possible de créer un contexte unique puis de l’utiliser, aussi bien pour effectuer des opérations d’ajout que de mise à jour ou de suppression. Cette opération est réalisable en regroupant les procédures relatives aux différentes opérations dans un package et en déclarant comme variable globale au package le contexte d’exécution des commandes du package DBMS_XMLSave.

- 10 - © ENI Editions - All rigths reserved

Page 262: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Introduction

Avec la version 10g du serveur de base de données, Oracle propose l’installation depuis le CD­Rom Compagnon du service HTML DB. Ce service permet de mettre en place une structure de bases de données et de gérer les données contenues dans ces tables au travers d’interface Web conviviales.

Avec HTML DB, il est possible de travailler avec un serveur Oracle sans pour autant maîtriser le langage SQL ni sa syntaxe. Cependant, des connaissances importantes en SQL et PL/SQL vont permettre de travailler de façon précise. L’interface HTML DB est alors utilisée pour éviter les erreurs de syntaxe et faciliter la saisie des opérations fastidieuses.

Ce service doit être installé par l’administrateur de bases de données sur le serveur Oracle 10g. Toutefois, il est possible de tester les fonctionnalités de HTML DB depuis le site internet suivant : http://htmldb.oracle.com. Après inscription (gratuite) sur ce site, il est possible d’utiliser HTML DB afin de tester le produit.

HTML DB possède également comme objectif de mettre en place, de façon très simple, une application de type Web qui utilise des données stockées dans une base relationnelle Oracle. Il va donc être possible de réaliser des rapports facilement accessibles par tous dans l’entreprise.

L’outil HTML DB permet donc de développer simplement et rapidement une interface web de saisie et de visualisation des données stockées dans une base Oracle.

HTML DB est divisé en quatre outils principaux :

Application Builderpermet de gérer une application dont l’interface graphique se présente sous forme de pages au format HTML, contenant des formulaires pour saisir les données. Ces données seront, par la suite, stockées dans des tables du schéma sous­jacent.

SQL Workshoprend possible le travail en SQL par son interface de saisie de requêtes SQL. Il est également possible d’écrire et de tester des blocs PL/SQL.

Data workshop : l’objectif de cet outil est de faciliter l’importation et l’exportation de données depuis ou vers des environnements Oracle ou autre.

Administration : c’est le module d’administration de HTML DB. Au travers de ce module, il est possible de gérer les différents utilisateurs (création, accord ou non de privilèges), de créer des espaces de travail ou encore d’obtenir des statistiques d’utilisation.

Le test du service HTML DB va être réalisé sur le site Oracle. Compte tenu que ce site est accessible par tous, une procédure d’enregistrement est présente afin de définir un espace de travail en se rattachant à un schéma, existant ou éventuellement à créer.

- 1 -© ENI Editions - All rigths reserved

Page 263: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Inscription au service HTML DB

Pour pouvoir tester ce service en ligne, il est facile de se connecter au site Oracle. Bien sûr si votre administrateur de base de données a installé HTML DB sur un serveur Oracle, cette étape d’inscription est totalement inutile. Pour pouvoir utiliser ce service, il suffit d’utiliser son nom d’utilisateur Oracle et son mot de passe, à condition de posséder les droits suffisants.

Par défaut, il est nécessaire de s’identifier avant de pouvoir travailler. Lors de la première connexion en tant que développeur, il est nécessaire de réclamer la création d’un workspace ou espace de travail. En effectuant cette demande, un formulaire de renseignements apparaît à l’écran. Il est nécessaire de remplir ce formulaire, sans oublier de saisir une adresse e­mail valide, car le login de connexion et le mot de passe vont être envoyés à cette adresse.

Normalement, l’interface HTML DB détecte automatiquement votre langue (celle du système d’exploitation de votre

- 1 -© ENI Editions - All rigths reserved

Page 264: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

poste) et adapte l’interface en conséquence. Il est ensuite nécessaire de définir le nom de l’espace de travail que l’on souhaite définir.

Étant donné que l’exemple est fait sur le site mis en place par Oracle, il n’est pas possible de se connecter à un schéma existant, à moins qu’il n’ait été créé au cours d’une précédente opération de ce type.

Après avoir fait la demande de création d’un nouveau schéma, il est nécessaire de préciser le nom de ce schéma ainsi que sa taille. Étant donné qu’ici, l’objectif est l’apprentissage du fonctionnement de HTML DB, un schéma de petite taille est suffisant.

- 2 - © ENI Editions - All rigths reserved

Page 265: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Compte tenu que ce service est offert gratuitement par Oracle, il est nécessaire de fournir une description pour expliquer le but de l’utilisation de ce service. Dans le cas présent, il suffit de préciser que l’objectif est la découverte du service HTML DB.

À l’issue de cette demande de renseignements, un écran récapitulatif est présenté.

- 3 -© ENI Editions - All rigths reserved

Page 266: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

En acceptant cette dernière étape, on met fin à la procédure de demande d’espace de travail. Rapidement, un mail de confirmation est envoyé par Oracle. Sur ce mail, le mot de passe qui permet de se connecter à son espace de travail est notifié.

Pour travailler avec cet outil, il est nécessaire de se connecter. La première étape consiste donc à fournir sur l’écran de connexion, son nom d’utilisateur, son mot de passe ainsi que l’espace de travail sur lequel on souhaite travailler.

Une fois l’ensemble de ces renseignements fournis, cliquer sur le bouton Login afin d’ouvrir une session de travail.

L’écran suivant s’affiche alors :

Se connecter à HTML DB

- 4 - © ENI Editions - All rigths reserved

Page 267: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Il est possible de sélectionner, d’une façon simple, l’atelier avec lequel on souhaite maintenant travailler.

- 5 -© ENI Editions - All rigths reserved

Page 268: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

SQL Workshop

Cet atelier SQL permet de réaliser toutes les opérations de gestion de la structure de la base de données, comme l’exécution de commandes SQL, le chargement de scripts, conserver un historique des commandes SQL, parcourir le dictionnaire....

Afin de pouvoir parcourir les principales fonctionnalités de HTML DB, il est nécessaire de créer des tables, des vues... soit tous les éléments utilisés sur un schéma classique de base de données. Il ne faut pas oublier que l’objectif premier de HTML DB est de faciliter la lisibilité des données issues d’une base de données. L’application, qui va être créée, va reprendre les mêmes tables d’exemples que celles utilisées dans cet ouvrage, c’est­à­dire : CLIENTS, ARTICLES, COMMANDES et LIGNES_CDES.

À partir de ces quatre tables, il va être possible d’illustrer les principales fonctionnalités de HTML DB. SQL Workshop propose de nombreuses facilités pour travailler avec la base, au travers de guides et d’assistants.

Sur la première ligne d’images, on trouve les différents guides et assistants, tandis que sur la seconde, sont fournis des outils de parcours du dictionnaire de données.

Bien entendu, un expert SQL peut réaliser l’ensemble des opérations depuis le processeur de commandes SQL. Toutefois, comme personne n’est à l’abri d’une erreur, particulièrement de syntaxe, il est intéressant d’utiliser les outils.

Pour créer la table des clients, c’est le guide créer un objet qui va être utilisé. Sélectionner tout d’abord le type de l’objet à créer.

- 1 -© ENI Editions - All rigths reserved

Page 269: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Pour la création d’une table, il existe la possibilité soit de la créer entièrement (ce qui va être le cas ici), ou au contraire à partir d’un ensemble de données. Dans une syntaxe SQL, le premier cas correspond à une instruction CREATE TABLE suivi du nom de la table et de la définition de l’ensemble des colonnes tandis que la seconde correspond à l’instruction CREATE TABLE suivie d’une requête SELECT afin de stocker le résultat de la requête d’extraction.

Ensuite, donner la définition des colonnes constitutives de la table : nom, type de données et précision.

Puis, il est nécessaire de définir les contraintes d’intégrité relatives à la table. La première contrainte à définir est celle de clé primaire. C’est la colonne nocli qui constitue la clé primaire de la table des clients.

- 2 - © ENI Editions - All rigths reserved

Page 270: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

L’interface propose d’associer une clé primaire numérique à une séquence.

Pour la définition des autres contraintes (unicité, validation et clé étrangère), il faut exécuter une requête SQL.

Lorsque la clé primaire est composée de plus d’une colonne alors il n’est pas possible de la définir à l’aide du guide de création de tables. Il est nécessaire de passer par une instruction SQL pour créer la totalité de la table.

Pour terminer la création des tables, il faut encore définir les autres contraintes d’intégrité. Pour cela, il est nécessaire de saisir les requêtes de type ALTER TABLE via le processeur de requête SQL.

Par exemple, pour définir la contrainte d’intégrité entre les tables COMMANDES et CLIENTS sur le numéro de clients, il est nécessaire de saisir la requête suivante :

- 3 -© ENI Editions - All rigths reserved

Page 271: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Puis la demande d’exécution est demandée en appuyant sur le bouton Exécuter du SQL, un message du type table modifiée doit alors apparaître afin de confirmer la bonne exécution de l’instruction.

Le processeur de commandes SQL va également être utilisé pour saisir des instructions du SQL DML, ou soit les instructions INSERT, UPDATE, DELETE et SELECT. Les informations ramenées par l’instruction SELECT sont présentées sous forme de tableau.

1. Créer une application

Après avoir créé la structure permettant de stocker l’information, et éventuellement l’importation de données existantes, l’intérêt de HTML DB réside dans la création d’applications. Les applications HTML DB sont au format Web et contiennent essentiellement des rapports. Mais l’application HTML DB, générée en quelques clics, permet également de définir des écrans de saisie et de modification des données. C’est donc une application simple qui est mise en place de façon automatique. Il est ensuite possible de personnaliser le modèle de cette application afin d’obtenir des écrans qui reprennent une charte graphique plus connue de l’utilisateur.

Depuis l’écran d’accueil de HTML DB, choisir l’outil Application Builder(constructeur d’application) pour pouvoir effectuer la demande de création d’une nouvelle application.

- 4 - © ENI Editions - All rigths reserved

Page 272: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Un écran de gestion des applications est présenté. Par défaut, il se positionne sur l’application d’exemple. Il est tout à fait possible d’exécuter cette application afin de tester et d’apercevoir les possibilités offertes par HTML DB, mais il est également possible de définir une nouvelle application. C’est ce dernier choix qui est fait dans l’exemple ci­après.

Dans le cas illustré par ce livre, nous créons une application qui va utiliser les tables créées avec le SQL Workshop. Mais il est à remarquer qu’HTML DB offre la possibilité de créer une application entièrement nouvelle, c’est­à­ dire basée sur des tables qui n’existent pas encore. Comme l’application s’appuie sur des tables existantes, il faut préciser

- 5 -© ENI Editions - All rigths reserved

Page 273: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

le schéma dans lequel ces tables se situent.

L’écran suivant illustre la sélection du schéma :

Lors de l’exécution de cet assistant, il est possible de savoir à quel niveau l’écran, que l’on est en train de réaliser, se situe en consultant l’arborescence située sur la gauche de l’écran.

La suite logique consiste donc à sélectionner sur le schéma quelles sont les tables et les vues qui vont être utilisées par l’application.

Dans l’exemple illustré ci­dessous, les quatre tables CLIENTS, COMMANDES, LIGCDES et ARTICLES sont sélectionnées.

Enfin, préciser le nom de l’application et quelques précisions la concernant.

- 6 - © ENI Editions - All rigths reserved

Page 274: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Enfin, un écran de résumé permet d’afficher un récapitulatif des différents choix effectués au cours de l’exécution de cet assistant. Après validation de cette dernière étape, l’application est créée.

2. Exécuter une application

Une fois l’application créée, il est nécessaire de la tester. Pour cela, demander l’exécution de l’application depuis Application builder, après avoir pris soin de sélectionner l’application désirée dans la liste déroulante, située en haut de l’écran.

La première étape lors de l’exécution de l’application consiste à demander une authentification. En effet, l’application va présenter des données et permettre leurs modifications, il est donc nécessaire de s’authentifier auparavant.

- 7 -© ENI Editions - All rigths reserved

Page 275: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Une liste d’hyperliens, située en bas de la page, permet de faire des modifications sur l’application.

L’application générée s’affiche alors. Elle permet de réaliser les opérations de base (INSERT, UPDATE, DELETE et SELECT) sur les tables sélectionnées lors de la définition de l’application.

Une troisième partie permet de faire des analyses simples, sur les données présentes dans les tables.

Enfin un onglet est défini pour chaque table et permet de travailler tout de suite avec les données stockées dans la table correspondant à l’onglet.

- 8 - © ENI Editions - All rigths reserved

Page 276: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Pour illustrer l’application générée, les écrans correspondant à la gestion de la table des clients vont être parcourus.

Depuis l’écran de création, il est possible de créer un nouveau client. C’est ce même écran qui permettra de modifier ou de supprimer un client, après sa sélection, parmi la liste de clients. L’écran de création présente autant de champs de saisie que de colonnes présentes dans la table. Il faut bien sûr saisir des informations compatibles avec le domaine de définition des colonnes.

- 9 -© ENI Editions - All rigths reserved

Page 277: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Après la saisie des données, l’appui sur le bouton Create permet d’ajouter les informations dans la table. Un écran de confirmation est alors présenté. Il est possible, à partir de cet écran, d’ajouter une nouvelle ligne d’informations dans la table ou bien de consulter le rapport, c’est­à­dire de consulter le contenu de la table. Ce même rapport est affiché si l’on sélectionne directement le nom de la table dans la colonne Report and Edit depuis la page d’accueil.

- 10 - © ENI Editions - All rigths reserved

Page 278: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Ce rapport est dynamique car il permet non seulement de trier les données en cliquant simplement sur l’en­tête de la colonne, mais également de faire une recherche extrêmement simple en saisissant uniquement le critère de recherche. Ce type de rapport permet donc un accès précis aux données, même pour un utilisateur qui ne connaît pas le SQL.

Enfin, en sélectionnant une ligne et en cliquant sur la valeur de sa clé primaire, l’écran de modification des données est affiché. Cet écran permet également de supprimer la ligne de données de la table.

3. Personnaliser une application

Après avoir parcouru les écrans générés de façon automatique par les assistants, il est normal de souhaiter aller un peu plus loin avec le produit pour découvrir comment créer un nouveau rapport afin de faciliter l’extraction et l’analyse des données.

Derrière chaque rapport présenté par HTML DB, se cache une requête d’extraction de données de type SELECT. La création d’un nouveau rapport s’effectue par l’intermédiaire d’un assistant et prend appui sur une requête SQL. L’assistant peut générer de façon dynamique la requête SELECT en offrant la possibilité de sélectionner les tables puis les colonnes, ou il est nécessaire de saisir directement la requête en SQL. Par la suite, il sera possible de personnaliser l’exécution du rapport en ajoutant des critères de sélection, ou en spécifiant les colonnes présentes dans le résultat.

Depuis Application Builder, sélectionner l’application d’exemple puis cliquer sur l’onglet Assistant afin d’exécuter l’un des nombreux assistants.

Comme tenu du fait que l’objectif est d’ajouter un rapport à partir d’une requête SELECT déjà connue, le choix va se porter sur l’assistant Etat SQL. La demande d’exécution de cet assistant va entraîner le présentation de cinq pages.

La première étape consiste à identifier le nouvel état.

- 11 -© ENI Editions - All rigths reserved

Page 279: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Ensuite, spécifier comment sera classé ce nouvel état dans l’application et donc comment il sera accessible.

Le choix se porte ici sur la création d’un nouvel onglet en plus de ceux déjà existants. En effet, l’objectif est de présenter les commandes avec leur détail et non pas seulement le contenu d’une table.

La troisième étape permet de saisir la requête SQL d’extraction d’informations. Dans un tel cas, il est souhaitable de tester la requête dans un outil tel que SQL*Plus afin de s’assurer que le résultat retourné est bien celui souhaité.

- 12 - © ENI Editions - All rigths reserved

Page 280: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Enfin, choisir des paramètres relatifs à la présentation de l’état.

Après la validation de l’écran de confirmation qui présente les éléments choisis au travers de l’assistant, l’état est créé et il est possible de le tester en exécutant l’application.

Il n’y a pas d’étape de déploiement par rapport à une application HTML DB ; toutes les modifications concernant les états sont reportées immédiatement dans l’application.

Lors de l’exécution de l’application, le nouvel onglet apparaît immédiatement.

En sélectionnant cet onglet, le rapport associé est exécuté et affiché automatiquement.

- 13 -© ENI Editions - All rigths reserved

Page 281: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Il est tout à fait possible, et souvent souhaitable, d’améliorer cet état.

Pour modifier une page existante, il existe deux possibilités, qui conduisent au même résultat :

Soit depuis application builder : après avoir sélectionné l’application, la page est à son tour sélectionnée dans la liste des pages présentes dans l’application.

Soit depuis l’exécution de l’application : après activation de l’hyperlien intitulé modifier une page, l’écran de définition de la page en question est affiché.

La page HTML de présentation du rapport est divisée en région. Chaque région contient des données de même nature, c’est­à­dire qui jouent un rôle similaire : soit critères de sélection, soit affichage du résultat. Chaque région est présentée dans la page de résultat par numéro croissant de région également appelé numéro de séquence. Chaque page peut contenir plusieurs régions. La notion de région permet de regrouper logiquement les éléments qui vont être présentés sur la page.

Dans le cas où l’objectif est de sélectionner quelques colonnes qui peuvent être présentes dans le résultat, la nouvelle région doit être placée avant celle qui contient le résultat de la requête SELECT.

- 14 - © ENI Editions - All rigths reserved

Page 282: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

La création d’une nouvelle région est réalisée en appelant l’assistant de création de région par l’intermédiaire du bouton Créer dans la zone Affichage de la page Régions.

Dans le cadre de l’exemple pris ici, la région doit être de type HTML, mais il est possible de définir d’autres types, avec d’autres contraintes d’utilisation. La saisie du titre du cadre ainsi que du numéro de séquence est obligatoire.

- 15 -© ENI Editions - All rigths reserved

Page 283: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Les trois derniers écrans de l’assistant concernent le code HTML que l’on souhaite saisir pour définir le contenu de la région, les conditions d’affichage de la région et bien entendu de la page de confirmation de création de la région. En acceptant les deux dernières étapes sans rien y ajouter, une région basique est créée, cette région sera toujours présente sur le rapport.

L’écran de synthèse de conception de la page confirme la création de la région et la répertorie parmi les régions définies dans la page dans la zone Affichage de la page Régions.

- 16 - © ENI Editions - All rigths reserved

Page 284: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Maintenant que la région est définie, il reste à y placer les différents contrôles. Dans l’exemple exposé ici, le choix va se porter sur l’affichage conditionnel de certaines colonnes. Une telle opération de sélection dynamique des colonnes présentes dans le rapport va se réaliser en trois étapes :

définir les cases à cocher relatives à l’affichage des colonnes ;

définir un bouton permettant de regénérer le rapport pour rendre en compte les modifications ;

Modifier la définition des éléments représentatifs des colonnes afin de ne les afficher que si la case à cocher est active.

Après avoir réalisé ces trois étapes, il sera possible de tester le rapport. Lors de la création de ces nouveaux éléments, des assistants vont être utilisés et le code à saisir va être extrêmement simple et réduit à son minimum.

La définition de cases à cocher sur la page va être possible depuis l’écran de conception de la page, en sélectionnant dans la zone Affichage de la page ­ Elements le bouton Créer.

- 17 -© ENI Editions - All rigths reserved

Page 285: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

La création du nouvel élément nécessite de définir son type, son nom, son numéro de séquence et la zone dans laquelle il va être défini.

Bien entendu, on peut si on le souhaite, créer d’autres éléments. Il est intéressant de remarquer la richesse des zones de saisies disponibles, afin de satisfaire aux exigences multiples et variées d’une application.

La seconde étape de définition de l’élément va être de préciser les libellés des différentes options de contrôle. Dans

- 18 - © ENI Editions - All rigths reserved

Page 286: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

l’exemple actuel, c’est l’affichage ou non du numéro de colonne et du numéro de ligne.

La zone de texte permet de saisir la description des informations qui vont être présentées sous forme de cases à cocher. Toutes ces informations seront statiques et pour chaque case à cocher, il faut indiquer le libellé suivi de la valeur ; ainsi, dans l’exemple précédent, une case à cocher portera le libellé Numero commande ce qui correspond à la valeur NOCDE. L’assistant pose ensuite des questions relatives à la présentation des informations comme le libellé, le type d’alignement, la largeur d’affichage...

Puis, l’écran suivant va permettre de préciser la source des données, ce qui est inutile dans le cas présent car les informations sont statiques.

- 19 -© ENI Editions - All rigths reserved

Page 287: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Enfin une dernière question, concernant la mise en mémoire des informations, est posée avant l’affichage de l’écran de synthèse.

Il est ensuite nécessaire de définir un nouveau bouton. Cette mise en place se fait par l’intermédiaire d’un assistant et, comme pour les éléments définis précédemment, ce bouton va appartenir à une région. Les boutons peuvent permettre différentes actions, comme la navigation vers une autre page ou encore l’envoi d’informations sur le serveur, afin qu’il réagisse en conséquence : demande de création ou demande de l’affichage des informations suivantes.

Pour pouvoir créer un bouton, il faut depuis l’écran de gestion de la page, cliquer sur le bouton Créer situé dans la zone Affichage de la page ­ Boutons. Un assistant de création du bouton se met alors en place.

La première page de cet assistant va permettre de déterminer la région qui va accueillir ce bouton.

- 20 - © ENI Editions - All rigths reserved

Page 288: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Le second écran va permettre de définir le bouton, lui même. Dans le cas étudié ici, un simple bouton HTML suffit. La sélection de ce type de bouton va limiter considérablement les étapes de l’assistant ainsi que les éléments à renseigner.

Après avoir renseigné et personnalisé les champs correspondant au nom, au libellé du bouton et à sa valeur, définir les propriétés d’affichage du bouton.

- 21 -© ENI Editions - All rigths reserved

Page 289: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Enfin, définir l’action associée à l’appui sur le bouton. Dans ce cas précis de création de bouton, il s’agit de réclamer une page située sur le serveur. Comme l’opération souhaitée est de réclamer la même page mais avec des paramètres d’affichages autres, le numéro de la page courante est renseigné dans la zone de saisie intitulée Branchement sur la page.

La dernière étape de la personnalisation de ce rapport consiste à prendre en compte la sélection des cases à cocher afin d’afficher les colonnes en conséquence. Pour cela, il est nécessaire d’afficher l’écran présentant les caractéristiques de la région qui héberge le rapport. Un simple clic sur le nom de la région, depuis la zone Affichage de page ­ Régions de l’écran de définition de la page, suffit.

- 22 - © ENI Editions - All rigths reserved

Page 290: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Depuis l’écran de définition de la région, cliquer sur l’onglet Attributs d’états pour faire apparaître les éléments représentatifs des colonnes de la requête SELECT.

C’est l’affichage conditionnel des colonnes NOCDE et NOLIG qui est concerné par la sélection ou non des cases à cocher. En cliquant sur l’icône situé à gauche du nom de la colonne apparaît la page descriptive de la colonne.

- 23 -© ENI Editions - All rigths reserved

Page 291: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

La demande d’affichage conditionnel peut être saisie dans la zone Affichage conditionnel en saisissant une expression PL/SQL qui permet la saisie de texte si la chaîne NOCDE est présente dans l’élément de type case à cocher.

Pour faire ce test, la fonction INSTR est mise à contribution. Cette fonction retourne la position de la chaîne passée en tant que second paramètre dans la chaîne passée en premier paramètre. Pour référencer l’élément correspondant à la case à cocher, il faut utiliser son nom préfixé par deux points(:) comme pour une variable définie en dehors du bloc PL/SQL.

De même que pour les rapports, HTML DB propose des assistants pour créer simplement et rapidement des formulaires de saisie d’informations. En une dizaine d’étapes, chacune très simple, l’assistant conduit la création d’un formulaire pour saisir des informations directement dans une table ou bien dans une vue.

Pour lancer cet assistant, demander la création d’une nouvelle page, mais cette fois il ne faut pas demander un rapport mais un panneau basé sur une table. Dans l’exemple ci­dessous, le panneau va être basé sur la table des clients.

- 24 - © ENI Editions - All rigths reserved

Page 292: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Après avoir sélectionné le type de l’assistant à exécuter, les deux premiers écrans permettent de sélectionner le schéma puis la table de ce schéma mise en correspondance avec le panneau en cours de création. Ensuite l’assistant demande des informations d’ordre général sur la page en cours de création, telles que son numéro, son nom...

L’étape suivante permet de sélectionner si la page apparaît ou non dans un onglet et si oui, il est nécessaire de préciser le jeu d’onglet. Puis l’assistant demande de préciser quelles sont les colonnes qui participent à la clé primaire.

- 25 -© ENI Editions - All rigths reserved

Page 293: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Ensuite, l’assistant permet de sélectionner parmi les colonnes présentes dans la table quelles sont celles qui seront présentes dans le panneau final.

L’écran suivant propose d’afficher ou non des boutons de Création, Mise à jour ou Suppression et de notifier leur libellé. Ces boutons correspondent aux instructions INSERT, UPDATE et DELETE.

- 26 - © ENI Editions - All rigths reserved

Page 294: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Enfin, il est nécessaire de définir le numéro des pages sur lequelles l’application doit se rendre en cas de création réussie ou en cas d’annulation des actions.

Il est maintenant possible de tester la nouvelle page de saisie de nouveaux clients et d’enregistrement dans la base.

Au travers de cet exemple, de nombreux assistants ont pu être exécutés et permettent ainsi de comprendre la souplesse offerte par HTML DB en terme de développement d’applications HTML. HTML DB rend possible la création de diagrammes, de calendrier, de feuille de style pour personnaliser une application, de pages d’aide et permet également la rédaction et l’envoi d’e­mail par l’intermédiaire du package HTMLDB_MAIL.

4. Travailler avec les données

L’atelier Data Workshop de HTMLDB permet d’exporter et d’importer très facilement les données depuis ou bien vers les tables utilisées dans l’espace de travail courant de HTML DB.

- 27 -© ENI Editions - All rigths reserved

Page 295: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Le fonctionnement de cet outil est encore plus riche que les utilitaires d’import et d’export fournis par Oracle pour transporter facilement les données, et leur structure, d’une base Oracle à une autre.

Les données seront au format texte, séquentiel ou bien XML.

Écran d’accueil du data Workshop.

Les données peuvent être exportées soit au format texte soit au format XML. C’est un choix à réaliser lors de la demande d’exportation en fonction des souhaits émis par le demandeur d’informations. Il va sans dire qu’un export au format XML est plus standard qu’un export au format texte car il inclut en plus des informations sur leur structure. Par exemple pour extraire les données contenues dans la table des clients au format XML il suffit depuis l’écran d’accueil du Data Workshop de cliquer sur l’hyperlien Export XML, puis de se laisser guider par l’assistant.

La première étape consiste à sélectionner le schéma qui contient les informations à exporter. Puis il faut sélectionner la table parmi une liste déroulante qui présente l’ensemble des tables définies sur le schéma sélectionné. Et enfin pour la table sélectionnée, il faut sélectionner les colonnes qui vont participer à l’export.

Exportation de données

- 28 - © ENI Editions - All rigths reserved

Page 296: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Dans l’écran ci­dessus toutes les colonnes de la table des clients ont été sélectionnées et en plus la demande d’exportation signale qu’elle souhaite obtenir le résultat sous forme de fichier. En appuyant sur le bouton de demande d’exportation, le téléchargement d’un fichier au format XML est demandé.

Après enregistrement du fichier XML sur le disque, il est possible de visualiser son contenu.

<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE ROWSET (View Source for full doctype...)> - <ROWSET> - <ROW num="1">

<NOCLI>37</NOCLI>

<NOMCLI>Ets Laroche</NOMCLI>

<ADRCLI>rue nationale</ADRCLI>

<CODE_POSTAL>49000</CODE_POSTAL>

<VILLE>Angers</VILLE>

</ROW> - <ROW num="2">

<NOCLI>13</NOCLI>

<NOMCLI>Jean</NOMCLI>

<ADRCLI>Rue des sports</ADRCLI>

<CODE_POSTAL>44000</CODE_POSTAL>

<VILLE>Nantes</VILLE>

</ROW> - <ROW num="3">

- 29 -© ENI Editions - All rigths reserved

Page 297: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

<NOCLI>35</NOCLI>

<NOMCLI>DUBOIS</NOMCLI>

<ADRCLI>Jean</ADRCLI>

<CODE_POSTAL>44200</CODE_POSTAL>

<VILLE>Nantes</VILLE>

</ROW> - <ROW num="4">

<NOCLI>15</NOCLI>

<NOMCLI>DUPONT S.A.</NOMCLI>

<ADRCLI>rue des lys</ADRCLI>

<CODE_POSTAL>37000</CODE_POSTAL>

<VILLE>TOURS</VILLE>

- </ROW> </ROWSET>

En fonction de la taille du fichier de données, une solution technique va être retenue. Dans le cas où le fichier de données a une taille inférieure ou égale à 30 Ko, il est possible de faire un copier/coller des données directement dans l’assistant d’importation au format texte. Dans le cas contraire, il est nécessaire d’établir un lien vers les données à importer.

Par exemple pour importer des données depuis un fichier texte qui utilise la tabulation ou bien la virgule comme séparateur de champ, il suffit de sélectionner l’hyperlien correspondant à une importation de données au format texte depuis l’écran d’accueil du Data Workshop.

La première étape de l’assistant consiste à sélectionner le type de cible (nouvelle table ou bien table existante), ainsi que le volume des données.

Puis les deux étapes suivantes vont permettre de sélectionner la table qui va être la cible de cette importation : sélection du schéma, puis de la table dans le schéma sélectionné.

Importation de données

- 30 - © ENI Editions - All rigths reserved

Page 298: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

Enfin, il faut placer les données à importer dans la zone de saisie.

En bas à gauche, un compteur indique le nombre d’octets actuellement utilisé, car ce type de saisie d’informations est limité à 30 Ko au maximum.

Enfin, il faut définir le mapping des colonnes, c’est­à­dire si pour chaque colonne, des données vont être insérées par cette importation.

- 31 -© ENI Editions - All rigths reserved

Page 299: Oracle 10g - litis.univ-lehavre.frlitis.univ-lehavre.fr/~sadeg/PDF/oracle_doc_2.pdf · SQL*PLUS, PL/SQL et Java. Les techniques de programmation avancées en PL/SQL sont étudiées

À la suite de cette opération, l’importation est réalisée.

- 32 - © ENI Editions - All rigths reserved