SEANCE 7
Structures de Contrôle
(Conditions & Boucles)
Révision:
Erreurs fréquentes
BASES DE DONNEES RELATIONNELLES
Erreur 1
SQL> DECLARE
2 v_last_name VARCHAR2(20);
3 BEGIN
4 SELECT last_name INTO v_last_name
5 FROM employees
6 WHERE employee_ID=1000;
7 END;
8 /
DECLARE
*
ERREUR à la ligne 1 :
ORA-01403: aucune donnée trouvée
ORA-06512: à ligne 4
ORACLE PL/SQL
BASES DE DONNEES RELATIONNELLES
Erreur 2
SQL> DECLARE
2 v_last_name VARCHAR2(20);
3 BEGIN
4 SELECT last_name INTO v_last_name
5 FROM employees
6 WHERE employee_ID=100 OR employee_ID=2;
7 END;
8 /
DECLARE
*
SOLUTIO ERREUR à la ligne 1 :
CURSEUR N ORA-01422: l'extraction exacte ramène plus que le nombre
de lignes demandé
ORA-06512: à ligne 4
ORACLE PL/SQL
Objectifs
A la fin de ce chapitre, vous saurez :
• Reconnaître les commandes de programmation
structurée et leurs applications
• Ecrire une instruction IF
• Reconnaître et écrire les différents types de boucles
• Manipuler les tables logiques
• Maîtriser la programmation en utilisant des boucles
imbriquées et étiquettes
Le Processus d’Exécution PL/SQL
• Pous pouvez modifier l’enchaînement logique des
instructions en utilisant des instructions conditionnelles IF
ou des structures de boucles.
Sommaire
I. Instructions conditionnelles IF
II. Instructions conditionnelles CASE
III. Conditions logiques
IV. Contrôles itératifs (LOOP, FOR, WHILE)
V. Enregistrements
I. Instructions conditionnelles
IF
I. Instructions conditionnelles IF
Les Instructions conditionnelles IF sont :
IF <condition> THEN IF <condition> THEN IF <condition> THEN
xx xx xx
END IF; ELSE ELSIF <condition2>
xxx THEN
END IF; xxx
ELSE
xxxx
END IF;
I. Instructions conditionnelles IF
Instruction IF simple :
Example :
Si le nom du produit est ‘Intel Xeon E5-2660 V3’ , lui
associer le prix =1220.
IF v_product_name = 'Intel Xeon E5-2660 V3' THEN
v_list_price := 1220;
END IF;
I. Instructions conditionnelles IF
Instruction IF THEN ELSE (Processus d’Exécution)
TRUE FALSE
I. Instructions conditionnelles IF
Instruction IF THEN ELSE:
IF condition1 THEN
instruction1;
instruction 2;
ELSE
instruction 3;
END IF;
I. Instructions conditionnelles IF
Instruction IF THEN ELSE:
Example :
Etant le produit ID=12: DECLARE
v_difference products.list_price%TYPE;
üDéclarer ‘Acceptable’ pour BEGIN
select list_price - standard_cost into
lesquels la différence ente le v_difference
prix de vente d’achat est from products
where product_ID = 12;
moins de 200dh. IF v_difference > 200 THEN
dbms_output.put_line(‘Non acceptable’);
üSinon, déclarer ‘Non ELSE
acceptable’ dbms_output.put_line(‘Acceptable’);
END IF;
END;
/
I. Instructions conditionnelles IF
Instruction IF THEN ELSIF ELSE
(Processus d’Exécution) IF condition
TRUE FALSE
TRUE FALSE
I. Instructions conditionnelles IF
Instruction IF ELSIF ELSE:
IF condition1 THEN
instruction1;
instruction 2;
ELSIF condition2 THEN
instruction 3;
instruction 4;
ELSIF condition3 THEN
instruction 5;
instruction 6;
ELSE instruction 7;
END IF;
I. Instructions conditionnelles IF
Instruction IF THEN ELSIF
ELSE:
SQL> DECLARE
Example : 2 x integer := 20; y integer := 20;
3 BEGIN
4 IF x<Y THEN
5 DBMS_OUTPUT.PUT_LINE (x || ' < ' ||y);
6 ELSIF x=Y THEN
7 DBMS_OUTPUT.PUT_LINE (x || ' = ' ||y);
8 ELSIF x>Y THEN
9 DBMS_OUTPUT.PUT_LINE (x || ' > ' ||y);
10 ELSE
11 DBMS_OUTPUT.PUT_LINE ('Bizzare!!');
12 END IF ;
13 END;
14 /
20 = 20
I. Instructions conditionnelles IF
Instruction IF THEN ELSIF
ELSE:
Example : DECLARE
v_list_price products.list_price%TYPE;
üSi le prix du produit BEGIN
select list_price into v_list_price
sélectionné (ID=12) est plus from products
chère que 5000, afficher where product_ID = 12;
IF v_list_price > 5000 THEN
“cher”. dbms_output.put_line(‘cher’);
ELSIF v_list_price > 1500 THEN
üSi le prix est entre 1500 et dbms_output.put_line(‘normal);
5000, affichier “normal”. ELSE
dbms_output.put_line(‘pas cher’);
üSinon (moins de 1500), END IF;
END;
afficher “pas cher”. /
I. Instructions conditionnelles
CASE
I. Instructions conditionnelles CASE
Instruction CASE :
CASE selecteur
WHEN expression1 THEN instruction1;
WHEN expression2 THEN instruction2;
…
WHEN expression3 THEN instruction3;
ELSE instruction4;
END CASE;
I. Instructions conditionnelles CASE
Example 1 :
SQL> DECLARE
2 x integer := 2;
3 BEGIN
4 CASE x
5 WHEN 1 THEN DBMS_OUTPUT.PUT_LINE ('Le premier');
6 WHEN 2 THEN DBMS_OUTPUT.PUT_LINE ('Le deuxième');
7 WHEN 3 THEN DBMS_OUTPUT.PUT_LINE ('Le troisième');
8 ELSE DBMS_OUTPUT.PUT_LINE ('Le dernier');
9 END CASE;
10 END;
11 /
Le deuxième
Procédure PL/SQL terminée avec succès.
I. Instructions conditionnelles CASE
Example 2 :
SQL> DECLARE
2 x integer := 2;
3 BEGIN
4 CASE
5 WHEN x=1 THEN DBMS_OUTPUT.PUT_LINE ('Le premier');
6 WHEN x=2 THEN DBMS_OUTPUT.PUT_LINE ('Le deuxième');
7 WHEN x=3 THEN DBMS_OUTPUT.PUT_LINE ('Le troisième');
8 ELSE DBMS_OUTPUT.PUT_LINE ('Le dernier');
9 END CASE;
10 END;
11 /
Le deuxième
Procédure PL/SQL terminée avec succès.
III. Conditions logiques
III. Conditions logiques
Conditions Booléennes
– Vous pouvez manipuler les valeurs nulles avec
l’opérateur IS NULL.
– Toute expression arithmétique contenant une valeur
nulle est évaluée à NULL.
– Les expressions concaténées avec des valeurs nulles
traitent ces valeurs nulles comme des chaînes vides.
III. Conditions logiques
Conditions logiques
Quelle est la valeur de V_FLAG dans chaque cas ?
v_flag := v_reorder_flag AND v_available_flag;
III. Conditions logiques
Tables logiques
Ecrire une condition booléenne simple avec des opérateurs
de comparaison.
IV. Contrôles itératifs :
Instructions de boucle
IV. Contrôles itératifs : Instructions de boucle
• Les boucles permettent de réaliser plusieurs fois une
instruction ou une séquence d’instructions.
• Il y a trois types de boucles :
– La boucle Basique LOOP
– La boucle FOR
– La boucle WHILE
IV. Contrôles itératifs : Instructions de boucle
1. La boucle Basique LOOP
2. La boucle FOR
3. La boucle WHILE
4. Les boucles Imbriquées
5. Mot clé EXIT
6. Les étiquettes (dans les boucles imbriquées)
IV. Contrôles itératifs : Instructions de boucle
1. La boucle Basique
LOOP
instruction1;
. . .
EXIT [WHEN condition];
END LOOP;
•EXIT force la sortie de la boucle sans conditions.
•EXIT WHEN permet une sortie de boucle si la condition est vraie.
Où : condition est une variable booléenne
ou une expression
(TRUE, FALSE, ou NULL);
IV. Contrôles itératifs : Instructions de boucle
1. La boucle Basique
Exemple 1 le nombre est :0
le nombre est :1
On veut afficher les nombres de 0 à 10 (par ligne) le nombre est :2
le nombre est :3
le nombre est :4
SET SERVEROUTPUT ON le nombre est :5
DECLARE le nombre est :6
v_compteur NUMBER(2) := 0; le nombre est :7
BEGIN le nombre est :8
LOOP le nombre est :9
dbms_output.put_line('le nombre est :' || v_compteur); le nombre est :10
v_compteur := v_compteur + 1;
EXIT WHEN v_compteur > 10;
END LOOP; Procédure PL/SQL
END; terminée.
IV. Contrôles itératifs : Instructions de boucle
1. La boucle Basique
Exemple 1 le nombre est :0
le nombre est :1
On veut afficher les nombres de 0 à 10 (par ligne) le nombre est :2
le nombre est :3
le nombre est :4
SET SERVEROUTPUT ON
le nombre est :5
DECLARE
le nombre est :6
v_compteur NUMBER(2) := 0;
le nombre est :7
BEGIN
le nombre est :8
LOOP
le nombre est :9
dbms_output.put_line('le nombre est :' || v_compteur);
le nombre est :10
v_compteur := v_compteur + 1;
IF v_compteur > 10 THEN
EXIT;
Procédure PL/SQL
END IF;
terminée.
END LOOP;
END;
IV. Contrôles itératifs : Instructions de boucle
2. La Boucle FOR IN LOOP
FOR compteur in [REVERSE] borne_inférieure..borne_supérieure LOOP
instruction1;
instruction2;
. . .
END LOOP;
ü compteur : un entier déclaré implicitement, dont la valeur décroît ou augmente
automatiquement (elle décroît si le mot clé REVERSE est utilisé) de 1 à chaque itération de
la boucle jusqu’à ce que la borne supérieure ou inférieure soit atteinte
ü REVERSE : mot clé indiquant que le compteur décroît à chaque itération de la boucle
depuis la borne supérieure jusqu’à la borne inférieure
ü Borne inférieure : borne inférieure du compteur (est toujours indiquée en premier)
ü Borne supérieure borne supérieure du compteur
IV. Contrôles itératifs : Instructions de boucle
2. La Boucle FOR
ü On utilise une boucle FOR pour contrôler le nombre d’itérations.
ü On ne déclare pas le compteur, sa déclaration est implicite.
ü N’utiliser le compteur qu’à l’intérieur de la boucle
• car il n’est pas défini en dehors.
ü Ne jamais modifier le compteur.
IV. Contrôles itératifs : Instructions de boucle
2. La Boucle FOR
Exemple 1 0
1
On veut afficher les nombres de 0 à 10 (par ligne) en 2
3
utilisant la boucle FOR. 4
5
6
SET SERVEROUTPUT ON 7
DECLARE 8
v_compteur NUMBER(2) := 0; 9
BEGIN 10
FOR v_compteur in 0..10 LOOP
dbms_output.put_line(v_compteur);
END LOOP; Procédure PL/SQL
END; terminée.
IV. Contrôles itératifs : Instructions de boucle
2. La Boucle FOR
Exemple 2 0
1
On veut afficher les nombres de 5 à 1 (par ligne) en 2
3
utilisant la boucle FOR. 4
5
6
SET SERVEROUTPUT ON 7
DECLARE 8
v_compteur NUMBER(2) := 0; 9
BEGIN 10
FOR v_compteur REVERSE 1..5 LOOP
dbms_output.put_line(v_compteur);
END LOOP; Procédure PL/SQL
END; terminée.
IV. Contrôles itératifs : Instructions de boucle
2. La Boucle FOR
Exemple 3
Pour les produits ayant le product_ID entre 1 et 100,
augmenter le produit de vente (list_price) de 10% 5
4
3
2
SET SERVEROUTPUT ON
1
DECLARE
BEGIN
Procédure
FOR v_compteur in 1..100 LOOP
PL/SQL
UPDATE Products
terminée.
SET list_price = list_price + 0.1 * list_price
WHERE product_ID = v_compteur ;
END LOOP;
END;
IV. Contrôles itératifs : Instructions de boucle
2. La Boucle FOR
Exemple 3 --> Résultat
IV. Contrôles itératifs : Instructions de boucle
2. La Boucle FOR
Exemple 4
Pour les clients (Costumer_ID) de 1 à 5, on veut leur
créer une commande chacun, avec:
üStatus = ‘Pending’
üSalesman_ID=1
üorder_data = aujoud’hui
üRemarque: Order_ID est incrémenté automatiquement
BEGIN
FOR v_compteur in 1..5 LOOP
INSERT INTO ORDERS (customer_ID, status,
salesman_ID, order_date)
VALUES (v_compteur, ‘Pending’, 1, SYSDATE());
END LOOP;
END;
IV. Contrôles itératifs : Instructions de boucle
2. La Boucle FOR
Exemple 4 -> Résultat
IV. Contrôles itératifs : Instructions de boucle
2. La Boucle FOR
Exemple 5
SQL> BEGIN
2 FOR i IN 1..5 LOOP
3 DBMS_OUTPUT.PUT_LINE (i);
4 EXIT WHEN i>3;
5 END LOOP;
6 END;
7 /
1
2
3
4
Procédure PL/SQL terminée avec succès.
IV. Contrôles itératifs : Instructions de boucle
3. La Boucle WHILE
WHILE condition LOOP La condition est
instruction1; évaluée au début de
instruction2; chaque itération.
. . .
END LOOP;
• condition : une variable ou une expression booléenne (TRUE,
FALSE, ou NULL)
IV. Contrôles itératifs : Instructions de boucle
2. La Boucle WHILE
Exemple 1
Pour les clients (Costumer_ID) de 1 à 5, on veut leur
créer une commande chacun, avec:
üStatus = ‘Pending’
üSalesman_ID=1
DECLARE
üorder_data = aujoud’hui v_compteur number(2) :=1;
üRemarque: Order_ID est incrémenté
BEGIN automatiquement
WHILE v_compteur <= 5 LOOP
INSERT INTO ORDERS (customer_ID, status,
salesman_ID, order_date)
VALUES (v_compteur, ‘Pending’, 1, SYSDATE())
v_compteur := v_compteur + 1;
END LOOP;
END;
IV. Contrôles itératifs : Instructions de boucle
2. La Boucle WHILE
Exemple 1
Pour les commandes (order_ID) de 105 à 110, on
veut changer le status de Pending à Shipped:
DECLARE
v_compteur number := 105;
BEGIN
WHILE v_compteur <= 110 LOOP
UPDATE ORDERS
SET status = ‘Shipped’
WHERE order_ID = v_compteur;
v_compteur := v_compteur + 1;
END LOOP;
END;
IV. Contrôles itératifs : Instructions de boucle
3. La Boucle WHILE
ü On utilise une boucle FOR pour répéter des instructions tant
qu’une condition est vérifiée (condition = vrai)
ü Si la variable impliquée dans les conditions ne change pas au
cours de la boucle, la condition est toujours vérifiée et la boucle
ne s’arrête jamais.
ü Note : Si la condition est évaluée à NULL, la boucle est ignorée
et l’exécution du programme reprend à l’instruction suivant le
END LOOP.
IV. Contrôles itératifs : Instructions de boucle
4. Les Boucles Imbriquées
üOn peut imbriquer des boucles à plusieurs niveaux.
4. Les Boucles Imbriquées
Exercice: DECLARE
i number(3);
Le but est d’afficher les tables de j number(3);
multiplications de 1, 2 et 3 BEGIN
i := 1;
LOOP
j:= 1;
LOOP
dbms_output.put_line(i || 'x' || j || ' = ' || i*j);
j := j + 1;
EXIT WHEN j = 11;
END LOOP;
i := i + 1;
EXIT WHEN i =4;
END LOOP;
END;
5. Le mot clé EXIT
• Lorsque le moteur PL/SQL rencontre ce
mot-clé, il sortira immédiatement de la
boucle actuelle.
• Si le moteur PL/SQL rencontre EXIT
dans une boucle imbriquée, alors il
sortira de la boucle dans laquelle il a été
défini (la boucle interne) mais pas de la
boucle externe.
5. Le mot clé EXIT
Exemple:
DECLARE Résultat de l’exécution:
v_a number(2) := 10;
BEGIN
-- while loop execution value of a: 10
WHILE v_a < 20 LOOP value of a: 11
dbms_output.put_line ('Valeur de : ' || v_a); value of a: 12
v_a := v_a + 1; value of a: 13
IF v_a > 15 THEN
value of a: 14
-- Sortir de la boucle
EXIT; value of a: 15
END IF;
END LOOP; PL/SQL procedure
END; successfully completed.
/
6. Les étiquettes (dans les boucles imbriquées)
üOn utilise les étiquettes pour différencier les blocs et
les boucles.
üLa commande EXIT permet de quitter la boucle maître
en référencant l’étiquette de celle-ci.
6. Les étiquettes (dans les boucles imbriquées)
<<BOUCLE_EXTERNE>>
LOOP
<execution_block_starts>
...
<<BOUCLE_INTERNE>>
LOOP --interne
<execution_part> La boucle
END LOOP; interne
...
<execution_block_ends>
END LOOP;
• Le '<< >>' et '<< >>' sont les étiquettes de ces boucles.
6. Les étiquettes (dans les boucles imbriquées)
Exemple
• Le '< >' et '< >' sont les étiquettes de ces boucles.
V. Les enregistrements
V. Les enregistrements
Déclaration d’un enregistrement
TYPE nom_type_rec IS RECORD (
nom_champ1 type_élément1 [[ NOT NULL] := expression ],
nom_champ2 type_élément2 [[ NOT NULL] := expression ],
…
nom_champN type_élémentN[[ NOT NULL] := expression ]
);
Nom_variable nom_type_rec ;
V. Les enregistrements
Déclaration d’un enregistrement
• Exemple:
TYPE T_REC_EMP IS RECORD (
Num EMPLOYEES.employee_ID%TYPE,
Nom EMPLOYEES.last_name%TYPE,
Pre EMPLOYEES.first_name%TYPE
);
EMP T_REC_EMP ;
V. Les enregistrements
• Exercise: Afficher le nom et le prénom de l’employé ID 201. Utiliser la notion
d’enregistrement pour récupérer ce nom et ce prénom.
SQL> DECLARE
2 TYPE T_EMP IS RECORD (
3 NOM_EMP employees.last_name%TYPE,
4 PRENOM_EMP employees.first_name%TYPE
5 );
6 EMP T_EMP;
7 BEGIN
8 SELECT last_name, first_name INTO EMP
9 FROM employees
10 WHERE employee_ID=201;
11 DBMS_OUTPUT.PUT_LINE ('Le nom de l’’employé 201 est '|| EMP.NOM_EMP);
12 DBMS_OUTPUT.PUT_LINE ('son prénom est '|| EMP.PRENOM_EMP);
13 END;
14 /
Les enregistrements
Déclaration d’un %ROWTYPE
• Exercise: Afficher tous les détails du poste ID ‘AD_PRES’.
SQL> DECLARE
2 JOB jobs%ROWTYPE;
3 BEGIN
4 SELECT * INTO JOB
5 FROM jobs
6 WHERE job_ID = ‘AD_PRES’;
7 DBMS_OUTPUT.PUT_LINE ('Détails du job AD_PRES :');
8 DBMS_OUTPUT.PUT_LINE ('NOM '|| JOB.job_title);
10 DBMS_OUTPUT.PUT_LINE ('Salaire minimum '|| JOB.min_salary);
11 DBMS_OUTPUT.PUT_LINE ('Salaire maximum '|| JOB.max_salary);
16 END;
17 /
Résumé
Résumé
Vous êtes capable de modifier l’enchaînement logique des
instructions en utilisant des structures de contrôle :
• Conditionnelle (instruction IF)
• Boucles :
– Boucle basique
– Boucle FOR
– Boucle WHILE
– Instruction EXIT
Présentation de l’Exercice
– Ecrire des actions conditionnelles en
utilisant l’instruction IF
– Ecrire des schémas itératifs en utilisant
la structure de boucle