Interaction avec la base de données
Extraction
Insertion
Modification
Suppression
Structures de contrôle
Structures conditionnelles :
IF
case
Structures répétitives:
LOOP
WHILE-LOOP
FOR-LOOP
Structures répétitives:
Boucles avec étiquettes
Contrôle séquentiel avec GOTO
Opérateurs de comparaison:
IS NULL
LIKE
BETWEEN
IN
2. PLAN
Interaction avec la base de données
Extraction
Insertion
Modification
Suppression
Structures de contrôle
Structures conditionnelles :
Structures répétitives:
LOOP
WHILE-LOOP
FOR-LOOP
Structures répétitives:
IF
case
Boucles avec étiquettes
Contrôle séquentiel avec GOTO
Opérateurs de comparaison:
IS NULL
LIKE
BETWEEN
IN
2
3. MANIPULATION DES DONNÉES SQL À
PARTIR DE PL/SQL
Pour manipuler les données Oracle, on utilise les
commandes (SQL) INSERT, UPDATE, DELETE,
SELECT et LOCK TABLE.
La commande INSERT insert de nouvelles données à
des tables de la base de données;
UPDATE modifie des données;
DELETE supprime des données (non désirées);
SELECT récupère des lignes qui correspondent à vos
critères de recherche,
LOCK TABLE limite temporairement l'accès à une
table,
3
4. EXTRACTION DE DONNÉES
Pour extraire des données à partir d’un programme
PL/SQL on utilise l’instruction SELECT.
En PL/SQL on doit utiliser obligatoirement la directive
INTO avec l’instruction SELECT en PL/SQL :
SELECT liste INTO { nomVariablePLSQL [,nomVariablePLSQL]… | nomRECORD } FROM
nomTable …;
4
5. EXTRACTION DE DONNÉES
Exemple
ID
product
client_no
employe_name
dt_entree
qtyInStock
<pk>
Table : T_Command
NUMBER(7)
VARCHAR2(25)
NUMBER(7)
VARCHAR2(25)
DATE
NUMBER(7)
VARIABLE g_name CHAR(20);
DECLARE
rty_command T_Command%ROWTYPE;
v_prodcut T_Command.product %TYPE;
BEGIN
-- Extraction d’un enregistrement dans la variable rty_command
SELECT * INTO rty_command FROM T_Command WHERE ID=5;
-- Extraction de la valeur d’une colonne dans la variable v_prodcut
SELECT product INTO v_prodcut FROM T_Command WHERE ID=4;
-- Extraction de la valeur d’une colonne dans la variable globale g_name.
SELECT name INTO :g_name FROM T_Command WHERE ID=7;
END;
/
Print g_name
not null
not null
not null
null
null
null
5
6. EXTRACTION DE DONNÉES
NB1: Une requête SELECT … INTO doit renvoyer un
seul enregistrement.
Une requête qui renvoie plusieurs enregistrements, ou qui
n’en renvoie aucun, génère une erreur PL/SQL en
déclenchant des exceptions (respectivement ORA-01422
TOO_MANY_ROWS et ORA-01403 NO_DATA_FOUND).
Le traitement des exceptions sera détaillé un peux plu
loin.
NB2: Pour traiter des requêtes renvoyant plusieurs
enregistrements, il faut utiliser des curseurs (étudiés
un peux plus loin dans ce cours).
6
7. EXTRACTION DE DONNÉES
On peut utiliser les fonctions SQL à l’intérieur de
PL/SQL:
DECLARE
v_MinqtyInStock NUMBER;
v_UpperName T_Command.product%TYPE;
BEGIN
-- Monolignes
SELECT UPPER(product) INTO v_UpperName FROM T_Command WHERE
ID=5;
-- Multilignes
SELECT MIN(qtyInStock) INTO v_MinqtyInStock FROM T_Command;
END;
7
8. INSERTION DE DONNÉES
Pour l’insertion de données dans une table sous
Pl/SQL, on peut utiliser plusieurs écritures
comme il est montré dans l’exemple suivant :
8
9. DECLARE
-- Insertion des enregistrements dans la table T_Product de différentes manières
-- T_Product(ID, name, mark, QtyInStock, pricePerUnit)
rty_product T_Product%ROWTYPE;
NSERTION DE DONNÉES
v_name T_Product.name%TYPE;
v_mark T_Product.mark%TYPE;
BEGIN
INSERT INTO T_Product VALUES (1,'Lait', 'Jawda', 5000, 3.5);
v_name := 'Thé';
v_mark :='Qafila';
INSERT INTO T_Product VALUES (2, v_name, v_mark, 2000, 17.3 );
I
-- Insertion d’un enregistrement en utilisant un ROWTYPE et en spécifiant les colonnes.
rty_product.ID := 3;
rty_product.name :='Huile';
rty_product.mark :='Lesieur';
rty_product. QtyInStock:=1500;
rty_product. pricePerUnit:=10.5;
INSERT INTO T_Product (ID, name, mark, QtyInStock, pricePerUnit) VALUES
(rty_product.ID, rty_product.name, rty_product.mark, rty_product. QtyInStock, rty_product.
pricePerUnit);
-- ou bien
INSERT INTO T_Product VALUES rty_product;
COMMIT;
/* The Commit statement commits all changes for the current session. Once a commit is 9
issued, other users will be able to see your changes.*/
END;
/
10. MODIFICATION DE DONNÉES
Pour mètre à jours le contenu d’une table, comme
dans SQL, on utilise l’instruction UPDATE:
UPDATE nomTable SET nomColonne = { nomVariablePLSQL | expression | nomColonne |
(requête) } [,nomColonne2 = … ] [WHERE …];
Exemple:
DECLARE
v_price NUMBER(3,1) := 17.5;
BEGIN
UPDATE T_Product SET PricePerUnit = v_price WHERE ID= 2;
UPDATE T_Product SET PricePerUnit = PricePerUnit + 0.5 WHERE name =
'Lait';
10
COMMIT;
END;
11. MODIFICATION DE DONNÉES
NB1: contrairement à l'instruction SELECT, Si
aucun enregistrement n’est modifié par
l’instruction UPDATE, aucune erreur ne se
produit et aucune exception n’est levée,
NB2: Les affectations dans le code PL/SQL
utilisent obligatoirement l’opérateur « := » tandis
que les comparaisons ou affectations SQL
nécessitent l’opérateur « = ».
11
12. SUPPRESSION DE DONNÉES
Pour supprimer des données d’une table de la
base de données on utilise l’instruction DELETE.
DELETE FROM nomTable WHERE nomColonne = { nomVariablePLSQL | expression |
nomColonne | (requête) } [,nomColonne2 = … ] …;
Exemple:
DECLARE
v_price NUMBER(3,1) := 15.5;
BEGIN
DELETE FROM T_Product WHERE PricePerUnit > v_price;
DELETE FROM T_Product WHERE name=’Lait’;
COMMIT;
END;
/
12
13. SUPPRESSION DE DONNÉES
NB1 : contrairement à l'instruction SELECT, Si
aucun enregistrement n’est supprimé par
l’instruction DELETE, aucune erreur ne se
produit et aucune exception n’est levée,
NB2 : Un curseur implicite permet de savoir
combien d’enregistrements ont été modifiés.
13
14. LES STRUCTURES DE CONTRÔLE
Les structures de contrôle présentent l’apport le plus
important pour l’extension du SQL à PL/SQL.
Non seulement PL/SQL nous permet de manipuler des
données Oracle, il nous permet de manipuler les
données à l'aide de:
Structures conditionnelles:
PL/SQL propose deux structures pour programmer une action
conditionnelle : la structure IF et la structure CASE
Les structures répétitives:
En PL/SQL, les structures répétitives (qui sont en nombre de trois;
FOR, WHILE, LOOP) utilisent toutes l’instruction LOOP.
14
15. LES STRUCTURES DE CONTRÔLE
STRUCTURES CONDITIONNELLES: LA STRUCTURE IF
L'instruction IF permet d'exécuter une séquence
d'instructions conditionnelles
Suivant les tests à programmer, on peut distinguer
trois formes de structure IF:
IF-THEN (si-alors)
IF-THEN-ELSE (avec le sinon à programmer),
IF-THEN-ELSIF (imbrications de conditions).
NB:
L’instruction IF se termine par « END IF » et pas « ENDIF »
15
16. LES STRUCTURES DE CONTRÔLE
STRUCTURES CONDITIONNELLES: LA STRUCTURE IF
IF-THEN
IF condition THEN
instructions;
END IF;
IF-THEN-ELSE
IF condition THEN
instructions;
ELSE
instructions;
END IF;
IF-THEN-ELSIF
IF condition1 THEN
instructions;
ELSIF condition2 THEN
instructions;
ELSE
instructions;
END IF;
16
17. LES STRUCTURES DE CONTRÔLE
STRUCTURES CONDITIONNELLES: LA STRUCTURE IF
Exercice:
Ecrivez un programme qui permet de savoir si un
numéro de téléphone (déclaré et initialisé dans la
section DECLARE) est un numéro fixe ou numéro
portable.
NB1: Utiliser la fonction SUBSTR
SUBSTR( chaîne, start[, lenght] ): Extrait une chaine à partir du
l’indice start et de longueur lenght. Si start est négatif alors on
commence par la fin
NB2: Utiliser la fonction PUT_LINE du paquetage DBMS_OUTPUT
pour afficher une chaîne de caractères dans l’interface SQL*Plus
DBMS_OUTPUT.PUT_LINE (string);
17
18. LES STRUCTURES DE CONTRÔLE
STRUCTURES CONDITIONNELLES: LA STRUCTURE IF
DECLARE
v_tele CHAR(10) NOT NULL := '0539688027';
BEGIN
/*
La fonction SUBSTR permet d'extraire une sous-chaîne de caractères à partir d'une chaîne
de caractères.
La fonction PUT_LINE du paquetage DBMS_OUTPUT permet d’afficher une chaîne de
caractères dans l’interface SQL*Plus
*/
IF SUBSTR(v_tele,1,2)='05' THEN
DBMS_OUTPUT.PUT_LINE ('C''est un fixe !');
ELSE
DBMS_OUTPUT.PUT_LINE ('C''est un portable !');
END IF;
END;
18
/
19. LES STRUCTURES DE CONTRÔLE
STRUCTURES CONDITIONNELLES: LA STRUCTURE IF
PROMPT 'Entrer un numéro'
ACCEPT tel
DECLARE
v_tele CHAR(10) NOT NULL := '&tel';
BEGIN
/*
La fonction SUBSTR permet d'extraire une sous-chaîne de caractères à partir d'une chaîne
de caractères.
La fonction PUT_LINE du paquetage DBMS_OUTPUT permet d’afficher une chaîne de
caractères dans l’interface SQL*Plus
*/
IF SUBSTR(v_tele,1,2)='05' THEN
DBMS_OUTPUT.PUT_LINE ('C''est un fixe !');
ELSE
DBMS_OUTPUT.PUT_LINE ('C''est un portable !');
END IF;
19
END;
/
20. LES STRUCTURES DE CONTRÔLE
STRUCTURES CONDITIONNELLES: CASE
Pour choisir entre plusieurs valeurs ou plusieurs
actions, on peut utiliser l’instruction CASE,
Nous avons deux formes possibles pour utiliser l’instruction
CASE:
1)
2)
La structure CASE évalue une condition et renvoie une
valeur pour chaque cas,
La structure CASE évalue une condition et exécute une
action (qui peut être un bloc PL/SQL) pour chaque cas,
20
21. LES STRUCTURES DE CONTRÔLE
STRUCTURES CONDITIONNELLES: CASE
La première forme:
CASE expression
WHEN exp1 THEN instructions1 ;
WHEN exp2 THEN instructions2 ;
…
WHEN expI THEN instructionsI ;
ELSE instructionsElse ;
END CASE ;
La deuxième forme:
CASE
WHEN condition1 THEN instructions1;
WHEN condition2 THEN instructions2;
…
WHEN conditionI THEN instructionsI;
ELSE instructionsElses;
END CASE;
NB: Si la clause ELSE n’existe pas, et dans le cas ou aucune
condition n’est valide le système renvoie une erreur
21
22. LES STRUCTURES DE CONTRÔLE
STRUCTURES CONDITIONNELLES: CASE
Exercice:
Ecrivez un code PL/SQL qui permet de trouver la
mention d’un étudiant à partir de sa note (déclarée et
initialisée dans la partie DECLARE ou bien saisie à la
console).
NB:
Utiliser la fonction PUT_LINE du paquetage DBMS_OUTPUT pour
afficher une chaîne de caractères dans l’interface SQL*Plus
DBMS_OUTPUT.PUT_LINE (string);
Utiliser la commande PROMPT pour afficher un message à la console
Utiliser la commande ACCEPT pour récupérer ce qui a été saisi à la
22
console
23. LES STRUCTURES DE CONTRÔLE
STRUCTURES CONDITIONNELLES: CASE
PROMPT Entrer la note
ACCEPT v_note
DECLARE
v_mention CHAR(2);
v_note FLOAT:='&v_note';
BEGIN
CASE
WHEN v_note >= 16 THEN v_mention := 'TB';
WHEN v_note >= 14 THEN v_mention := 'B';
WHEN v_note >= 12 THEN v_mention := 'AB';
WHEN v_note >= 10 THEN v_mention := 'P';
ELSE v_mention := 'AJ';
END CASE;
DBMS_OUTPUT.PUT_LINE('La mention est: '|| v_mention);
END;
/
23
24. LES STRUCTURES DE CONTRÔLE
STRUCTURES RÉPÉTITIVES
En PL/SQL, les structures répétitives (qui sont en
nombre de trois) utilisent toutes l’instruction LOOP:
Boucle générale LOOP,
Boucle Tant-Que (WHILE),
Boucle pour (FOR).
24
25. LES STRUCTURES DE CONTRÔLE
STRUCTURES RÉPÉTITIVES: LOOP
En général, l’instruction LOOP permet d'exécuter une séquence
d'instructions plusieurs fois.
Le mot-clé LOOP est placé avant la première instruction dans la
séquence et le mot-clé END LOOP est placé après la dernière
instruction dans la séquence.
La syntaxe est la suivante:
LOOP
-- instructions à exécuter
END LOOP;
Pour sortir de la boucle LOOP on utilise l’instruction EXIT
comme suit :
LOOP
-- instructions à exécuter
EXIT [WHEN condition;]
END LOOP;
25
26. LES STRUCTURES DE CONTRÔLE
STRUCTURES RÉPÉTITIVES: LOOP
LOOP
-- instructions à exécuter
EXIT [WHEN condition;]
END LOOP;
La particularité de cette structure est que la première itération est
effectuée quelles que soient les conditions initiales.
La condition n’est évaluée qu’en fin de boucle.
Si aucune condition n’est spécifiée (condition absente), la sortie
de la boucle est immédiate.
Si la condition est fausse, la séquence d’instructions est de
nouveau exécutée. Ce processus continu jusqu’à ce que la
condition soit vraie pour passer en séquence après le END
LOOP.
26
27. LES STRUCTURES DE CONTRÔLE
STRUCTURES RÉPÉTITIVES: LOOP
Exercice:
Ecrivez un code PL/SQL qui permet de calculer la somme
des n premiers entiers: somme=n+n-1+n-2+…+2+1
Ecrivez un code PL/SQL qui permet de calculer le factoriel
de 10
27
28. LES STRUCTURES DE CONTRÔLE
STRUCTURES RÉPÉTITIVES: LOOP
DECLARE
v_somme NUMBER(4) := 0;
v_entier NUMBER(3) := 1;
BEGIN
LOOP
v_somme := v_somme+v_entier;
v_entier := v_entier + 1;
EXIT WHEN v_entier=10;
END LOOP;
DBMS_OUTPUT.PUT_LINE ('Somme = ' || v_somme);
END;
28
29. LES STRUCTURES DE CONTRÔLE
STRUCTURES RÉPÉTITIVES: LOOP
DECLARE
v_fac NUMBER := 1;
v_entier NUMBER(3) := 10;
BEGIN
LOOP
v_fac := v_fac * v_entier;
v_entier := v_entier - 1;
EXIT WHEN v_entier=0;
END LOOP;
DBMS_OUTPUT.PUT_LINE ('10!= ' || v_fac);
END;
29
30. LES STRUCTURES DE CONTRÔLE
STRUCTURES RÉPÉTITIVES: WHILE-LOOP
L’instruction WHILE-LOOP associe une condition
d'une séquence d'instructions
Avant chaque itération de la boucle, la condition est
évaluée.
Si la condition est vraie, la séquence d'instructions est
exécutée, alors le contrôle reprend au début de la boucle
Si la condition est fausse ou nulle, la boucle est ignorée et le
contrôle passe à l'instruction suivante (après le END
LOOP).
Syntaxe:
WHILE condition LOOP
-- instructions;
END LOOP;
30
31. LES STRUCTURES DE CONTRÔLE
STRUCTURES RÉPÉTITIVES: WHILE-LOOP
Exemple
DECLARE
v_somme NUMBER(4) := 0;
v_entier NUMBER(3) := 1;
BEGIN
WHILE (v_entier<=5) LOOP
v_somme := v_somme+v_entier;
v_entier := v_entier + 1;
END LOOP;
DBMS_OUTPUT.PUT_LINE ('Somme = ' || v_somme);
END;
De même, on peut utiliser l’instruction EXIT-WHEN si
on veut sortir de la boucle LOOP si une condition est
vérifiée (autre que la condition de WHILE).
31
32. LES STRUCTURES DE CONTRÔLE
STRUCTURES RÉPÉTITIVES: FOR-LOOP
La boucle FOR-LOOP, appelée compteur, permet de
réaliser une boucle itérative associée à une variable
entière qui sera incrémentée à chaque itération.
La syntaxe générale de la structure FOR-LOOP est la
suivante:
FOR compteur IN [REVERSE] valeur_Inf..valeur_Sup LOOP
-- instructions à exécuter;
END LOOP;
Le nombre d'itérations est connu d’avance même avant le
début de la boucle.
On utilise un double point (..) comme opérateur d'intervalle.
32
Le pas de la boucle FOR est toujours 1
33. LES STRUCTURES DE CONTRÔLE
STRUCTURES RÉPÉTITIVES: FOR-LOOP
Exemples:
Calculez la somme des 50 premiers entiers,
Calculez le factoriel de 9.
33
34. LES STRUCTURES DE CONTRÔLE
STRUCTURES RÉPÉTITIVES: FOR-LOOP
DECLARE
v_somme NUMBER(4) := 0;
BEGIN
FOR v_compteur IN 1..50 LOOP
v_somme := v_somme+ v_compteur ;
END LOOP;
DBMS_OUTPUT.PUT_LINE ('La somme = ' || v_somme);
END;
DECLARE
v_fact NUMBER := 1;
BEGIN
FOR v_compteur IN 1..9 LOOP
v_fact:= v_fact * v_compteur;
END LOOP;
DBMS_OUTPUT.PUT_LINE ('le factoriel = ' || v_fact);
END;
34
35. LES STRUCTURES DE CONTRÔLE
STRUCTURES RÉPÉTITIVES: FOR-LOOP
NB1 : À l’intérieur de la boucle FOR, le compteur
ne peut pas être modifié
FOR v_compteur IN 1..9 LOOP
…
v_compteur:=8; -- expression 'V_COMPTEUR' ne peut être utilisée comme cible d'affectation
END LOOP;
NB2 : la variable compteur de la boucle FOR n’est
accessible que dans la boucle.
FOR v_compteur IN 1..9 LOOP
…
END LOOP;
DBMS_OUTPUT.PUT_LINE (v_compteur); -- 'V_COMPTEUR' doit être déclaré
35
36. LES STRUCTURES DE CONTRÔLE
STRUCTURES RÉPÉTITIVES: BOUCLES AVEC ÉTIQUETTES
Comme les blocs de traitements, les boucles peuvent
être étiquetées.
L’étiquette est notée par un identifiant non déclaré
délimiter par des double crochets qui apparaît après
l’instruction de fin de boucle par la syntaxe suivante :
<<etiquette>>
LOOP
-- instructions;
END LOOP etiquette;
36
37. LES STRUCTURES DE CONTRÔLE
STRUCTURES RÉPÉTITIVES: CONTRÔLE SÉQUENTIEL AVEC GOTO
L'instruction GOTO nous permet de sauter à une
étiquette sans condition.
Lorsqu’elle est exécutée, l'instruction GOTO transfère
le contrôle à l'instruction (ou le bloc) étiquetée, comme
le montre l'exemple suivant:
…
IF rating > 90 THEN
GOTO calc_raise; -- branch to label
END IF;
...
<<calc_raise>>
IF job_title = 'SALESMAN' THEN -- control resumes here
amount := commission * 0.25;
ELSE
amount := salary * 0.10;
END IF;
…
37
38. OPÉRATEURS DE COMPARAISON
IS NULL
Retourne la valeur booléenne TRUE si son opérande est
nulle et retourne FALSE si elle n'est pas nulle
L’opérateur IS NULL est un opérateur unaire
On peut tester si une valeur est nulle comme suit :
IF variable IS NULL THEN
--END IF;
Les comparaisons avec les valeurs NULL produira
toujours la valeur NULL.
38
39. OPÉRATEURS DE COMPARAISON
LIKE
On utilise l'opérateur LIKE pour comparer de manière générique
des chaînes de caractères à une expression.
DECLARE
v_string VARCHAR2(5):='MAROC';
begin
IF v_string LIKE ('M%C') THEN
dbms_output.put_line('MAROC');
END IF;
end;
/
Le symbole % remplace un ou plusieurs caractères
Le symbole _ remplace un caractère
LIKE retourne la valeur booléenne TRUE si les arguments
correspondent et retourne FALSE si elles ne correspondent pas.39
40. OPÉRATEURS DE COMPARAISON
BETWEEN
L’opérateur BETWEEN test si une valeur se situe dans
une plage spécifiée.
Il signifie: supérieur ou égal à une valeur inférieur et
inférieure ou égale à une valeur élevée.
Exemple:
DECLARE
v_nbr NUMBER := 15;
begin
IF v_nbr BETWEEN 5 AND 15)THEN -- <==> IF (5<=v_nbr AND v_nbr<=15) THEN
dbms_output.put_line('5<=' || v_nbr|| '<=15');
END IF;
end;
/
40
41. OPÉRATEURS DE COMPARAISON
IN
L'opérateur IN compare une expression avec une liste de valeurs
Il signifie « égal à un des membres »
Par exemple, l’expression suivante teste si une valeur fait partie
d'un ensemble de valeurs ou pas :
DECLARE
v_nbr char := 't';
begin
IF v_nbr IN ('a','b','t') THEN
dbms_output.put_line('le caractère est dans la liste');
END IF;
end;
/
On peut inverser la condition
if v_nbr NOT IN ('a','b','t') THEN
dbms_output.put_line('le caractère n est pas dans la liste');
end if;
41