Cours PL/SQL

Support d’introduction au langage PL SQL


Télécharger Support d’introduction au langage PL SQL

★★★★★★★★★★3.5 étoiles sur 5 basé sur 1 votes.
Votez ce document:

Télécharger aussi :


Fondements des bases de données

Programmation en PL/SQL Oracle (1/2)

Équipe pédagogique BD

Version du 12 février 2014

Langage PL/SQL

Commandes

Curseurs

Pourquoi PL/SQL ?

PL/SQL = PROCEDURAL LANGUAGE/SQL

I SQL est un langage non procédural

I Les traitements complexes sont parfois difficiles à écrire si on ne peut utiliser des variables et les structures de programmation comme les boucles et les alternatives I On ressent vite le besoin d’un langage procédural pour lier plusieurs requêtes SQL avec des variables et dans les structures de programmation habituelles

Principales caractéristiques

I Extension de SQL : des requêtes SQL cohabitent avec les structures de contrôle habituelles de la programmation structurée (blocs, alternatives, boucles).

I La syntaxe ressemble au langage Ada ou Pascal.

I Un programme est constitué de procédures et de fonctions. I Des variables permettent l’échange d’information entre les requêtes SQL et le reste du programme

Utilisation de PL/SQL

I PL/SQL peut être utilisé pour l’écriture des procédures stockées et des triggers.

I (Oracle accepte aussi le langage Java)

I Il convient aussi pour écrire des fonctions utilisateurs qui peuvent être utilisées dans les requêtes SQL (en plus des fonctions prédéfinies).

I Il est aussi utilisé dans des outils Oracle I Ex : Forms et Report.

Utilisation de PL/SQL (suite)

Le PL/SQL peut être utilisé sous 3 formes :

1.    un bloc de code, exécuté comme une unique commande SQL, via un interpréteur standard (SQLplus ou iSQL*PLus)

2.    un fichier de commande PL/SQL

3.    un programme stocké (procédure, fonction, trigger)

Langage PL/SQL

Commandes

Curseurs

Blocs

I Un programme est structuré en blocs d’instructions de 3 types :

I procédures ou bloc anonymes, I procédures nommées, I fonctions nommées.

I Un bloc peut contenir d’autres blocs.

I Considérons d’abord les blocs anonymes.


Structure d’un bloc anonyme

DECLARE

?? d e f i n i t i o n      des  v a r i a b l e s

BEGIN

?? code      du    programme

EXCEPTION

?? code      de     gestion      des

e r r e u r s

END;

Seuls BEGIN et END

sont obligatoires

Les blocs se terminent par un ;


Déclaration, initialisation des variables

I Identificateurs Oracle :

I 30 caractères au plus,

I commence par une lettre,

I peut contenir lettres, chiffres, _, $ et # I pas sensible à la casse.

I Portée habituelle des langages à blocs

I Doivent être déclarées avant d’être utilisées

I Déclaration et initialisation

I Nom_variable type_variable := valeur;

I Initialisation

I Nom_variable := valeur;

I Déclarations multiples interdites.

Exemples

I age integer;

I nom varchar(30);

I dateNaissance date;

I ok boolean := true;

Plusieurs façons d’affecter une valeur à une variable

I Opérateur d’affectation n:=.

I Directive INTO de la requête SELECT.

Exemples

I dateNaissance := to_date(’10/10/2004’,’DD/MM/YYYY’);

I SELECT nom INTO v_nom FROM emp

WHERE matr = 509;

Attention

Pour éviter les conflits de nommage, préfixer les variables

PL/SQL par v_



SELECT INTO

Instruction SELECT expr1,expr2, INTO var1, var2,

I Met des valeurs de la BD dans une ou plusieurs variables var1, var2,

I Le SELECT ne doit retourner qu’une seule ligne

I Avec Oracle il n’est pas possible d’inclure un SELECT sans INTO dans une procédure.

I Pour retourner plusieurs lignes, voir la suite du cours sur les curseurs.

Types de variables

VARCHAR2

I Longueur maximale : 32767 octets; I Exemples : name VARCHAR2(30); name VARCHAR2(30) := ’toto’;

NUMBER(long,dec)

I Long : longueur maximale; I Dec : longueur de la partie décimale; I Exemples : num_telnumber(10); toto number(5,2)=142.12;

