Elemente de PL/SQL
1. Blocuri
Acestea reprezina unitati logice de program din cadrul limbajului procedural PL/SQL si contin alaturi de frazele SQL o serie de instructiuni comenzi procedurale. Din punct de vedere sintactic, blocurile contin o parte declarativa, o parte executabila si o sectiune de tratare a exceptiilor. (Obs. Īn PL/SQL aparitia unei erori reprezinta o exceptie). Deosebim trei tipuri de blocuri, si anume: 858e44i blocuri anonime (sunt declarate īntr-un punct al aplicatiei, de unde sunt lansate īn executie; nu au nume, deci nu pot fi apelate din alte programe), blocuri de tip subprogram (apar sub forma unor proceduri/functii, putānd fi apelate din alte subprograme):
[DECLARE
<declaratii_locale>]
BEGIN
<instructiuni>
[EXCEPTION
<instructiuni>]
END;
PROCEDURE <nume>[<param_formali>] IS
[<declaratii_locale>]
BEGIN
<instructiuni>
[EXCEPTION
<instructiuni>]
END;
FUNCTION <nume> [<param_formali>] RETURN <tip_data> IS
[<declaratii_locale>]
BEGIN
<instructiuni>
RETURN <valoare>
[EXCEPTION
<instructiuni>
RETURN <valoare>]
END;
Obs. 1. Īn zona declaratiilor locale, putem avea declaratii de constante, variabile, cursoare, exceptii utilizator si/sau de subprograme. Īn ceea ce priveste constantele si variabilele locale, acestea se declara īn felul urmator:
<nume> CONSTANT <tip_data> := <valoare>;
<nume> <tip_data> [NOT NULL] [ <valoare>]
Obs. 2. Frazele SELECT prezinta īn limbajul procedural o serie de particularitati spre deosebire de comenzile INSERT, UPDATE si DELETE ce se pot utiliza fara nici o restrictie
fraza SELECT trebuie sa returneze o singura valoare sau o singura linie de date; returnarea mai multor īnregistrari sau a nici uneia genereaza "eroarea" <too_many_rows> respectiv <no_data_found>, ce se poate trata īn sectiunea de exceptii a blocului
comanda SELECT trebuie sa contina clauza INTO pentru a memora rezultatul interogarii;
SELECT nu poate contine clauzele GROUP BY si ORDER BY.
Obs. 3. Atributele %TYPE si %ROWTYPE se folosesc pentru a declarara o variabila similara cu un cāmp din structura unei tabele de date, respectiv o variabila de tip īnregistrare identica cu structura īnregistrarilor tabelei referite.
2. Comanda SELECT
Tratarea acesteia prin programarea exceptiilor
Exceptiile, atāt cele sistem, cāt si cele declarate de catre utilizator īn zona de declaratii locale, pot fi activate explicit cu ajutorul comenzii RAISE. Tratarea tuturor acestor exceptii, adica specificarea actiunilor ce au loc atunci cānd se declanseaza exceptiile respective, se realizeaza cu ajutorul comenzii
WHEN <exceptie> THEN <instructiuni>.
Exemplu : |
Se va formula o procedura ce permite īnregistrarea unei noi facturi; inserarea acesteia īn tabela facturi se va descrie n portiunea de tratare a exceptiei no_data_found. |
PROCEDURE inserare (nr IN NUMBER) IS
v_factura facturi%ROWTYPE;
BEGIN
SELECT * INTO v_factura
FROM facturi
WHERE nrfact = nr;
RAISE too_many_rows;
EXCEPTION
WHEN no_data_found THEN
INSERT INTO facturi (nrfact, codcl, obs)
VALUES (nr, 1005,'');
WHEN too_many_rows THEN
DBMS_OUTPUT.PUT_LINE ('Nr existent !!!');
END;
Tratarea acesteia cu ajutorul cursoarelor explicite
Un cursor exlicit reprezinta o zona de memorie utilizata pentru prelucrarea interogarilor SELECT ce returneaza mai multe linii de date. Pentru a controla un cursor explicit trebuie sa parcurgem urmatoarele etape
declararea cursorului:
CURSOR <nume> [(<param_formali>)] IS <interogare_SELECT>;
deschiderea cursorului:
OPEN <nume> [(<param_actuali>)];
prelucrarea datelor (a unei linii de date) din cursor:
FETCH <nume> INTO <variabile>;
īnchiderea cursorului
CLOSE <nume;
Exemplu : |
Se va formula o procedura pentru afisarea pozitiilor unei facturi; se va declara un cursor explicit pentru tratarea frazei SELECT utilizate. |
PROCEDURE afisare (nr IN NUMBER) IS
v_inreg liniifact%ROWTYPE;
v_linie CHAR(2);
v_codpr CHAR(6);
c_cant CHAR(11);
c_pr CHAR(11);
CURSOR c_fact IS
SELECT *
FROM liniifact
WHERE nrfact = nr;
BEGIN
OPEN c_fact;
FETCH c_fact INTO v_inreg;
EXIT WHEN c_fact%NOTFOUND;
v_linie := TO_CHAR(v_inreg.linie);
v_codpr := TO_CHAR(v_inreg.codpr);
v_cant := TO_CHAR(v_inreg.cantitate);
v_pr := TO_CHAR(v_inreg.pretunit);
DBMS_OUTPUT.PUT_LINE(v_linie v_codpr v_cant v_pr);
END
CLOSE c_fact;
END;
|