Sunteți pe pagina 1din 17

Proiectarea bazelor de date - Laborator 2

Structuri de Control

Obiective

Identificarea tipurilor si folosirea structurilor de control

Constructia unei declaratii IF

Constructia si identificarea diferitelor declaratii de bucle

Folosirea tabelelor logice

Controlarea blocurilor folosind bucle si etichete

Scopul lectiei:
În aceasta lectie, veti învata despre structurile de control în cadrul blocurilor
PL/SQL prin folosirea instructiunilor IF si a buclelor repetitive.

Controlul executiei PL/SQL


Puteti schimba cursul logic al executiei folosind
instructiuni IF si structuri de buclare.

Declararea lui IF:


• IF-THEN-END IF
• IF-THEN-ELSE END IF
• IF-THEN-ELSIF-END IF

Puteti schimba cursul logic al instructiunilor înauntrul unui block PL/SQL cu


ajutorul structurilor de control. Aceasta lectie explica doua tipuri de structuri de
control: constructiile conditionale (instructiunea IF) si structurile de control LOOP
(dezbatute mai tîrziu în aceasta lectie).

Sunt trei forme ale instructiunii IF:


• IF-THEN-END IF
• IF-THEN-ELSE END IF
• IF-THEN-ELSIF-END IF

1
Instructiunea IF
Sintaxa
IF conditie THEN
instructiuni;
[ELSIF conditie THEN
instructiuni;]
[ELSE
instructiuni;]
END IF

O instructiune IF simpla:
Setati ID managerului la 22 daca numele angajatului
este Osborne.
IF v_ename = ‘OSBORNE’ THEN
v_mgr := 22 ;
END IF;
Instructiunea IF
Structura instructiunii IF în PL/SQL este similara cu structura instructiunii IF
în alte limbaje procedurale. Instructiunea permite realizarea de actiuni selective bazate
pe o conditie.

în sintaxa:
conditie este o variabila logica sau expresie (TRUE,
FALSE sau NULL); este asociata cu o lista de
instructiuni care sunt executate doar în cazul în
care conditia este TRUE.

THEN este o clauza asociata cu expresia logica pe care o


precede cu o secventa de instructiuni.

instructiuni pot fi una sau mai multe instructiuni PL/SQL; pot


sa includa alte instructiuni IF, ELSE si ELSIF.

ELSIF este un cuvînt cheie ce introduce o expresie


logica; daca prima conditie este FALSE sau
NULL atunci cuvîntul cheie ELSIF introduce un
noua conditie.

ELSE este un cuvant cheie care realizeaza execu]ia


instructiunilor care urmeaza dupa el daca controlul
ajunge pe aceasta ramura.

2
Instructiunea simpla IF
Schimbati denumirea meseriei cu Salesman,
numarul departament ului cu 35 si comisionul cu
20% a salariului curent daca ultimul nume este
Miller.
Exemplu:

. . .
IF v_ename := ‘MILLER’ THEN
v_job : = ‘SALESMAN’;
v_deptno := 35;
v_new_comm := sal∗0.20
END IF ;
. . .

Instructiunea IF simpla
În exemplul din figura, PL/SQL relizeaza actiunile: seteaza v_job, v_depno si
v_new_comm doar daca conditia din IF este TRUE. Daca conditia este FALSE or
NULL, PL/SQL ignora instructiunile de setare. În acest caz se continua cu executia
instructiunilor de dupa END IF.

OBS:
• Se pot realiza actiuni selective bazate pe o conditie întîlnita.
• Când scrieti cod, amintiti-va sintaxa cuvintelor cheie:
- ELSIF este un cuvânt;
- END IF sunt doua cuvinte;
• Daca expresia logica este TRUE, se executa instructiunile asociate; daca
conditia este FALSE or NULL, secventa de instructiuni asociata este
sarita. Este permis orice numar de clauze ELSIF.
• Poate sa existe cel mult o clauza ELSE.
• Aliniati instructiunile pentru claritate.

3
Instructiunea IF-THEN-ELSE
Cursul executiei

Conditie IF

Actiuni THEN Actiuni ELSE


(inclusiv ale If-uri) (inclusiv ale If-uri)

Cand conditia este FALSE sau NULL, puteti folosi o clauza ELSE pentru a executa
alte actiuni. La fel ca la instructiunea simpla IF, controlul executiei programului este
redat instructiunilor de dupa END IF.
Exemplu:

