Exercitii date spre rezolvare: Enunt/Rezolvare pentru Luni EG305 10-14
PL/SQL este un limbaj structurat pe blocuri. Are caracteristici de procesare procedurală și de tratare a erorilor. Blocurile pot fi de două tipuri:
Deoarece PL/SQL este o extensie pentru SQL, regulile sintactice de bază aplicabile în SQL sunt valabile și în PL/SQL:
PL/SQL permite o varietate de tipuri de date ce pot fi folosite pentru declararea de variabile și constante. Variabilele pot avea, opțional, atribuite valori la declarare și pot să-și schimbe valoarea prin atribuiri ulterioare în cadrul blocului. Constantele sunt identificatori care păstrează o valoare fixă ce trebuie atribuită în momentul declarării. Instructiunile PL/SQL nu sunt case sensitive. Setul de caractere este format din literele mari și mici, cifrele de la 0-9, spații, caractere de tabulare, carriage return și simboluri special.
Blocul anonim are cea mai simplă structură și este compus din trei părți:
Fiecare bloc începe cu unul dintre cuvintele cheie DECLARE sau BEGIN. Cuvântul BEGIN este punctul de început al blocului de execuție. Înainte de executarea unui bloc se golește bufferul SQL.
Structura logică a unui bloc PL/SQL anonim este:
Ex. 1. Să se selecteze numele si functia unui angajat introducand id-ul acestuia de la tastatura (testați cu 1, 100 și 200).
/
*
…*
/
-
-
-
-
acest & se va executa , atunci compilatorul va cere o valoare pentru variabila de substituție & din comentariu./
*
acest & nu se va executa *
/
, atunci compilatorul nu va cere o valoare pentru variabila de substituție & din comentariu.
Blocurile anonime pot fi înlănțuite. Execuția se face secvențial. Declararea variabilelor pentru toate blocurile înlănțuite se face o singură data în secțiunea DECLARE.
Structura logică pentru un bloc înlănțuit este:
[<<label>>] -- etichetă bloc (opțional) [DECLARE] -- (opțional) -- variabile pentru blocurile partinte și copii BEGIN -- start bloc parinte [DECLARE] -- (opțional) -- variabile pentru blocul copil_1 BEGIN -- start blocul copil_1 -- accesibile variabilele declarate în blocurile -- parinte și copil_1 [EXEPTION] -- (opțional) -- interceptarea și tratarea excepțiilor blocul copil_1 END; -- sfârșit bloc copil_1 [DECLARE] -- (opțional) -- variabile pentru blocul copil_2 BEGIN -- start blocul copil_2 -- accesibile variabilele declarate în blocurile -- parinte si copil_2 [EXCEPTION] -- (opțional) -- interceptarea și tratarea excepțiilor bloc 2 END; -- sfârșit bloc copil_2 [EXCEPTION] -- (opțional) -- interceptarea și tratarea excepțiilor bloc principal -- si orice alta exceptie netratata în blocurile copii END; -- sfârșit bloc parinte
Ex. 2. Să se insereze un nou angajat, astfel:
După insert să se adauge pentru acest angajat un punctaj pentru comision de 0.5.
Blocurile imbricate sunt blocuri care se execută în interiorul altui bloc. Se mai numesc și sub-blocuri. Variabile pot fi transmise de la bloc la sub-bloc, nu și invers.
Structura logică pentru un bloc imbricat este:
[<<label>>] -- etichetă bloc (opțional) [DECLARE] -- (opțional) -- variabile bloc principal, bloc 1, bloc 2, bloc 3 BEGIN [DECLARE] -- (opțional) -- variabile bloc 1, bloc 2, bloc 3 BEGIN -- bloc 1 [DECLARE] -- (opțional) -- variabile bloc 2, bloc 3 BEGIN -- bloc 2 [DECLARE] -- (opțional) -- variabile bloc 3 BEGIN -- bloc 3 [EXCEPTION] -- (opțional) -- tratare erori bloc 3 END; -- bloc 3 [EXCEPTION] -- (opțional) -- tratare erori bloc 2 -- tratarea erorilor propagate din blocul 3 END; -- bloc 2 [EXCEPTION] -- (opțional) -- tratare erori bloc 1 -- tratarea erorilor propagate din blocul 2 și 3 END; -- bloc 1 [EXCEPTION] -- (opțional) -- tratare erori bloc principal -- tratarea erorilor propagate din blocurile 1, 2 și 3 END;
Ex. 3. Să se rezolve exercițiul anterior folosind blocuri imbricate.
În cazul în care nu aveți acces la un IDE, puteți să vă conectați la un Server ORACLE folosind utilitarul în linie de comandă SQL*Plus. (Mai multe dedalii în Laboratorul 2 - Baze de date)
Pentru a vă conecta la SQL*Plus în consolă comanda care se folosește este:
sqlplus [username[/password[@bazadate]]]
Blocurile PL/SQL pot fi editate direct în SQL*Plus (nerecomandat) sau pot fi editate în orice editor de text. Pentru a executa un bloc în SQL*Plus folositi una din comenzile (comanda intreagă sau abrevierea):
Comandă | Abreviere | Utilizare |
---|---|---|
RUN | R | Afișează și execută blocul curent din buffer |
/ | Execută blocul curent din buffer |
În SQL*Plus
În SQL*Plus un bloc se poate executa astfel:
În linia de comandă se mai pot da și următoarele comenzi:
Comenzi SQL*Plus utile pentru formatare
Comandă | Utilizare |
---|---|
set serveroutput on | Permite afișarea în SQL*Plus |
set lines n | Permite printarea a n caractere pe verticală |
set pages n | Permite printarea a n coloane |
PL/SQL acceptă toate tipurile de date din SQL. Nu sunt permise referințe anticipate, deci toate variabilele și constantele trebuie să fie declarate în secțiunea DECLARE înainte de utilizare. În secțiunea DECLARE trebuie declarate numele și tipul fiecărei variabile utilizate în cadrul blocului. Tipul specifică formatul de memorare, restricțiile și un domeniu valid de valori. Sintaxa declarării unei variabile este următoarea:
nume_var [CONSTANT]{tip_de_date|identificator%TYPE|identificator%ROWTYPE}[NOT NULL][{:=|DEFAULT} expresie_PL/SQL];
Tipurile de date scalare nu au componente interne (conţin valori atomice).
Tipurile de date ce stochează valori numerice cuprind:
Tipurile de date ce stochează caractere cuprind:
Tipurile de date ce stochează data calendaristica si ora cuprind tipurile:
Tipurile de date ce stochează date în format unicode includ tipurile
Tipul de date BOOLEAN stochează valori logice (true, false sau null)
Exemple:
v_valoare NUMBER(15) NOT NULL := 0; v_data_achizitie DATE DEFAULT SYSDATE; v_material VARCHAR2(15) := 'Matase'; c_valoare CONSTANT NUMBER := 100000; v_stare VARCHAR2(20) DEFAULT 'Buna'; v_clasificare BOOLEAN DEFAULT FALSE; int_an_luna INTERVAL YEAR TO MONTH := INTERVAL '3-2' YEAR TO MONTH; --interval de 3 ani si 2 luni
Ex. 4. Să se scrie un bloc PL/SQL care primește de la tastatură un id de angajat și va afișa un mesaj cu forma: 'nume_angajat are un venit orar de venit_orar și face parte din departamentul denumire_departament. A lucrat în firma un număr total de zile_lucrate zile'. În caz că angajatul nu există să se trateze eroarea.
Tipurile corelate sunt folosite pentru a declara variabile de tipul unui rând de tabel sau al unei coloane de tabel. Avantajul folosirii unor astfel de tipuri este că atunci când se modifică structura coloanelor dintr-un tabel nu mai trebuie să fie modificat și codul PL/SQL.
Tipuri corelate:
Ex. 5. Să se scrie un bloc PL/SQL care primește de la tastatură un id de angajat și afișează numele, funcția acestuia, departamentul și locația departamentului. Locația deopartamentului va cuprinde orașul, statul/județul, țara și regiunea.
Tipuri LOB (Large OBject) sunt folosite pentru stocarea de date binare, text, imagini și fișiere video de dimensiuni mari (până la 4GB).
Data Type | Description |
---|---|
CLOB | A character large object containing single-byte or multibyte characters. Both fixed-width and variable-width character sets are supported, both using the database character set. Maximum size is (4 gigabytes - 1) * (database block size). |
NLOB | A character large object containing Unicode characters. Both fixed-width and variable-width character sets are supported, both using the database national character set. Maximum size is (4 gigabytes - 1) * (database block size). Stores national character set data. |
BLOB | A binary large object. Maximum size is (4 gigabytes - 1) * (database block size). |
BFILE | Contains a locator to a large binary file stored outside the database. Enables byte stream I/O access to external LOBs residing on the database server. Maximum size is 4 gigabytes. |
Operatori aritmetici | Descriere |
---|---|
+ | Adunare |
- | Scădere |
* | Multiplicare |
/ | Împărțire |
** | Exponențial |
Operatorii de comparație pot fi feluri: operatori logici și operatori SQL
Operator Logic | Semnificație |
---|---|
= | Egal |
> | Mai mare decât |
>= | Mai mare sau egal decât |
< | Mai mic decât |
<= | Mai mic sau egal decât |
Operator SQL | Semnificație |
---|---|
val BETWEEN val1 AND val2 | Verifică daca o valoare se află între două valori date (inclusiv). Echivalent cu val >= val1 AND val <= val2 |
IN (list) | Compară dacă valoarea se află în lista de valori list. val IN (a,b,c) este echivalent cu val = a OR val = b OR val = c |
LIKE string | Compară cu un model de tip caracter/șir de caractere |
IS NULL | Verifică dacă o valoare este NULL |
Operatorii de negație pot fi de două feluri: operatori logici și operatori SQL.
Operator Logic | Semnificație |
---|---|
!= | Diferit de (Unix, Windows) |
^= | Diferit de (IBM) |
<> | Diferit de (Toate OS) |
NOT val { = | > | >= | < | <= } | Neagă operatorul de comparație |
Operator SQL | Semnificație |
---|---|
NOT BETWEEN val1 AND val2 | Verifică daca o valoare nu se află între două valori date (inclusiv) |
NOT IN (list) | Compară dacă valoarea nu se află în lista de valori list. |
NOT LIKE string | Compară cu un model de tip caracter/șir de caractere |
IS NOT NULL | Verifică dacă o valoare nu este NULL |
Precedența operatorilor logici este următoarea:
=,<,<=,>,>=,<>,!=,^=, BETWEEN, IN, LIKE, IS NULL
)NOT
(pentru inversarea rezultatului unei expresii logice)AND
OR
Ordine | Operație | Descriere |
---|---|---|
1 | ** | exponențial |
2 | + , - | identitate, negație |
3 | * , / | înmulțire, împărțire |
4 | + , - , || | adunare, scădere, concatenare |
5 | = , != , < , > , %⇐% , >= , IS NULL , LIKE , BETWEEN , IN | comparație |
6 | NOT | negație |
7 | AND | conjuncție |
8 | OR | incluziune |
Simbol | Descriere |
---|---|
( ) | Delimitator de listă sau expresii |
; | Delimitator de instrucțiuni |
, | Separator de obiect |
. | Selector de componentă |
@ | Delimitator de acces la baza de date |
' | Delimitator de șir |
: | Delimitator de server |
$ | Format de afișare în USD |
& | Variabilă substituită |
Simbol | Descriere |
---|---|
:= | Asignare |
= > | Asociere |
.. | Rang |
|| | Concatenare |
< < > > | Etichetă |
- - | Comentariu pe o singură linie |
/ * * / | Comentatiu pe mai multe linii |
Domeniul de valabilitate al variabilelor reprezintă zona unui program în care acestea pot fi folosite. Variabilele și constantele pot fi declarate în cadrul blocului în care au fost definite sau în orice sub-bloc inclus în acesta. Variabilele declarate într-un sub-bloc pot fi folosite doar în acesta sau în sub-blocurile acestuia. Variabilele se pot transmite de la un bloc la sub-bloc, dar nu și invers. Aceste constrângeri se aplică tuturor obiectelor declarate, inscusiv cursoare, constante și excepții definite de utilizator.
Ex. 6. Să se afișeze informațiile despre ultimul angajat care a venit în firmă în anul 2001.
Ex. 7. Să se găsească care angajat are o vechime de peste 19 de ani si 5 luni in firmă.
Ex. 8. Să se facă o verificare a numărului de angajări pentru un an introdus de la tastatură. Dacă există o angajare, atunci se va afișa mesajul 'In anul [an] au avut loc [numar angajari] angajare'. Dacă nu există nicio angajare, se va declanșa o excepție no_data_found și se va afișa mesajul 'Nu exista angajari in anul [an]'. Dacă sunt mai mulți angajați, se va declanșa excepția too_many_rows și se va afișa mesajul 'Sunt [numar angajari] angajari in anul [an]'.
Ex. 9. Să să selecteze departamementul, numele, data angajării și comisionul unui angajat introducând id-ul angajatului de la tastatură. În cazul în care angajatul nu are departament, se afișează N/A. Testați cu valorile 100 si 178
Ex. 10. Să se calculeze suma veniturilor angajaților care au aceeași funcție și lucrează în același departament. Testați cu