Differences

This shows you the differences between two versions of the page.

Link to this comparison view

bd2:laboratoare:02 [2020/10/06 10:26]
apetrescu0506
— (current)
Line 1: Line 1:
-====== Laboratorul 02 - PL/SQL Structuri de control și tipuri compuse și colecții ====== 
- 
-===== Obiective ===== 
- 
-  * Instrucțiuni ​ 
-  * Tipuri compuse și colecții 
- 
-===== Instrucțiuni ===== 
- 
-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. 
- 
-==== Instrucțiuni condiționale​ ==== 
- 
-=== Instrucțiunea IF ... THEN​ === 
- 
-Sintaxa instrucțiunii este:​ 
- 
-<code sql> 
-IF conditions​ THEN 
-    statements;​​ 
-END IF;​ 
-</​code>​ 
- 
-Unde: 
-  * conditions – reprezintă condițiile cerute pentru execuția instrucțiunilor 
-  * statements – reprezintă secvența de instrucțiuni condiționale 
- 
-<​note>​ 
-Instrucțiunile care urmează după **THEN** se execută numai dacă toate condițiile din **conditions** sunt îndeplinite.​ 
-</​note>​ 
- 
-<color red>Ex. 1.</​color>​ 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. 
- 
-{{:​bd2:​laboratoare:​l02ex01.png?​730|}} 
- 
-=== Instrucțiunea IF ... THEN ... ELSE​ === 
- 
-Sintaxa instrucțiunii este:​ 
- 
-<code sql> 
-IF conditions​ THEN  
-    statements_1;​​ 
-ELSE  
-    statements_2;​​ 
-END IF;​ 
-</​code>​ 
- 
-Unde: 
-  * conditions – reprezintă condițiile cerute pentru execuția statements_1 
-  * statements_1 – reprezintă secvența de instrucțiuni atunci când conditions este TRUE 
-  * statements_2 – reprezintă secvența de instrucțiuni atunci când conditions este FALSE 
- 
-<color red>Ex. 2.</​color>​ 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)​. 
- 
-{{:​bd2:​laboratoare:​l02ex02.png?​730|}} 
- 
-=== Instrucțiunea IF ... THEN ... ELSIF ... ELSE​ === 
- 
-Sintaxa instrucțiunii este:​ 
- 
-<code sql> 
-IF conditions_1 THEN  
-  statements_1;​ 
-ELSIF conditions_2​ THEN  
-  statements_2;​ 
-...​ 
-[ELSE statements_k;​] 
-END IF;​ 
-</​code>​ 
- 
-Unde: 
-  * conditions_1 – reprezintă setul de condiții cerute pentru execuția statements_1 
-  * statements_1 – reprezintă secvența de instrucțiuni executate atunci când conditions_1 = TRUE 
-  * conditions_2 – reprezintă setul de condiții cerute pentru execuția statements_2 
-  * statements_2 – reprezintă secvența de instrucțiuni executate atunci când conditions_2 = TRU​E 
-  * statements_k – reprezintă secvența de instrucțiuni executate dacă niciuna dintre conditions_1..k-1 nu sunt verificate 
- 
-<​note>​ 
-Verificarea seturilor de condiții se face secvențial,​ în ordinea specificată și fiecare set poate conține condiții multiple. 
- 
-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. 
-</​note>​ 
- 
- 
-<color red>Ex. 3. </​color>​ Să se acorde un comision de 10%, conducerii companiei care nu a primit comision, dar președintele să nu primească comision.​ 
- 
-{{:​bd2:​laboratoare:​l02ex03.png?​600|}} 
- 
-=== Instrucțiunea CASE​ === 
- 
-Sintaxa instrucțiunii este:​ 
- 
-<code sql> 
-[<<​label_name>>​] 
-CASE expression 
-WHEN value_1 ​  ​THEN ​  ​statements_1;​​ 
-WHEN value_2 ​  ​THEN ​  ​statements_2;​ 
-... 
-[ELSE statements_k;​] 
-END CASE [label_name];​ 
-</​code>​ 
- 
-Unde: 
-  * expression – reprezintă expresia care se va evalua ​ 
-  * statements_1 – reprezintă secvența de instrucțiuni executate în cazul în care expression = value_1 
-  * statements_2 – reprezintă secvența de instrucțiuni executate în cazul în care expression = value_2 
-  * statements_k – reprezintă secvența de instrucțiuni executate dacă expression <> value_1, value_2, ... 
- 
-<color red>Ex. 4.</​color>​ Să se calculeze impozitul pe salariu al unui angajat, după algoritmul:​​ 
-  * Din tabela JOBS se află salariul minim, respectiv maxim, pentru funcția pe care o deține; 
-  * Dacă angajatul are salariul minim, atunci impozitul este de 10% din salariu. 
-  * Dacă angajatul are salariul maxim, atunci impozitul este de 30% din salariu. 
-  * Altfel impozitul este de 20% din salariu. 
-  * Se afișează numele și impozitul angajatului. 
- 
-{{:​bd2:​laboratoare:​l02ex04.png?​730|}} 
- 
-=== Instrucțiunea SEARCHED CASE​ === 
- 
-PL/SQL pune la dispoziția dezvoltatorilor **SEARCHED CASE**. Sintaxa instrucțiunii **SEARCHED CASE** este: 
- 
-<code sql> 
-[<<​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];​​ 
-</​code>​ 
- 
-<color red>Ex. 5.</​color>​ Folosirea instrucțiunii searched CASE:​ 
- 
-{{:​bd2:​laboratoare:​l02ex05.png?​730|}} 
- 
-<color red>Ex. 6.</​color>​ Folosirea instrucțiunii CASE pentru inițializarea unei variabile și în clauza where a unei cereri:​ 
- 
-{{:​bd2:​laboratoare:​l02ex06.png?​730|}} 
- 
-<color red>Ex. 7.</​color>​ Exemplu de folosire a instrucțiunii CASE în clauza SELECT.​ 
- 
-{{:​bd2:​laboratoare:​l02ex07.png?​730|}} 
- 
-<note important>​ 
-Observații:​ 
-  * Clauza **ELSE** poate să lipsească din instrucțiunea **CASE**; 
-  * Dacă lipsește clauza **ELSE** și niciuna dintre clauzele **WHEN** nu se execută ​ atunci apare eroarea **CASE_NOT_FOUND**. 
-</​note>​ 
- 
-==== Instrucțiuni de repetiție ==== 
- 
-=== Instrucțiunea LOOP​ === 
- 
-Instrucțiunea LOOP este  folosită pentru execuția ciclică a unei secvențe de instrucțiuni. 
- 
-Sintaxa instrucțiunii este:​ 
- 
-<code sql> 
-[<<​label_name>>​] 
-LOOP 
-    statements; 
-    [EXIT [WHEN conditions];​] 
-    [CONTINUE [WHEN conditions];​] 
-END LOOP [label_name];​ 
-</​code>​ 
- 
-Unde: 
-  * statements – reprezintă secvența de instrcțiuni execuate în cadrul buclei 
-  * label_name – este eticheta următoarei instrucțiuni la care se forțează saltul, care poate să lipsească 
-  * conditions – reprezintă setul de condiții la care se forțează ieșirea din buclă și nu este obligatoriu,​ iar dacă lipsește atunci bucla are o singură iterație 
- 
-<​note>​ 
-Observații 
-  * După fiecare procesare a unui ciclu, controlul revine la începutul ciclului și se reia execuția instrucțiunilor 
-  * Instrucțiunea **EXIT** este folosită pentru ieșirea din ciclu, cu sau fără verificare de condiție 
-  * **EXIT** poate fi executată fie ca o acțiune dintr-un **IF** în cadrul blocului **LOOP**, fie ca o instrucțiune individuală în cadrul unui ciclu 
-  * O clauză **WHEN** poate fi înlocuită de instrucțiunea **IF**, cum se vede în construcția următoare: 
- 
-<code sql> 
-LOOP 
-    statements; 
-    IF conditions THEN 
-        statements_in_if;​ 
-        EXIT;  -- exit loop immediately 
-    END IF; 
-END LOOP; 
-</​code>​​ 
-</​note>​ 
- 
-<color red>Ex. 8.</​color> ​ Î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. 
- 
-{{:​bd2:​laboratoare:​l02ex08.png?​730|}} 
- 
- 
-=== Instrucțiunea WHILE === 
- 
-Instructiunea WHILE este folosită pentru realizarea unei structuri repetitive condiționate. ​ 
- 
-Sintaxa instrucțiunii este: 
-<code sql> 
-WHILE conditions 
-LOOP 
-    statements; 
-END LOOP; 
-</​code>​ 
- 
-Unde: 
-  * conditions – reprezintă setul de condiții pentru execuția buclei 
-  * statements – reptezintă secvența de instrucțiuni executată în cadrul buclei 
- 
-<color red>Ex. 9.</​color>​ Să se modifice exercițiul precedent astfel încât să folosească instrucțiunea WHILE. 
- 
-{{:​bd2:​laboratoare:​l02ex09.png?​730|}} 
- 
-=== Instrucțiunea FOR​ === 
- 
-Instrucțiunea FOR este folosită pentru realizarea unei structuri repetitive. 
- 
-Sintaxa instrucțiunii este: 
- 
-<code sql> 
-FOR contor IN [REVERSE] value1 .. value2 
-LOOP 
-    statements 
-END LOOP; 
-</​code>​ 
- 
-Unde: 
-  * contor – este contorul folosit pentru incrementarea (decrementarea) iterațiilor 
-  * value1 .. value2 – reprezintă valorile minime și maxime ale contorului (value1 <= value2) 
-  * statements – reprezintă secvența de instrucțiuni executate în cadrul buclei​ 
- 
-<​note>​ 
-Observații:​​ 
-  * Întotdeauna trebuie să se îndeplinească condiția **value1 < value2** pentru a se intra în bucla **FOR**, indiferent dacă se folosește **IN** sau **IN REVERSE** 
-  * Incrementarea (cazul cu **IN**) sau decrementarea (cazul **IN REVERSE**) contorului este făcută automat cu 1 (cu data tipul PLS_INTEGER) 
-</​note>​ 
- 
-<color red>Ex. 10.</​color>​ Să se modifice exercițiul precedent astfel încât să folosească instrucțiunea FOR. 
- 
-{{:​bd2:​laboratoare:​l02ex10.png?​730|}} 
- 
-<​note>​ 
-Observații:​ 
-  * Buclele pot fi imbricate pe mai multe niveluri 
-  * În general, o buclă internă nu termină execuția unui bucle care o include, exceptând cazul când este generată o excepție 
-  * Pentru salturi de instrucțiuni,​ se folosește instrucțiunea **GOTO** 
-  * **GO** poate fi folosit în oricare dintre instrucțiunile prezentate 
-  * Instrucțiunea **GOTO** poate fi folosită și să se iasă dintr-o buclă 
-</​note>​ 
- 
-<color red>Ex. 11.</​color>​Exemplu de folosire a instrucțiunii GOTO. 
- 
-{{:​bd2:​laboratoare:​l02ex11.png?​730|}} 
- 
-<color red>Ex. 12.</​color>​ Exeplu de ieșise dintr-o buclă folosind GOTO. 
- 
-{{:​bd2:​laboratoare:​l02ex12.png?​730|}} 
- 
-<color red>Ex. 13.</​color>​ Să se scrie un bloc PL/SQL care face o listă cu numărul angajaților care au veniturile mai mici de 2000 (considerate venituri mici) și mai mari de 2000 (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. 
- 
-{{:​bd2:​laboratoare:​l02ex13.png?​730|}} 
- 
-===== Tipuri compuse și colecție ===== 
- 
- 
-==== Tipul RECORD ==== 
- 
-Tipurile scalare nu au componente interne, în timp ce tipurile compuse au componente interne care se pot manipula. ​ 
- 
-RECORD este un tip compus: 
-  * Folosit pentru a accesa liniile tabelelor sub formă de matrice 
-  * Asemănător cu o înregistrare a unei tabele cu excepția faptului că numele coloanelor sunt proprii fiecărei înregistrări 
- 
-Declararea tipului RECORD se face conform următoarei sintaxe:​ 
- 
-<code sql> 
-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] ] 
-);​ 
-</​code>​ 
- 
-<​note>​ 
-Începând cu Oracle9i, pentru tipul RECORD sunt  introduse câteva facilităţi:​ 
-  * Se poate insera (INSERT) o linie într-un tabel utilizând tipul RECORD 
-  * Se poate actualiza (UPDATE) o linie într-un tabel utilizând tipul RECORD (cu sintaxa SET ROW) 
-  * Se poate regăsi şi returna sau şterge informaţia din clauza RETURNING a comenzilor UPDATE sau DELETE 
-  * Dacă în comenzile UPDATE sau DELETE se modifică mai multe linii, atunci pot fi utilizate colecţii de înregistrări cu sintaxa BULK COLLECT INTO 
-</​note>​ 
- 
-<color red>Ex. 14.</​color>​ Un exemplu de utilizare a tipului RECORD.​ 
- 
-{{:​bd2:​laboratoare:​l02ex14.png?​730|}} 
- 
-<color red>Ex. 15.</​color>​ Ex. 15. Folosindu-se tipul compus RECORD: 
-  * Să se creeze un record de forma tabelului dept 
-  * Să se insereze un nou departament folosind o variabilă de tip record 
-  * Să se selecteze înregistrarea inserată într-un record 
-  * Să se updateze înregistrarea inserată folosindu-se record și să se returneze într-un record informații 
-  * Să se șteargă departamentul creat și să se  returneze într-un record informații. 
- 
-{{:​bd2:​laboratoare:​l02ex15.png?​730|}} 
- 
-==== Tipuri colecție ==== 
- 
-Tipurile colecție sunt: 
-  * Varrays 
-  * Index-by table 
-  * Nested tables 
- 
-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​ ​                      | 
- 
- 
-=== Tipul VARRAY === 
- 
-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:​ 
- 
-<code sql> 
-TYPE name IS {VARRAY | VARYING ARRAY} (max_length) OF element_type [NOT NULL]​; 
-</​code>​ 
- 
-<color red>Ex. 16.</​color> ​ Exemplul folosire varray​. 
- 
-{{:​bd2:​laboratoare:​l02ex16.png?​730|}} 
- 
-=== Tipul ASSOCIATIVE ARRAY === 
- 
-Tipul ASSOCIATIVE ARRAY se mai numește și INDEX BY TABLE (tabel indexat). 
- 
-Un table indexat în PL/SQL are două componente: 
-  * Coloană ce cuprinde cheia primară pentru a avea acces la liniile tabelului 
-  * O coloană care include valoarea efectivă a elementelor tabelului 
- 
-Declararea tipului ASSOCIATIVE ARRAY se face cu următoarea sintaxă: 
- 
-<code sql> 
-TYPE name IS TABLE OF​ {data_type | variable%TYPE |​ table.column%TYPE [NOT NULL] |​ table%ROWTYPE}​ INDEX BY data_type_index;​​ 
-</​code>​ 
- 
-Unde: 
-  * data_type_index poate fi String sau Integer 
- 
-<note important>​ 
-Observații:​ 
-  * Elementele unui ASSOCIATIVE ARRAY nu sunt într-o ordine particulară şi pot fi inserate cu chei arbitrare 
-  * Deoarece nu există constrângeri de dimensiune, dimensiunea tabelului se modifică dinamic 
-  * Un ASSOCIATIVE ARRAY nu poate fi iniţializat în declararea sa 
-  * Un ASSOCIATIVE ARRAY neiniţializat este vid (nu conţine nici valori, nici chei) 
-  * Un element al unui ASSOCIATIVE ARRAY este nedefinit atâta timp cât nu are atribuită o valoare efectivă 
-  * Dacă se face referire la o linie care nu există, atunci se produce excepţia **NO_DATA_FOUND**.​ 
-</​note>​ 
- 
-<color red>Ex. 17.</​color>​ Exemplu de folosire ASSOCIATIVE ARRAY. 
- 
-{{:​bd2:​laboratoare:​l02ex17.png?​730|}} 
- 
-=== Tipul Nested Table​ === 
- 
-Un tablou imbricat este o mulţime neordonată de elemente de acelaşi tip. Valorile de acest tip: 
-  * Pot fi stocate în baza de date 
-  * Pot fi prelucrate direct în instrucţiuni SQL 
-  * Au excepţii predefinite proprii 
- 
-Comanda de declarare a tipului de date tablou imbricat are sintaxa: 
-<code sql> 
-TYPE name IS TABLE OF {data_type | variable%TYPE |​ table.column%TYPE [NOT NULL] |​ table%ROWTYPE}​ [NOT NULL];​ 
-</​code>​ 
- 
-<​note>​ 
-Observații:​ 
-  * Pentru adăugarea de linii intr-un tablou imbricat, acesta trebuie sa fie inițializat cu ajutorul constructorului 
-  * PL/SQL apelează un constructor numai în mod explicit 
-  * Tabelele indexate nu au constructori 
-  * Constructorul primeşte ca argumente o listă de valori numerotate în ordine, de la 1 la numărul de valori date ca parametrii constructorului 
-  * Dimensiunea iniţială a colecţiei este egală cu numărul de argumente date în constructor,​ când aceasta este iniţializată 
-  * Pentru vectori nu poate fi depăşită dimensiunea maximă precizată la declarare 
-  * Atunci când constructorul este fără argumente va crea o colecție fără niciun element (vida), dar care are valoarea not null 
-</​note>​ 
- 
-<color red>Ex. 18.</​color>​ Exemplu de folosire al unui tabel imbricat.​ 
- 
-{{:​bd2:​laboratoare:​l02ex18.png?​730|}} 
- 
-==== Colecții stocate ==== 
- 
-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​ | 
- 
- 
-<color red>Ex. 19.</​color>​ Definirea tipurilor direct în baza de date. 
- 
-{{:​bd2:​laboratoare:​l02ex19.png?​730|}} 
- 
-==== BULK COLLECT ==== 
- 
-Pentru a insera mai multe valori într-o variabilă de tip colecție se poate folosi BULK COLLECT INTO.  
- 
- 
-<color red>Ex. 20.</​color>​ Folosirea BULK COLLECT INTO cu varray.​ 
- 
-{{:​bd2:​laboratoare:​l02ex20.png?​730|}} 
- 
-<color red>Ex. 21.</​color>​ Folosirea BULK COLLECT INTO cu index-by table.​ 
- 
-{{:​bd2:​laboratoare:​l02ex21.png?​730|}} 
- 
-<color red>Ex. 22.</​color>​ Folosirea BULK COLLECT INTO cu nested table.​ 
- 
-{{:​bd2:​laboratoare:​l02ex22.png?​730|}} 
- 
-==== Colecții de înregistrări ==== 
- 
-Se poate crea un "​tabel"​ care sa aibă coloane definite de dezvoltatori folosind un table(index-by sau nested) care să fie de tipul RECORD. 
- 
-<color red>Ex. 23.</​color>​ Crearea unui tabel cu coloanele definite de utilizator. 
- 
-{{:​bd2:​laboratoare:​l02ex23.png?​730|}} 
- 
  
bd2/laboratoare/02.1601969193.txt.gz · Last modified: 2020/10/06 10:26 by apetrescu0506
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0