IF conditie THEN
Instructiuni1;
ELSE
Instructiuni2;
END IF

Imbricarea instructiunilor IF

Fiecare set de actiuni a unui IF poate include alta instructiune IF înainte de a realiza
orice alta actiune. Clauzele THEN si ELSE pot include instructiuni IF. Fiecare
comanda IF imbricata trebuie terminata cu END IF.

IF conditie THEN
Instructiuni1;
ELSE
IF conditie2 THEN
Instructiuni2;
END IF
END IF

4
Instructiunea IF-THEN-ELSE

Setati un flag pentru comenzi când sunt mai putin


de 5 zile între data comenzii si cea a expedierii.
Exemplu:
. . .
IF v_shipdate – v_orderdate < 5 THEN
v_ship_flag := ‘Acceptat’;
ELSE
v_ship_flag := ‘Neacceptat’;
END IF

Exemplu:
Înlocuiti ocupatia cu Manager daca numele angajatului este King. Daca
numele angajatului este altul decât King atunci ocupatia sa fie Clerk.
IF v_ename = ‘KING’ THEN
v_job := ‘MANAGER’;
ELSE
v_job := ‘CLERK’;
END IF

Instructiunea IF-THEN-ELSIF
Cursul executiei
Conditie IF

Conditie
ELSIF
Actiuni THEN

Actiuni
Actiuni THEN
ELSE

5
Cursul executiei instructiunii IF-THEN-ELSIF
Într-un formular al unei aplicatii Oracle, introduceti numarul departamentului
al noilor angajati pentru a determina bonusul lor.

. . .
IF :v_deptno = 10 THEN
v_comm := 5000;
ELSIF :v_deptno = 20 THEN
v_comm := 7500;
ELSE
v_comm := 2000;
END IF;
. . .

În exemplu variabila v_comm este folosita pentru a introduce într-o variabila


bonusul angajatului iar :v_deptno reprezinta valoarea introdusa în câmpul din
formular.

Instructiunea IF-THEN-ELSIF

Pentru o anumita valoare data calculati o alta


valoare.
Exemplu:
. . .
IF v_start >100 THEN
v_start := 2 ∗ v_start;
ELSIF v_start >= 50 THEN
v_start := . 5 ∗ v_start;
ELSE
v_start := .1 ∗ v_start;
END IF
. . .

Instructiunea IF -THEN-ELSIF
Când este posibil, folositi clauza ELSEIF înaintea instuctiunilor IF imbricate. Codul
este mai usor de citit si de de înteles, iar logica programului este mai usor de înteles.
Daca actiunea în clasa ELSE depinde de alta instructiune IF, este mult mai
convenabil sa folosim clauza ELSIF.Aceasta face codul clar prin îndepartarea nevoii
de a folosi END IF la sfârsitul fiecarui alt set de conditii si actiuni.

6
Exemplu:

IF conditie1 THEN
instructiuni1;
ELSIF conditie2 THEN
instructiuni2;
ELSIF conditie3 THEN
instructiuni3;
END IF;

Exemplul IF-THEN-ELSIF de mai sus este definit dupa cum urmeaza:


Pentru o valoare introdusa, returneaza o valoare calculata. Daca valoarea
introdusa este peste 100, atunci valoarea calculata es te de doua ori valoarea introdusa.
Daca este între 50 si 100 atunci rezultatul este 50% din valoarea de start. Daca
valoarea introdusa este mai mica decât 50 atunci valoarea calculata este 10% din
valoarea de start.

Nota: Orice expresie aritmetica continînd o valoare nulla este evaluata la null.

Construirea conditiilor logice



Puteti manipula valori nule cu operatorul IS
NULL.

Orice expresie ce contine o valoare nula este
evaluata ca NULL.

Concatenarea expresiilor cu o valori nule se face
prin tratarea valorii nule ca un string empty
(gol)

Construirea conditiilor logice


Puteti construi o simpla conditie logica prin combinatii de numere, caractere
sau date cu un operator de comparare. În general manipularea valorilor nulle se face
cu operatorul IS NULL.

NULL în expresii si comparari


• Operatorul IS NULL este evaluat ca TRUE doar daca variabila este NULL .
• Orice expresie continînd o valoare nulla este evaluata ca NULL, cu exceptia
unei expresii concatenate, caz în care se trateaza valoarea nula ca un string
gol.

7
Exemple: v_sal > 1000 sau v_sal ∗ 1000

