Limbajul PL/SQL combină puterea de procesare a datelor, specifică limbajelor procedurale, cu puterea de manipulare a datelor, specifică instrucțiunilor. Structurile de control reprezintă cea mai importantă completare adusă de PL/SQL limbajului SQL prin introducerea instrucțiunilor de control condiționale, iterative, secvențiale și necondiționale. Toate structurile acceptă în clauzele lor instrucțiuni imbricate.
Sintaxa instrucțiunii este:
IF conditions THEN statements; END IF;
Unde:
Ex. 1. Pentru un angajat cu funcția 'FI_MGR' care nu primește comision să se modifice comisionul la 10% (.1). Testați cu id-ul 108.
Sintaxa instrucțiunii este:
IF conditions THEN statements_1; ELSE statements_2; END IF;
Unde:
Ex. 2. Să se acorde un comision de 10% din salariu angajaților care au o vechime de cel puțin 15 de ani în companie. (testati cu 108 si 149).
Sintaxa instrucțiunii este:
IF conditions_1 THEN statements_1; ELSIF conditions_2 THEN statements_2; ... [ELSE statements_k;] END IF;
Unde:
Se acceptă mai multe clause ELSIF dar o singură clasuză ELSE.
Clauza ELSE este opțională, aceasta poate să lipsească din construcția instrucțiunii.
Ex. 3. Să se acorde un comision de 10%, conducerii companiei care nu a primit comision, dar președintele să nu primească comision.
Sintaxa instrucțiunii este:
[<<label_name>>] CASE expression WHEN value_1 THEN statements_1; WHEN value_2 THEN statements_2; ... [ELSE statements_k;] END CASE [label_name];
Unde:
Ex. 4. Să se calculeze impozitul pe salariu al unui angajat, după algoritmul:
PL/SQL pune la dispoziția dezvoltatorilor SEARCHED CASE. Sintaxa instrucțiunii SEARCHED CASE este:
[<<label_name>>] CASE WHEN search_condition_1 THEN sequence_of_statements_1; WHEN search_condition_2 THEN sequence_of_statements_2; ... WHEN search_condition_N THEN sequence_of_statements_N; [ELSE sequence_of_statements_N+1;] END CASE [label_name];
Ex. 5. Folosirea instrucțiunii searched CASE:
Ex. 6. Folosirea instrucțiunii CASE pentru inițializarea unei variabile și în clauza where a unei cereri:
Ex. 7. Exemplu de folosire a instrucțiunii CASE în clauza SELECT.
Instrucțiunea LOOP este folosită pentru execuția ciclică a unei secvențe de instrucțiuni.
Sintaxa instrucțiunii este:
[<<label_name>>] LOOP statements; [EXIT [WHEN conditions];] [CONTINUE [WHEN conditions];] END LOOP [label_name];
Unde:
LOOP statements; IF conditions THEN statements_in_if; EXIT; -- exit loop immediately END IF; END LOOP;
Ex. 8. În exemplul următor se dorește să se facă o listă cu data angajării și veniturile angajaților care fac parte dintr-un departament specificat.
Instructiunea WHILE este folosită pentru realizarea unei structuri repetitive condiționate.
Sintaxa instrucțiunii este:
WHILE conditions
LOOP
statements;
END LOOP;
Unde:
Ex. 9. Să se modifice exercițiul precedent astfel încât să folosească instrucțiunea WHILE.
Instrucțiunea FOR este folosită pentru realizarea unei structuri repetitive.
Sintaxa instrucțiunii este:
FOR contor IN [REVERSE] value1 .. value2 LOOP statements END LOOP;
Unde:
Ex. 10. Să se modifice exercițiul precedent astfel încât să folosească instrucțiunea FOR.
Ex. 11.Exemplu de folosire a instrucțiunii GOTO.
Ex. 12. Exeplu de ieșise dintr-o buclă folosind GOTO.
Ex. 13. Să se scrie un bloc PL/SQL care face o listă cu numărul angajaților care au veniturile mai mici de 4000 (considerate venituri mici) și mai mari de 4000 (considerate venituri mari), pentru fiecare departament. Se va face o construcție folosind structuri de control și cicluri. Pentru departamentele care nu au niciun angajat se va afișa un mesaj.
Tipurile scalare nu au componente interne, în timp ce tipurile compuse au componente interne care se pot manipula.
RECORD este un tip compus:
Declararea tipului RECORD se face conform următoarei sintaxe:
TYPE nume_tip IS RECORD ( field_1 {datatype | variable%TYPE | TABLE.column%TYPE | table%ROWTYPE} [ [NOT NULL] [{:= | DEFAULT} expression_1] ], field_2 {datatype | variable%TYPE | TABLE.column%TYPE | table%ROWTYPE} [ [NOT NULL] [{:= | DEFAULT} expression_2] ], ... field_n {datatype | variable%TYPE | TABLE.column%TYPE | table%ROWTYPE} [ [NOT NULL] [{:= | DEFAULT} expression_n] ] );
Ex. 14. Un exemplu de utilizare a tipului RECORD.
Ex. 15. Ex. 15. Folosindu-se tipul compus RECORD:
Tipurile colecție sunt:
Tipurile colecție au atribute și metode. (În funcție de tip, atributele se comporta diferit).
Atribute și metode | Descriere |
---|---|
COUNT | Numărul de componente din colecţie |
FIRST | Indicele primului element din tablou |
LAST | Indicele ultimului element din colecție |
EXISTS | Întoarce TRUE dacă există în coleție componenta cu indexul specificat |
NEXT | Întoarce indicele următoarei componente |
PRIOR | Întoarce indicele componentei anterioare |
DELETE | Șterge una sau mai multe componente |
EXTEND | Adaugă elemente la sfârşitul colecției |
LIMIT | Întoarce numărul maxim de elemente al unei colecţii (pentru vectori), null pentru tablouri imbricate |
TRIM | Șterge elementele de la sfârşitul unei colecţii |
Vectorii (varray) sunt structuri asemănătoare vectorilor din limbajele C sau Java. Vectorii au o dimensiune maximă (constantă) stabilită la declarare. Se utilizează pentru modelarea relaţiilor one-to-many, atunci când numărul maxim de elemente din partea “many” este cunoscut şi ordinea elementelor este importantă. Fiecare element are un index. Indexarea începe de la 1.
Tipul de date vector este declarat utilizând sintaxa:
TYPE name IS {VARRAY | VARYING ARRAY} (max_length) OF element_type [NOT NULL];
Ex. 16. Exemplul folosire varray.
Tipul ASSOCIATIVE ARRAY se mai numește și INDEX BY TABLE (tabel indexat).
Un table indexat în PL/SQL are două componente:
Declararea tipului ASSOCIATIVE ARRAY se face cu următoarea sintaxă:
TYPE name IS TABLE OF {data_type | variable%TYPE | TABLE.column%TYPE [NOT NULL] | table%ROWTYPE} INDEX BY data_type_index;
Unde:
Ex. 17. Exemplu de folosire ASSOCIATIVE ARRAY.
Un tablou imbricat este o mulţime neordonată de elemente de acelaşi tip. Valorile de acest tip:
Comanda de declarare a tipului de date tablou imbricat are sintaxa:
TYPE name IS TABLE OF {data_type | variable%TYPE | TABLE.column%TYPE [NOT NULL] | table%ROWTYPE} [NOT NULL];
Ex. 18. Exemplu de folosire al unui tabel imbricat.
Tipurile colecție pot fi definite direct în baza de date.
Collection Type | Number of Elements | Subscript Type | Dense or Sparse | Where Created | Can Be Object Type Attribute |
---|---|---|---|---|---|
Associative array (or index-by table) | Unbounded | String or PLS_INTEGER/BINARY_INTEGER | Either | Only in PL/SQL block | No |
Nested table | Unbounded | Integer | Starts dense, can become sparse | Either in PL/SQL block or at schema level | Yes |
Variable-size array (varray) | Bounded | Integer | Always dense | Either in PL/SQL block or at schema level | Yes |
Ex. 19. Definirea tipurilor direct în baza de date.
NESTED TABLE proiect STORE AS proiect_store;
Pentru a insera mai multe valori într-o variabilă de tip colecție se poate folosi BULK COLLECT INTO.
Ex. 20. Folosirea BULK COLLECT INTO cu varray.
Ex. 21. Folosirea BULK COLLECT INTO cu index-by table.
Ex. 22. Folosirea BULK COLLECT INTO cu nested table.