DATE

I Fonction TO_DATE; I Exemples : start_date := to_date(’29-SEP-2003’,’DD-MON-YYYY’); start_date := to_date(’29-SEP-2003:13:01’,’DD-MON-YYYY:HH24:MI’);

BOOLEAN

I TRUE

I FALSE

I NULL

Déclaration %TYPE et %ROWTYPE

v_nom .%TYPE;

On peut déclarer qu’une variable est du même type qu’une colonne d’une table ou (ou qu’une autre variable).

v_employe emp%ROWTYPE;

Une variable peut contenir toutes les colonnes d’un tuple d’une table (la variable v_employe contiendra une ligne de la table emp).

Important pour la robustesse du code

Exemple

DECLARE

?? Declaration v_employe emp%ROWTYPE;

v_nom emp .nom.%TYPE;

BEGIN SELECT ? INTO v_employe

FROM emp WHERE matr = 900; v_nom := v_employe .nom; v_employe . dept := 20;

. . .

?? I n s e r t i o n d ’ un tuple dans la baseINSERT into emp VALUES v_employe ;

END;

Vérifier à bien retourner un seul tuple avec la requête SELECT INTO

Langage PL/SQL

Commandes

Curseurs

Test conditionnel

IF-THEN

IF v_date > ’01?JAN?08 ’ THEN v_salaire := v_salaire ? 1.15; END IF ;

IF-THEN-ELSE

IF      v_date >          ’01?JAN?08 ’ THEN

         v_salaire       :=                v_salaire ?

ELSE

1.15;

v_salaire := v_salaire ? END IF ;

IF-THEN-ELSIF

IF v_nom =             ’PARKER ’ THEN

1.05;

         v_salaire       :=                v_salaire ?

1.15;

ELSIF v_nom = ’SMITH ’ THEN v_salaire := v_salaire ? 1.05;

END IF ;


CASE

CASE s e l e c t i o n

WHEN expression1 THEN r e s u l t a t 1

WHEN expression2 THEN r e s u l t a t 2

. . .

ELSE               r e s u l t a t END;

Exemple

          val       := CASE c i t y

WHEN ’TORONTO’ THEN ’RAPTORS’

CASE renvoie une valeur qui vaut resultat1 ou resultat2 ou ou resultat par défaut.


WHEN ’LOS?ANGELES ’ THEN ’LAKERS ’

WHEN ’SAN?ANTONIO ’ THEN ’SPURS ’

ELSE      ’NO?TEAM’

END;

Les boucles

LOOP i n s t r u c t i o n s ;



EXIT[WHEN condition ] ; i n s t r u c t i o n s ;

END LOOP;

WHILE condition LOOP i n s t r u c t i o n s ; END LOOP;

Exemple

LOOP monthly_value := daily_value ? 31; EXIT WHEN monthly_value > 4000;

END LOOP;

Obligation d’utiliser la commande EXIT pour éviter une boucle infinie.

FOR

FOR v a r i a b l e     IN      [REVERSE]       debut . . f i n

LOOP i n s t r u c t i o n s ; END LOOP;

I La variable de boucle prend successivement les valeurs de debut,debut + 1,debut + 2, , jusqu’à la valeur fin.

I On pourra également utiliser un curseur dans la clause IN (dans quelques slides).

I Le mot clef REVERSE à l’effet escompté.

Exemple

FOR Lcntr        IN REVERSE 1..15 LOOP

                  LCalc     :=        Lcntr ? 31;

END LOOP;

Affichage

I Activer le retour écran : set serveroutput on size 10000

I Sortie standard : dbms_output.put_line(chaîne); I Concaténation de chaînes : opérateur ||

Exemple

DECLARE i       number ( 2 ) ; BEGIN FOR i     IN            1 . . 5 LOOP

dbms_output . put_line ( ’Nombre : ? ’ | | i ) ; END LOOP;

END;

/

Le caractère / seul sur une ligne déclenche l’évaluation.

Affichage

Exemple bis

DECLARE compteur number ( 3 ) ;

               i    number ( 3 ) ;

BEGIN SELECT COUNT(?) INTO compteur

FROM EtudiantLIF10 ;

FOR i IN 1 . . compteur LOOP dbms_output . put_line ( ’Nombre? : ?L3IF? ’ | | i ) ; END LOOP;