v_sal este evaluat ca fiind NULL daca v_sal este NULL în ambele cazuri de mai sus.
În urmatorul exemplu urmator v_string nu este evaluat ca NULL daca acesta este
NULL.
‘PL’ | | v_string | | ‘SQL’

Tabelele Logice
Construiti conditii logice simple cu ajutorul unui
operator de comparare.
AND TRUE FALS E NULL OR TRUE FALSE NULL NOT

TRUE TRUE FALSE NULL TRUE TRUE TRUE TRUE TRUE FALSE

FALSE FALSE FALSE FALSE FALSE TRUE FALSE NULL FALSE TRUE

NULL NULL FALSE NULL NULL TRUE NULL NULL NULL NULL

Conditii logice cu operatori logici


Puteti construi o conditie booleana complexa prin combinarea unei simple
conditii booleene cu operatorii logici: AND, OR sau NOT.
Nota: Negatia lui NULL (NOT NULL) este o valoare nula deoarece valorile nule sunt
nedeterminante.

Conditii Booleene

Care este valoarea lui v _flag în fiecare caz?


v_flag := v_reorder_flag AND v_available_flag

V_REORDER_FLAG V_AVAILABLE_FLAG V_FLAG


TRUE TRUE TRUE
TRUE FALSE FALSE
NULL TRUE NULL
NULL FALSE FALSE

8
Controlul iterativ: instructiunea LOOP

• Bucla repeta o instructiune sau o secventa de


instructiuni de mai multe ori.
• Sunt trei forme de bucle :
- bucla de baza
- bucla FOR
- bucla WHILE

Controlul iterativ : instructiunea LOOP


PL/SQL prevede o serie de facilitati pentru bucle structurate pentru a repeta o
serie de instructiuni de mai multe ori.
Bucla este un al doilea tip de structura de control:
• Bucle de baza care realizeaza actiuni repetitive fara alte conditii suplimentare.
• Bucla FOR care realizeaza controlul iterativ bazat pe un contor.
• Bucla WHILE care realizeaza controlul iterativ bazat pe o conditie.
• Instructiunea EXIT pentru atermina o bucla.

Nota: Un alt tip de bucla FOR LOOP, cursorul FOR LOOP este discutat într-o
alta lectie.

Bucla LOOP de baza

Sintaxa

LOOP -- delimitator
instructiuni1 -- instructiuni
. . .
EXIT [ WHEN conditie ]; -- instructiunea EXIT
END LOOP -- delimitator

unde: conditie este o variabila Booleana sau o expresie (TRUE, FALSE OR


NULL);

9
Bucla de baza LOOP
Cea mai simpla forma a instructiunii LOOP este o bucla simpla (infinita), ce
include o secventa de instructiuni între cuvintele cheie LOOP si END LOOP. De
fiecare data când cursul executiei atinge instructiune END LOOP, controlul este redat
instructiunii corespondente LOOP de mai înaintea ei. O astfel de bucla permite
executia instructiunilor macar o data chiar daca conditia este falsa la intrarea în bucla.
• Repetati instructiunile de la un capat la altul cu ajutorul unei bucle.
• Fara instructiunea EXIT bucla va fi infinita.

Instructiunea EXIT
Puteti termina o bucla folosind instructunea EXIT. Controlul este redat
urmatoarei instructiuni de dupa instructiunea END LOOP. Puteti folosi EXIT
împreunacu o instructiune IF sau ca o instructune de sine statatoare înauntrul buclei.
Instructiunea EXIT trebuie plasata în interiorul buclei. Aditional puteti adauga clauza
WHEN împreuna cu o conditie pentru a conditiona terminarea buclei. Când
instructiunea EXIT este atinsa se evalueaza clauza WHEN. Daca conditia este TRUE
bucla se încheie si controlul este preluat de prima instructiune de dupa END LOOP. O
bucla poate contine mai multe instructiuni EXIT.

Bucla LOOP de baza

Exemplu

DECLARE
v_ordid item.ordid%TYPE := 101;
v_counter NUMBER(2) := 1;
BEGIN
LOOP
INSERT INTO item(ordid, itemid)
VALUES (v_ordid, v_counter);
v_counter := v_counter+1;
EXIT WHEN v_counter > 10;
END LOOP;

Bucla de baza LOOP


Exemplul realizeaza urmatoarele : insereaza în primele 10 linii item-uri pentru
numarul de ordine 101.

