-
Notifications
You must be signed in to change notification settings - Fork 19
SGBD
-
nume_variabila := expresie;
-
IF conditie1 THEN secventa_de_comenzi_1 [ELSIF conditie2 THEN secventa_de_comenzi_2] ... [ELSE secventa_de_comenzi_n] END IF;
-
Sau următoarea formă, în care fiecare clauză WHEN conține o expresie booleană.
CASE test_var WHEN valoare_1 THEN secventa_de_comenzi_1; WHEN valoare_2 THEN secventa_de_comenzi_2; ... WHEN valoare_k THEN secventa_de_comenzi_k; [ELSE alta_secventa;] END CASE;
CASE WHEN conditie_1 THEN secventa_de_comenzi_1; WHEN conditie_2 THEN secventa_de_comenzi_2; ... WHEN conditie_k THEN secventa_de_comenzi_k; [ELSE alta_secventa;] END CASE;
-
Exemplu:
[DECLARE instructiuni de declarare] BEGIN instructiuni executabile (SQL sau PL/SQL) END;
-- Programul afiseaza suma a doua numere. SET SERVEROUTPUT ON; DECLARE a number; b number; rez number; BEGIN rez := a + b; dbms_output.put_line(rez); END;
-
Exemplu:
TYPE nume_tip IS RECORD ( nume_camp1 tip_camp1; nume_camp2 tip_camp2; ... );
-- Declararea tipului TYPE individ IS RECORD ( cnp number; nume varchar2(100); prenume varchar2(100); ); -- Declararea unei variabile de tipul <individ> v_angajat individ;
-
-
Exemplu:
TYPE nume_tip IS TABLE OF tip INDEX BY tip_indexare
Output-ul pentru aceste instrucțiuni este următorul:SET SERVEROUTPUT ON; DECLARE -- Declar tipul elementelor din tabel. TYPE pereche is RECORD ( num number, some_date date ); -- Declar tabelul de elemente de tipul definit mai sus. -- Il voi indexa in functie de intregi astfel incat sa ma refer la -- elemente prin numere. (ex: v_tab(1), v_tab(2)). -- Poate fi folosit si BINARY_INTEGER pentru aceeasi cauza. De -- mentionat ca elementele dintr-un INDEX-BY Table NU pot fi -- indexate dupa tipuri standard precum INTEGER, NUMBER, etc. In -- schimb pot fi indexate dupa string-uri (VARCHAR2 etc.) TYPE valori is TABLE OF pereche INDEX BY PLS_INTEGER; -- Declar o variabila de tipul tabelului definit mai sus. v_tab valori; -- Declar o variabila de tipul structurii definite mai sus in care -- voi stoca informatiile ce vor fi puse ulterior in tabel. v_pereche pereche; v_start_date date := to_date('01-01-1970', 'dd-mm-yyyy'); BEGIN for i in 1..5 loop -- Adaug in campul 'num1' pe i si in campul 'some_date' a "i"-a -- zi dupa 01.01.1970. v_pereche.num := i; v_pereche.some_date := v_start_date + i; -- Adaug in tabel structura realizata mai sus. v_tab(i) := v_pereche; end loop; -- Afisez elementele vectorului, separand fiecare camp prin spatiu. for i in 1..v_tab.COUNT loop dbms_output.put_line(v_tab(i).num || ' ' || to_char(v_tab(i).some_date, 'dd-mm-yyyy')); end loop; END;
1 02-01-1970 2 03-01-1970 3 04-01-1970 4 05-01-1970 5 06-01-1970
-
Exemplu
TYPE nume_tip IS VARRAY(lungime_maxima) OF tip_elemente;
Output-ul comenzii de mai sus va arăta în felul următor:SET SERVEROUTPUT ON; DECLARE -- Declar tipul elementelor din vector. TYPE pereche is RECORD ( num1 NUMBER, num2 NUMBER ); -- Declar array-ul de elemente definite mai sus si initializez -- acest array. TYPE valori is VARRAY(256) OF pereche; v_vec valori := valori(); -- Declar o variabila de tipul structurii definite mai sus in care -- voi stoca informatiile ce vor fi puse ulterior in vector. v_pereche pereche; BEGIN -- Adaug 5 de elemente in vector dupa regula descrisa mai jos. for i in 1..5 loop -- Maresc capacitatea de stocare a vectorului. v_vec.EXTEND; -- Regula: Adaug in campul 'num1' pe i si in campul 'num2' pe i-1. v_pereche.num1 := i; v_pereche.num2 := i - 1; -- Adaug in vector structura realizata mai sus. v_vec(v_vec.COUNT) := v_pereche; end loop; -- Afisez elementele vectorului, separand fiecare camp prin spatiu. for i in 1..v_vec.COUNT loop dbms_output.put_line(v_vec(i).num1 || ' ' || v_vec(i).num2); end loop; END; . / -- NOTA: Spre deosebire de INDEX-BY table, nu pot fi adaugate -- valori pe orice pozitie. Vectorul are initial lungimea 0, -- iar la fiecare apel al metodei EXTEND, el isi creste lungimea -- cu 1.
1 0 2 1 3 2 4 3 5 4
-
Nested tables (Tablouri imbricate)
ExempluTYPE nume_tip IS TABLE OF tip_elemente;
Executând blocul de mai sus, vom obține următorul rezultat (identic cu cel de la "Index-by" table)SET SERVEROUTPUT ON; DECLARE -- Declar tipul elementelor din tabel. TYPE pereche is RECORD ( num number, some_date date ); -- Declar tabelul de elemente de tipul definit mai sus. TYPE valori is TABLE OF pereche; -- Declar o variabila de tipul tabelului definit mai sus. v_tab valori := valori(); -- Declar o variabila de tipul structurii definite mai sus in care -- voi stoca informatiile ce vor fi puse ulterior in tabel. v_pereche pereche; v_start_date date := to_date('01-01-1970', 'dd-mm-yyyy'); BEGIN for i in 1..5 loop -- Adaug in campul 'num1' pe i si in campul 'some_date' a "i"-a -- zi dupa 01.01.1970. v_pereche.num := i; v_pereche.some_date := v_start_date + i; -- Adaug in tabel structura realizata mai sus. v_tab.EXTEND; v_tab(v_tab.COUNT) := v_pereche; end loop; -- Afisez elementele vectorului, separand fiecare camp prin spatiu. for i in 1..5 loop dbms_output.put_line(v_tab(i).num || ' ' || to_char(v_tab(i).some_date, 'dd-mm-yyyy')); end loop; END; . /
1 02-01-1970 2 03-01-1970 3 04-01-1970 4 05-01-1970 5 06-01-1970
De menționat este faptul că există diferențe între "Index-By Table" și "Nested Table" și anume:
-
Nested Table
-- Trebuie initializat -- tabelul cu un constructor. v_tab valori := valori();
-- Nu este mentionat tipul dupa care se face -- ordonarea elementelor TYPE valori is TABLE OF pereche;
-
Index-by Table
-- Initializarea se face implicit. v_tab valori;
Totodată, următorul tabel descrie diferențele semnificative dintre tipul de colecții:-- Este mentionat tipul in functie de care -- este determinata pozitia elementului in tabel TYPE valori is TABLE OF pereche INDEX BY PLS_INTEGER;
Nested Table Varray Index-by Table Nu are lungime maximă
Are lungime maximă
Nu are lungime maximă
Elementele pot fi așezate în așa fel încât să existe elemente lipsă între oricare două elemente atunci când în acele spații s-au aflat alte elemente care au fost scoase ulterior. Nu pot fi adăugate elemente într-un mod împrăștiat ca la Index-by Table.
Nu există locuri libere între elemente. Componentele unui Varray pot fi scoase doar de la sfârșitul vectorului.
Elementele sunt aranjate într-un mod "împrăștiat" (ex: pot fi adăugate elemente pe pozițiile 1, 2, 4, iar pe poziția 3 să nu fie nimic).
Poate fi stocat într-o bază de date.
Poate fi stocat într-o bază de date.
Nu poate fi stocat într-o bază de date.
Inițializarea se face prin constructor.
Inițializarea se face prin constructor.
Inițializarea se face la declarare (implicit).
-
-
-
Cursoarele sunt folosite pentru a itera peste (a parcurge) rezultatele query-urilor (SELECT-urilor) executate asupra tabelelor. Fie configurația bazei de date generată de următorul script:
CURSOR nume_cursor IS SELECT ...
Cursoarele pot fi declarate explicit (ca în definiția de mai sus) sau pot fi considerate implicite în urma unui query peste un tabel. Exemplu pentru declararea explicită:CREATE TABLE myTable ( id_info number primary key, country varchar2(50) default NULL, date_something varchar2(50) default NULL ); INSERT INTO myTable (id_info,country,date_something) VALUES ('1','Bulgaria','15-07-10'); INSERT INTO myTable (id_info,country,date_something) VALUES ('2','Gabon','21-08-12'); INSERT INTO myTable (id_info,country,date_something) VALUES ('3','Morocco','17-06-12'); INSERT INTO myTable (id_info,country,date_something) VALUES ('4','Thailand','09-08-12'); INSERT INTO myTable (id_info,country,date_something) VALUES ('5','Hong Kong','06-08-10'); INSERT INTO myTable (id_info,country,date_something) VALUES ('6','Saint Vincent and The Grenadines','18-09-11'); INSERT INTO myTable (id_info,country,date_something) VALUES ('7','Mauritius','21-01-13'); INSERT INTO myTable (id_info,country,date_something) VALUES ('8','Sudan','14-12-10'); INSERT INTO myTable (id_info,country,date_something) VALUES ('9','Belize','04-12-11'); INSERT INTO myTable (id_info,country,date_something) VALUES ('10','Afghanistan','22-05-11');
Exemplu pentru cursorul implicit:SET SERVEROUTPUT ON; DECLARE cursor curr is select * from myTable; BEGIN for i in curr loop dbms_output.put_line(i.id_info || ' ' || i.country); end loop; END; . /
Ambele exemple produc următorul output:SET SERVEROUTPUT ON; BEGIN for i in (select * from myTable) loop dbms_output.put_line(i.id_info || ' ' || i.country); end loop; END; . /
1 Bulgaria 2 Gabon 3 Morocco 4 Thailand 5 Hong Kong 6 Saint Vincent and The Grenadines 7 Mauritius 8 Sudan 9 Belize 10 Afghanistan
-
Parametrii se scriu sub forma nume_parametru [scop] tip_parametru, unde [scop] poate fi: in, out, sau ambele (in out). Implicit, parametrii sunt de tipul in. Dacă se dorește memorarea unei valori într-o variabilă dată ca parametru, se folosește out, însă valoarea acestei variabile nu va putea fi citită decât dacă este însoțită de cuvântul cheie in.
CREATE OR REPLACE PROCEDURE nume_procedura [(lista parametrii)] AS [declaratiile variabilelor locale] BEGIN instructiuni END;
Exemplu de procedură:
În urma execuției următoarei secvențe de instrucțiuni, vor fi introduse numărul 2 în tabelul par și 3 în tabelul impar.-- Tabel in care retin numerele pare. CREATE TABLE pare ( nr number ); -- Tabel in care retin numerele impare. CREATE TABLE impare ( nr number ); -- Procedura primeste ca parametru un numar pe care il introduce in -- tabelul 'pare' daca numarul introdus este 'par', altfel este introdus -- tabelul 'impare'. CREATE OR REPLACE PROCEDURE my_procedure(val number) AS BEGIN if val mod 2 = 0 then insert into pare values (val); else insert into impare values (val); end if; END; . /
call my_procedure(2); call my_procedure(3);
-
Funcțiile sunt asemănătoare procedurilor, singura diferență fiind faptul că ele trebuie să returneze și o valoare de tipul menționat în declarația funcției, conform definiției de mai sus.
CREATE OR REPLACE FUNCTION nume_functie [(lista parametrii)] RETURN tip_valoare_returnata AS BEGIN instructiuni END;
Exemplu:
Funcția de mai sus primește un număr n și returnează 1 în cazul în care n este prim, 0 altfel. Iată un mod de utilizare al funcției:CREATE OR REPLACE FUNCTION prim(n number) RETURN number AS divisor number := 2; BEGIN while divisor <= n/2 loop if mod(n, divisor) = 0 then return 0; end if; divisor := divisor + 1; end loop; return 1; END; . /
În urma executării acelor instrucțiuni, se va produce următorul output:SET SERVEROUTPUT ON; BEGIN dbms_output.put_line(prim(6)); dbms_output.put_line(prim(7)); dbms_output.put_line(prim(9)); END; . /
0 1 0