3.    Instructiuni de control PL/SQL

 

3.1.          Decizia

 

Sintaxa este:

IF conditie1 THEN

   instructiuni1;

[ELSIF conditie2 THEN

   instructiuni 2;]

[ELSE

   instructiuni 3;]

END IF;

 

Observatie: ELSEIF se scrie legat pe cand END IF in doua cuvinte.

In conditii se pot folosi toti operatorii de comparatie, operatorii specifici SQL (BETWEEN, IN, LIKE, IS [NOT] NULL), conectorii logici AND, OR, NOT,  paranteze si orice expresii aritmetice sau de alta natura valide.

 

Exemplu:

declare

  v_loc varchar2(10) := 'NEW YORK';

  v_nr   number(2);

begin

  select deptno

  into v_nr

  from dept

  where loc=v_loc;

  dbms_output.put_line('Numarul departamentului este:

                           '||v_nr);

  if (v_nr=20) then

      dbms_output.put_line('Este 20');

  elsif v_nr < 20 then

      dbms_output.put_line('Mai mic decat 20');

  else

      dbms_output.put_line('Mai mare decat 20');

  end if;

exception

  when no_data_found then

    dbms_output.put_line('Nu exista acest departament');

  when too_many_rows then

    dbms_output.put_line('Sunt mai multe');

  when others then

    dbms_output.put_line('Eroare nespecificata');

end;

 

 

 

 

3.2.         Cicluri

 

A.   Ciclul LOOP

 

Sintaxa este:

LOOP

Instructiuni;

IF . . .

EXIT [WHEN conditie]; -- iesire din ciclu

END IF;

Instructiuni;

END LOOP;

 

EXIT (conditionat sau nu) determina iesirea din ciclu.

 

Exemplu: Blocul urmator contine un ciclu LOOP cu o variabila contor care parcurge valorile 5, 10, 15, . . . , 70 si al carui corp contine un subbloc. Subblocul testeaza pentru numerele respective daca exista un departament cu acel cod si daca da afiseaza datele despre el in zona executabila. Daca nu exista un astfel de departament se afiseaza un mesaj corespunzator in zona de exceptii a subblocului.

 

declare

  v_contor number(2) :=5;

  v_deptno number;

  v_dname varchar2(10);

  v_loc varchar2(10);

begin

loop

  begin

  select deptno, dname, loc

  into v_deptno, v_dname, v_loc

  from dept

  where deptno=v_contor;

dbms_output.put_line('Dep.cu cod '|| v_contor||'     se numeste '||v_dname||

' si este in '||v_loc);

  exception

  when no_data_found then

dbms_output.put_line(

'Nu exista departamentul cu cod '||

v_contor);

  end;

v_contor := v_contor + 5;

exit when v_contor > 70;

end loop;

exception

when others then

  dbms_output.put_line('Exceptie');

end;

 

 

B.   Ciclul FOR

 

Sintaxa este:

FOR contor IN [REVERSE] val_initiala..v_finala LOOP

Instructiuni;

END LOOP;

 

Se poate folosi EXIT pentru iesirea fortata din ciclu.

 

Exemplu: Asemanator cu exemplul anterior dar se testeaza toate numerele intre 10 si 20 inclusiv.

 

declare

  v_contor number(2);

  v_deptno number;

  v_dname varchar2(10);

  v_loc varchar2(10);

begin

for v_contor in 10..20  loop

  begin

  select deptno, dname, loc

  into v_deptno, v_dname, v_loc

  from dept

  where deptno=v_contor;

  dbms_output.put_line('Dep.cu cod '|| v_contor||

  ' se numeste '||v_dname||' si este in '||v_loc);

  exception

  when no_data_found then

    dbms_output.put_line(

'Nu exista departamentul cu cod '||

v_contor);

  end;

end loop;

exception

when others then

  dbms_output.put_line('Exceptie');

end;

 

 

C.   Ciclul WHILE

 

Sintaxa este:

WHILE conditie LOOP

Instructiuni;

END LOOP;

 

Se poate folosi EXIT pentru iesirea fortata din ciclu.

Exemplu: Rescriere cu WHILE pentru exemplul de la LOOP

 

declare

  v_contor number(2) :=5;

  v_deptno number;

  v_dname varchar2(10);

  v_loc varchar2(10);

begin

while v_contor <=70 loop

  begin

  select deptno, dname, loc

  into v_deptno, v_dname, v_loc

  from dept

  where deptno=v_contor;

  dbms_output.put_line('Dep.cu cod '|| v_contor||' se numeste '||v_dname||' si este in '||v_loc);

  exception

  when no_data_found then

    dbms_output.put_line('Nu exista departamentul cu cod '|| v_contor);

  end;

v_contor := v_contor + 5;

end loop;

exception

when others then

  dbms_output.put_line('Exceptie');

end;

 

 

3.3.         Etichetarea instructiunilor

 

Forma unei etichete este:

<<eticheta>>

Aceasta se plaseaza inaintea instructiunii. Daca instructiunea este un ciclu, in cazul in care avem cicluri imbricate se poate comanda iesirea din ciclu pe mai multe nivele specificand la EXIT eticheta ciclului parasit. In acest caz la END LOOP se poate adauga optional eticheta ciclului.

Exemplu:

<<ciclu_mare>>

LOOP

- - -

<<ciclu_mic>>

     LOOP

- - -

EXIT ciclu_mic WHEN conditie1;

- - -

EXIT ciclu_mare WHEN conditie1;

END LOOP ciclu_mic

END LOOP ciclu_mare;

 

3.4.         Alegerea (CASE)

 

Sintaxa este:

CASE expresie

WHEN 'val1' THEN

  Instructiuni1;

WHEN 'val2' THEN

  Instructiuni2;

- - - - - - - -

[ELSE

  Instructiuni_else]

END CASE;

 

In cazul absentei lui ELSE se adauga implicit ridicarea unei exceptii predefinite:

ELSE RAISE CASE_NOT_FOUND;

 

Nota: instructiunea CASE apare incepand cu Oracle9