Nota:
O bucla de baza permite executia instructiunilor cel putin o da ta chiar daca
conditia este adevarata la intrarea în bucla.

10
Bucla FOR

Sintaxa
FOR contor IN [ REVERSE ] limita_inferioara .. limita_superioara LOOP

instructiuni

END LOOP

• Folositi o bucla LOOP pentru a scurta testul pentru numarul de iteratii.


• Nu declara si indexul; el este declarat implicit.

Buclele FOR au aceeasi structura generala ca buclele de baza, ele au un


control al executiei la începutul cuvîntului cheie pentru a determina numarul de
iteratii pe care le face PL/SQL.

În sintaxa,
contor este un întreg declarat implicit a carui valoare este
incrementata sau decrementata ( decrementata daca
este folosit cuvîntul cheie REVERSE ) automat, la
fiecare iteratie a buclei pîna când este atinsa limita
superioara sau inferioara.
REVERSE produce decrementarea indexului la fiecare iteratie
de la limita superioara spre cea inferioara. De
notat ca valoarea inferioara este totusi scrisa
prima.
limita_inferioara specifica marginea inferioara pentru zona acoperita
de valoarea indexului.
limita_superioara specifica marginea superioara pentru zona
acoperita de valoarea indexului.

De exemplu, instructiunea urmatoare este executata o singura data.

FOR i IN 3 . . 3 LOOP instructiune; END LOOP;

11
Bucla FOR

Sfaturi
• Faceti referiri la contor doar în cadrul buclei; el
este nedefinit în afara ei.
• Folositi o expresie pentru a va referi la o valoare
existenta a contorului.
• Nu va referiti la contor ca la tinta unei asignari.

Bucla FOR
Nota: L imita inferioara si cea superioara nu trebuie sa fie neaparat numerice.
Ele pot fi expesii care se convertesc la valori numerice.

Exemplu

DECLARE
v_lower NUMBER := 1;
v_uper NUMBER := 100;
BEGIN
FOR i IN v_lower .. v_upper LOOP
. . .
END LOOP;
END;

Bucla FOR

Inserati primele 10 noi linii la numarul de ordine


101.

Exemplu
D ECLARE
v_ordid item.ordid%TYPE := 101;
BEGIN
FOR i IN 1 .. 10 LOOP
INSERT INTO item( ordid, itemid)
values ( v_ordid, i );
END LOOP;
END;

12
Bucla WHILE

Sintaxa
WHILE conditie LOOP
Conditia este evaluata la
începutul fiecarei
instructiuni
iteratii.
END LOOP

Folositi o bucla WHILE pentru a repeta actiuni atîta timp cît o conditie este TRUE.

Instructiunea WHILE
Puteti folosi bucla WHILE pentru a repeta o secventa de instructiuni atîta timp
cît conditia este adevarata (TRUE). Conditia este evaluata la începutul fiecarei
iteratii. Bucla se termina cînd conditia este falsa la începutul buclei si atunci nici o
iteratie nu mai este facuta.

13
Bucla WHILE
Exemplu
ACCEPT p_price PROMPT ‘Introduceti pretul pe item: ’
ACCEPT p_itemtot PROMPT ‘Introduceti maximul total pentru
cumpararea itemului: ’
DECLARE
. . .
v_qty NUMBER( 8 ) := 1 ;
v_running_total NUMBER( 7, 2 ) := 0;
BEGIN
. . .
WHILE v_running_total < &p_itemtot LOOP
. . .
v_qty := v_qty + 1;
v_running_tottal := v_qty ∗ &p_price;
END LOOP
. . .

Buc la WHILE
În exemplul de mai sus cantitatea este incrementata cu fiecare iteratie a buclei
pîna cînd cantitatea nu mai este mai mica decît pretul maxim permis pentru un
obiect.

Bucle imbricate si etichete

• Bucle imbricate pe nivele multiple.


• Folositi etichete pentru a face diferenta între
blocuri si bucle.
• Iesiti din bucla exterioara cu instructiunea
EXIT referita la eticheta.