END;

Langage PL/SQL

Commandes

Curseurs

Les curseurs

Toutes les requêtes SQL sont associées à un curseur :

I Ce curseur représente la zone mémoire utilisée pour analyser et exécuter la requête.

I Le curseur peut être implicite (pas déclaré par l’utilisateur) ou explicite.

I Les curseurs explicites permettent de manipuler l’ensemble des résultats d’une requête.

Les curseurs implicites sont tous nommés SQL

DECLARE nb_lignes        integer ; BEGIN

DELETE FROM emp WHERE dept = 10; nb_lignes := SQL%ROWCOUNT;

. . .

END;

Attributs des curseurs

Tous les curseurs ont des attributs que l’utilisateur peut utiliser :

%ROWCOUNT Nombre de lignes traitées par le curseur.

%FOUND Vrai si au moins une ligne a été traitée par la requête ou le dernier fetch.

%NOTFOUND Vrai si aucune ligne n’a été traitée par la requête ou le dernier fetch.

%ISOPEN Vrai si le curseur est ouvert (utile seulement pour les curseurs explicites)


Pour traiter les SELECT qui renvoient plusieurs lignes

I Les curseurs doivent être déclarés explicitement. A la déclaration, on explicite la requête SELECT dont le résultat sera parcouru par le curseur.

I Le code doit les utiliser avec les commandes

I OPEN moncurseur, pour ouvrir le curseur;

I FETCH moncurseur, pour avancer le curseur à la ligne suivante;

I CLOSE moncurseur, pour refermer le curseur

Utilisation

I On utilise souvent les curseurs dans une boucle FOR qui permet une utilisation implicite des instructions OPEN, FETCH et CLOSE.

I Généralement, on sort de la boucle quand l’attribut NOTFOUND est vrai.



Exemple de boucle LOOP pour les curseurs

DECLARE

CURSOR c _ s a l a i r e s       IS

SELECT s a l

FROM emp ; v_salaire number ( 4 ) ; v_total number ( 6 ) ;

BEGIN v_total         :=             0;

OPEN c _ s a l a i r e s ;

LOOP

FETCH c _ s a l a i r e s INTO v_salaire ;

EXIT WHEN c _ s a l a i r e s%NOTFOUND;

IF v_salaire IS NOT NULL THEN v_salaire := v_total + v_salaire ;

dbms_output . put_line ( t o t a l ) ; END IF ;

END LOOP; CLOSE c _ s a l a i r e s ; dbms_output . put_line ( v_total ) ;

END;

Déclaration d’un type associé à un curseur

DECLARE CURSOR c                IS

SELECT matr ,       nom,    s a l

FROM emp ; employe c%ROWTYPE;

BEGIN OPEN c ; FETCH c INTO employe ; IF employe . s a l IS NOT NULL THEN

. . .

END IF ; END;


Boucle FOR pour un curseur

I Elle simplifie la programmation car elle évite d’utiliser explicitement les instruction OPEN, FETCH et CLOSE.

I En plus elle déclare implicitement une variable de type ROW associée au curseur.

Exemple

DECLARE

CURSOR c_nom_clients IS SELECT nom, adresse

FROM c l i e n t s ;

BEGIN

FOR l e _ c l i e n t IN c_nom_clients LOOP dbms_output . put_line (

                          ’ Employe? : ? ’        | | UPPER( l e _ c l i e n t .nom)     | |

’? V i l l e ? : ? ’ | | l e _ c l i e n t . adresse ) ; END LOOP;

END;

Préfixer le nom d’un curseur par c_ pour éviter les confusions

Curseurs paramétrés

I Un curseur paramétré peut servir plusieurs fois avec des valeurs des paramètres différentes.

I On doit fermer le curseur entre chaque utilisation de paramètres différents si on utilise pas la boucle FOR dédiée.

Exemple

DECLARE CURSOR c ( p_dept         integerIS

SELECT dept ,       nom

FROM emp

WHERE dept = p_dept ;

BEGIN

FOR employe      in       c (10) LOOP

dbms_output . put_line ( employe .nom ) ;

END LOOP;

FOR employe      in       c (20) LOOP

dbms_output . put_line ( employe .nom ) ;

END LOOP; END;

Fin du cinquième cours.



98