14
Bucle si etichete imbricate
Puteti imbrica bucle la nivele multiple. Puteti imbrica bucle FOR în interiorul
buclelor WHILE si buclele WHILE în interiorul buclelor FOR. Normal,
terminarea unei bucle imbricate nu termina bucla inclusa daca nu apare o exceptie.
În orice caz puteti eticheta buclele si iesiti din bucla exterioara cu instructiunea
EXIT.
Numele etichetelor respecta aceleasi reguli ca ceilalti indentificatori. O
eticheta este plasata înaintea unei instrucsiuni pe aceeasi linie, ori pe o linie
separata. etichetati buclele plasînd eticheta înaintea cuvîntului cheie LOOP în
delimitatorii de eticheta ( << eticheta >>).
Daca bucla este etichetata, numele etichetei poate fi optional inclus dupa
instructiunea END LOOP.

Bucla imbricate si etichete


BEGIN
<< Outer_loop >>
LOOP
v_counter := v_counter + 1;
EXIT WHEN v_counter > 10;
<< Inner_loop >>
LOOP
. . .
EXIT Outer_loop WHEN total_done = ‘YES’;
-- Parasesc ambele bucle
EXIT WHEN inner_done = ‘YES’
-- Parasesc doar bucla Inner_loop
. . .
END LOOP Inner_loop
. . .
END LOOP Outer_loop;
END;

15
Rezumat

Puteti schimba cursul logic al instructiunilor


folosind structuri de control.
• Conditionale ( instructiunea IF)
• Bucle
- Bucla de baza
- Bucla FOR
- Bucla WHILE
- Instructiunea EXIT

Aplicatii practice
În aceste exercitii practice veti crea blocuri PL/SQL care contin bucle si
structuri de control conditionate.

1. Creati tabela MESSAGES (text varchar2(50)). Scrieti un bloc PL/SQL pentru


a insera numere în tabela MESSAGES.
a. Inserati numerele de la 1 la 10 excluzînd 6 si 8.
b. Realizati COMMIT înainte de finele blocului.
c. Faceti un SELECT pe tabela MESSAGES pentru a verifica daca blocul a
functionat bine.

2. Creati tabela EMP1 care are aceeasi structura si continut ca tabela EMP.
Creati un bloc PL/SQL care calculeaza valoarea comisionului pentru un
angajat dat folosind salariul acestuia.
a. Inserati un nou angajat în tabela EMP1. Nota: Angajatul va avea salariul
NULL.
b. Acceptati numarul angajatului ca intrare cu o variabila de substitutie
SQL∗Plus.
c. Daca salariul angajatului este mai mic ca 1000$ fixati comisionul
angajatului la 10% din salar.
d. Daca salariul angajatului este între 1000$ si 1500$ fixati comisionul
angajatului la 15% din salar.
e. Daca salariul angajatului este mai mare ca 1500$ fixati comisionul
angajatului la 20% din salar.
f. Daca salariul angajatului este NULL fixati comisionul angajatului la 0.
g. COMMIT
h. Testati blocul PL/SQL pentru fiecare caz folosind urmatoarele cazuri de
test:

16
Numarul angajatului Salar Comisionul rezultat
7369 800 80
7934 1300 195
7499 1600 320
8000 NULL NULL

3. Modificati ex1.sql pentru a insera textul “Numarul este par” sau “Numarul este
impar” în functie de paritatea sau imparitatea numarului, în tabela
MESSAGES. Interogati tabela pentru avedea daca blocul construit a
functionat corect.

4. Adauga ti o coloana noua numita STARS la tabela EMP1 pentru a stoca ( ∗ ).

5. Creati un bloc PL/SQL care recompenseaza un angajat concatenînd un asterisc


în coloana STARS pentru fiecare 100$ din salariul angajatului. Rontujiti
salariul angajatului la cel mai apropiat numar întreg. Salvati blocul PL/SQL
într-un fisier numit ex5.sql.
a. Acceptati ID -ul angajatului ca intrare într-o variabila de substitutie
SQL∗Plus.
b. Initializati o variabila pentru a contine un sir de asterixuri.
c. Concatenati un asterisc la sir pentru fiecare 100$ din salar. De exeplu
daca un angajat are un salar de 800$, sirul de asteriscuri va contine 8
asteriscuri.
d. Revizuiti coloana STARS pentru angajat dupa metoda de la punctul
anterior.
e. Realizati COMMIT.
f. Testati blocul pentru un angajat care are salariu.

Introduceti numarul angajatului: 7364


P L/SQL procedure successfully completed.

Introduceti numarul angajatului: 8000


P L/SQL procedure successfully completed.

EMPNO SAL STARS


8000
7934 1300 *************

17

S-ar putea să vă placă și