cursbdoo idd

79
BAZE DE DATE ORIENTATE OBIECT LIMBAJUL PL/SQL Cracteristici: Suport pentru SQL Suport pentru programarea orientata obiect Performanta buna Portabilitate Productivitate mare Integrarea cu Oracle Limbajul PL/SQL- Exemple de tabele ce vor fi utilizate in continuare. CREATE TABLE dept(deptno NUMBER(2) NOT NULL, dname VARCHAR2(14),loc VARCHAR2(13)) CREATE TABLE emp(empno NUMBER(4) NOT NULL,ename VARCHAR2(10),job VARCHAR2(9),mgr NUMBER(4),hiredate DATE,sal NUMBER(7,2),comm NUMBER(7,2),deptno NUMBER(2)) Limbajul PL/SQL- Elemente de bază Caractere de bază: A..Z, a..z 0..9 tab, space, CR Simboli()+-*/<>=!~;:.’@%,”#$&_{}?[] Nu este case senzitive Limbajul PL/SQL- Elemente de bază Unitati lexicale: - delimitatori - identificatori - literali - comentarii Unitatile lexicale sunt separate prin spatii Limbajul PL/SQL- Elemente de bază Delimitatori: simboli simpli: +,*,%,etc. simboli compusi: **, <>,!=,~=,<=,>=,:=,=> .., ||,<<,>>,--,?*,*/ Identificatori: Formati din litere, numerale, $, _,semne numerice Limbajul PL/SQL- Elemente de bază Cuvinte rezervate: DECLARE, BEGIN , END, BOOLEAN, etc. Identificatori predefiniti: INVALID_NUMBER, etc. Identificatori cu “

Upload: ionut-fiorosu

Post on 25-Nov-2015

38 views

Category:

Documents


5 download

DESCRIPTION

Cursbdoo Idd

TRANSCRIPT

  • BAZE DE DATE ORIENTATE OBIECT LIMBAJUL PL/SQL Cracteristici: Suport pentru SQL Suport pentru programarea orientata obiect Performanta buna Portabilitate Productivitate mare Integrarea cu Oracle Limbajul PL/SQL- Exemple de tabele ce vor fi utilizate in continuare. CREATE TABLE dept(deptno NUMBER(2) NOT NULL, dname VARCHAR2(14),loc VARCHAR2(13)) CREATE TABLE emp(empno NUMBER(4) NOT NULL,ename VARCHAR2(10),job VARCHAR2(9),mgr NUMBER(4),hiredate DATE,sal NUMBER(7,2),comm NUMBER(7,2),deptno NUMBER(2)) Limbajul PL/SQL- Elemente de baz Caractere de baz: A..Z, a..z 0..9 tab, space, CR Simboli()+-*/=!~;:.@%,#$&_{}?[] Nu este case senzitive Limbajul PL/SQL- Elemente de baz Unitati lexicale: - delimitatori - identificatori - literali - comentarii Unitatile lexicale sunt separate prin spatii Limbajul PL/SQL- Elemente de baz Delimitatori: simboli simpli: +,*,%,etc. simboli compusi: **, ,!=,~=,=,:=,=> .., ||,,--,?*,*/ Identificatori: Formati din litere, numerale, $, _,semne numerice Limbajul PL/SQL- Elemente de baz Cuvinte rezervate: DECLARE, BEGIN , END, BOOLEAN, etc. Identificatori predefiniti: INVALID_NUMBER, etc. Identificatori cu

  • sir caractere Ex.TYPE este cuvint rezervat, Utilizarea in forma: SELECT numar, type, .-produce eroare Utilizarea in forma: SELECT numar,TYPE,-este corecta Limbajul PL/SQL- Elemente de baz Literali numerici: -sir de cifre, eventual precedat de +, sau -notatia stiintifica cu E sau e -operatorul ** Literali de tip caracter: c Literali de tip sir: sir de caractere Literalii de tip sir, cu exceptia sirului nul au tipul de date CHAR. Limbajul PL/SQL- Elemente de baz Literali booleeni: TRUE, FALSE, NULL Comentarii: -- */comentarii . /* Limbajul PL/SQL- Elemente de baz Tipuri de date: - Scalare definite cu urmatoarele cuvinte rezervate: BINARY_INTEGER NATURALN DEC NUMBER DECIMAL NUMERIC DOUBLE PRECISION PLS_INTEGER FLOAT POSITIVE INT POSITIVEN INTEGER REAL NATURAL SIGNTYPE CHAR ROWID CHARACTER STRING LONG VARCHAR LONG RAW VARCHAR2 NCHAR BOOLEAN NVARCHAR2 DATE RAW Limbajul PL/SQL- Elemente de baz Tipuri compuse: Tipuri LOB: RECORD BFILE

  • TABLE BLOB VARRAY CLOB Tipuri referin: NCLOB REF CURSOR REF tip-obiect Limbajul PL/SQL- Elemente de baz BINARY_INTEGER :[-2**31,2**31-1] Subtipuri ale lui BINARY_INTEGER: -SUBTYPE numesubtip IS tip-baza Subtipuri predefinite: -NATURAL -NATURALN -POSITIVE -POSITIVEN -SIGNTYPE Limbajul PL/SQL- Elemente de baz NUMBER[(precizie,nrzec)], 1.0E-130.. 9.99E125 NUMBER(precizie) max precizie 38 nrzec [-84,127] Subtipuri ale lui NUMBER: -DEC INTEGER -DECIMAL INT -NUMERIC DOUBLE PRECISION -FLOAT REAL -SMALLINT PLS_INTEGER Limbajul PL/SQL- Elemente de baz Tipuri caracter: - CHAR[(lungimef)], lungimef
  • - numar linie in bloc de date VARCHAR2(lungime) lungime
  • -SUBTYPE numesubtip IS variabila%TYPE; -SUBTYPE numesubtip IS cursor%ROWTYPE Limbajul PL/SQL- Elemente de baz DECLARE SUBTYPE EmpDate IS DATE; SUBTYPE alfa IS NATURAL; TYPE Nume1 IS TABLE OF VARCHAR2(15); SUBTYPE beta IS nume1; TYPE timprec IS RECORD( minute INTEGER, ore INTEGER); SUBTYPE timp IS timprec; Limbajul PL/SQL- Elemente de baz SUBTYPE numeid IS emp.empno%TYPE; CURSOR c1 IS SELECT * FROM dept; SUBTYPE deptlinie IS c1%ROWTYPE; In definitia unui subtip nu se poate specifica restrictie pe tipul de baza. SUBTYPE gama1 IS NUMBER(6,2); SUBTYPE gama2 IS CHAR(1); SUBTYPE gama3 IS VARCHAR(10); Limbajul PL/SQL- Elemente de baz Definirea de restrictii in mod indirect: DECLARE var1 VARCHAR2(10); SUBTYPE vartip IS var1%TYPE; Folosirea subtipurilor: DECLARE SUBTYPE contor IS NATURAL; nr1 contor; nr2 contor; Limbajul PL/SQL- Elemente de baz DECLARE SUBTYPE alfatip IS NUMBER; total alfatip(8,2); DECLARE temp NUMBER(2,0); SUBTYPE alfa IS temp%TYPE; x alfa; y alfa; BEGIN x:=100; -- eroare Limbajul PL/SQL- Elemente de baz

  • Compatibilitatea tipurilor: Un subtip nerestrins este interschimbabil cu tipul de baz. DECLARE SUBTYPE tipx IS NUMBER; cant NUMBER(8,2); total tipx; BEGIN total:=cant; Limbajul PL/SQL- Elemente de baz Subtipuri diferite sunt interschimbabile dac au acelasi tip de baz. DECLARE SUBTYPE tip1 IS BOOLEAN; SUBTYPE tip2 IS BOOLEAN; alfa tip1; beta tip2; BEGIN alfa:=beta; Limbajul PL/SQL- Elemente de baz Subtipuri diferite sunt interschimbabile dac tipurile lor de baz sunt in aceeasi familie. DECLARE SUBTYPE tip1 IS CHAR; SUBTYPE tip2 IS VARCHAR2; alfa tip1; beta tip2; BEGIN alfa:=beta; Limbajul PL/SQL- Elemente de baz Conversia tipurilor de date. 1. Conversia explicit: TO_DATE de la CHAR la DATE TO_NUMBER de la CHAR la NUMBER TO_CHAR de la DATE sau NUMBER la CHAR 2. Conversia implicit: DECLARE timp1 char(5); timp2 char(5); Limbajul PL/SQL- Elemente de baz diferenta number(5); BEGIN SELECT TO_CHAR(SYSDATE,SSSSS) INTO timp1 FROM sys.dual; secventa comenzi SELECT TO_CHAR(SYSDATE,SSSSS) INTO timp2 FROM sys.dual; diferenta:=timp2-timp1; INSERT INTO rezult VALUES (diferenta,..)

  • END; Limbajul PL/SQL- Elemente de baz. Conversii implicite posibile: ________________________________________________________________ bin_int char date long number pls_int raw rowid varchar2 bin_int * * * * * Char * * * * Date * * * Long * * * Number * * * * * Pls_int * * * * * Raw * * * Rowid * * Varchar2 * * * * * * * * ______________________________________________________ Limbajul PL/SQL- Elemente de baz Ex. 02-JUL-99 -> DATE xyDTRA -> DATE ? 12345ABCD -> NUMBER ? RAW sau LONG RAW in CHAR sau VARCHAR2. Coloana->variabil octet-> 2 caractere cd, unde c si d sunt cifre hexazecimale. CHAR sau VARCHAR2 in RAW sau LONG RAW. Variabil->coloan Limbajul PL/SQL- Elemente de baz Declararea variabilelor i constantelor: identificator tip [:=expresie]; identificator CONSTANT tip:=expresie; variabile neinitializate NULL - Cuvintul DEFAULT ptr.iniializarea variabilelor alfa BOOLEAN DEFAULT FALSE; - NOT NULL in declaraii urmat de iniializare. Limbajul PL/SQL- Elemente de baz Folosirea %TYPE: Specific tipul de dat al variabilelor sau coloanelor. NOT NULL nu se transmite. DECLARE nume emp.empno%TYPE BEGIN nume:=NULL; Limbajul PL/SQL- Elemente de baz Utilizare %ROWTYPE: Tip de inregistrare o linie tabel sau view DECLARE emp_rec emp%TYPE; CURSOR c1 IS SELECT deptno,dname,loc FROM dept; dept_rec c1%ROWTYPE; Coloanele din tip inregistrare au acelai tip cu cmpurile din nregistrare. SELECT * INTO emp_rec FROM emp where

  • Limbajul PL/SQL- Elemente de baz Valorile coloanelor returnate de SELECT -> cmpurile nregistrrii. Referina la un cmp se face prin: inregistrare.cmp Asignare agregat: Declaraia cu%ROWTYPE nu are clauz de iniializare. DECLARE dept_rec1 dept%ROWTYPE; dept_rec2 dept%ROWTYPE; CURSOR c1 IS SELECT deptno,dname,loc FROM dept; Limbajul PL/SQL- Elemente de baz dept_rec3 c1%ROWTYPE; BEGIN dept_rec1:=dept_rec2; dept_rec2:=dept_rec3; --incorect Putem asigna o lista de valori la o inregistrare cu SELECT sau FETCH: SELECT deptno,dname,loc INTO dept_rec1 FROM dept WHERE deptno=10; Limbajul PL/SQL- Elemente de baz Nu putem asigna o lista de valori pentru o asignare: Numeinregistrare:=(val1,val2,)incorect Nu putem folosi inregistrarile pentru inserare sau actualizare: INSERT INTO dept VALUES (numeinregistrare)incorect PL/SQL nu permite referine forward Nu putem defini acelai tip de data pentru mai multe variabile. Limbajul PL/SQL- Elemente de baz Precedena operatorilor(in ordinea descrescatoare a precedentei): **, NOT +, - *, / +, -, || =, !=,, = IS NULL, LIKE, BETWEEN, IN AND OR Limbajul PL/SQL- Elemente de baz Funcia NVL NVL(exp1,exp2) returneaz exp2 daca exp1=NULL altfel exp1 Funcia REPLACE REPLACE(sir1,sir2,sir3) returneaz: sir1 dac sir2 este NULL, indiferent de sir3 sir1 din care se elimin toate aparitiile lui sir2, cind sir2 nu e NULL si sir3 nu e NULL sir1 cind sir2 este NOT NULL si sir3 este NULL

  • Limbajul PL/SQL- Elemente de baz Funcii Built-in 1) privitoare la erori: SQLCODE, SQLERRM 2) privitoare la numere: ABS COSH ROUND ACOS EXP SIGN ASIN FLOOR SIN ATAN LN SINH ATAN2 LOG SQRT CEIL MOD TAN COS POWER TANH TRUNC Limbajul PL/SQL- Elemente de baz 3)Funcii caracter: ASCII LPAD RTRIM CHR LTRIM SOUNDEX CONCAT NLS_INITCAP SUBSTR INITCAP NLS_LOWER SUBSTRB INSTR NLS_UPPER TRANSLATE INSTRB NLSSORT UPPER LENGTH REPLACE LOWER RPAD Limbajul PL/SQL- Elemente de baz 4)Conversii: CHARTOROWID TO_CHAR CONVERT TO_DATE HEXTORAW TO_LABEL NLS_CHARSET_ID TO_MULTI_BYTE NLS_CHARSET_NAME TO_NUMBER RAWTOHEX TO_SINGLE_BYTE ROWIDTOCHAR Limbajul PL/SQL- Elemente de baz 5) Dat calendaristic: ADD_MONTHS LAST_DAY MONTHS_BETWEEN NEW_TIME NEXT_DAY ROUND SYSDATE TRUNC Limbajul PL/SQL- Elemente de baz 6) Diverse: DECODE LEAST_UB DUMP NVL GREATEST UID GREATEST_LB USER

  • LEAST USERENV VSIZE Limbajul PL/SQL- Structuri de control IF-THEN IF conditie THEN sir de comenzi; END IF; IF-THEN-ELSE: IF conditie THEN sir de comenzi1; ELSE sir de comenzi2; END IF; Limbajul PL/SQL- Structuri de control IF-THEN-ELSIF IF conditi1 THEN sir de comenzi1; ELSIF conditie2 THEN sir de comenzi2; ELSE sir de comenzi3; END IF; Limbajul PL/SQL- Structuri de control LOOP LOOP sir de comenzi; END LOOP; EXIT si EXIT-WHEN LOOP IF conditie THEN EXIT; END IF END LOOP; Limbajul PL/SQL- Structuri de control LOOP FETCH c1 INTO EXIT WHEN c1%NOTFOUND; . END LOOP; CLOSE c1; IF c1%NOTFOUND THEN

  • EXIT; END IF; Limbajul PL/SQL- Structuri de control Etichete LOOP LOOP sir de comenzi; END LOOP [nume eticheta]; LOOP Limbajul PL/SQL- Structuri de control EXIT e1 WHEN conditie; END LOOP e2; .. END LOOP e1; WHILE-LOOP WHILE conditie LOOP sir de comenzi; END LOOP; Limbajul PL/SQL- Structuri de control FOR-LOOP FOR contor IN [REVERSE] min..max LOOP sir de comenzi; END LOOP; In interior contor este referit ca o constant. min, max pot fi :literali, variabile, expresii evaluate ca intregi. STEP h - IF MOD(contor,h)=0 THEN contor nu trebuie definit. Limbajul PL/SQL- Structuri de control Ex. DECLARE contor integer; BEGIN FOR contor IN 1.. 20 LOOP . IF contor >8 THEN --refer contor din FOR END IF; END LOOP; END; Limbajul PL/SQL- Structuri de control

  • Pentru a referi variabila global contor vom da: DECLARE contor INTEGER; BEGIN FOR contor IN 1.20 LOOP IF et1.contor > 8 THEN END IF; END LOOP; END et1; Acelai lucru i pentru FOR imbricai. Limbajul PL/SQL- Structuri de control FOR pas IN 1..20 LOOP FOR pas IN 1..5 LOOP . IF et1.pas >=12 THEN END IF; END LOOP; END LOOP et1; Limbajul PL/SQL- Structuri de control Folosirea lui EXIT: DECLARE emp_rec emp%ROWTYPE; CURSOR c1 IS SELECT deptno,dname,loc FROM dept; numarrec integer :=0; BEGIN SELECT COUNT(*) INTO numarrec FROM c1; FOR j IN 1..numarrec LOOP Limbajul PL/SQL- Structuri de control FETCH c1 INTO emp_rec; EXIT WHEN c1%NOTFOUND; . END LOOP; END; Limbajul PL/SQL- Structuri de control FOR i IN 1..10 LOOP FOR j IN 1..5 LOOP FETCH c1 INTO emp_rec; EXIT et1 WHEN c1%NOTFOUND; .

  • END LOOP; END LOOP et1; --aici trece controlul Limbajul PL/SQL- Structuri de control Instruciunile GOTO i NULL. -GOTO eticheta Dup eticheta trebuie sa fie o instruciune executabil END LOOP nu este executabil. Folosim NULL; GOTO nu poate face saltul in interiorul unui IF, instruciune LOOP sau subbloc. GOTO nu poate face saltul de la o clauz IF la alta clauz a aceluai IF. GOTO nu poate face saltul dintr-un bloc de exceptii n blocul curent. Limbajul PL/SQL- Colecii i nregistrri Colecie=grup ordonat de elemente de acelai tip. Un element are indice unic n colecie. Dou tipuri de colecii: tabele nested i tablouri de dimensiune variabil-varrays. Coleciile pot memora instane ale unui tip obiect. Coleciile pot fi atribute ale unui tip obiect. Coleciile pot fi folosite ca parametri. Tabelele nested pot fi interpretate ca tabele cu o singur coloan. Limbajul PL/SQL- Colecii i nregistrri Arrays au un numr maxim de elemente. Tabelele nested sunt nemrginite. Arrays trebuie sa fie dense, fr spaii ntre elemente. Nu se pot terge elemente individuale din array. Iniial tabelele nested sunt dense. Cu procedura DELETE se pot terge elemente in tabele nested. Cu procedura NEXT operm asupra indicilor. Limbajul PL/SQL- Colecii i nregistrri Diferene ntre tabele nested i tabele index-by. - Tipuri permise pentru tabele index-by dar nu pentru tabele nested: Binary_integer, Boolean, Long,Long Raw, Natural, NaturalN, Pls_integer, Positive, PositiveN, Signtype, String. -Tabelele index-by sunt definite cu clauza INDEX BY BINARY_INTEGER. -O tabel nested neiniializat este NULL, ns o -tabel index-by neiniializat este vid. Limbajul PL/SQL- Colecii i nregistrri

  • Pentru tabele nested indicele 1..2*31-1 Pentru tabele index-by indicele 2**31.. 2**31-1 Pentru extinderea unei tabele nested folosim procedura EXTEND, pentru tabele index-by specificm indici mai mari. Procedurile EXTEND i TRIM se pot aplica numai la tabele nested. Limbajul PL/SQL- Colecii i nregistrri Definirea i declararea coleciilor TYPE numetip IS TABLE OF tipelement [NOT NULL] TYPE numetip IS{VARRAY|VARYING ARRAY}(max) OF tipelement [NOT NULL] Tipelement este orice tip PL/SQL cu excepia tipurilor: BINARY_INTEGER NCLOB SIGNTYPE BOOLEAN NVARCHAR2 STRING LONG PLS_INTEGER TABLE LONG RAW POSITIVE VARRAY NATURAL POSITIVEN NATURALN REF CURSOR NCHAR Tipuri obiect cu atribute TABLE sau VARRAY Limbajul PL/SQL- Colecii i nregistrri Dac tipelement este tip RECORD, atunci un cmp din nregistrare trebuie s fie tip scalar sau tip obiect. Definirea tipului tabele index-by: TYPE numetip IS TABLE OF tipelement [NOT NULL] INDEXED BY BINARY_INTEGER; Tipuri permise pentru tabele index-by: BINARY_INTEGER NATURAL POSITIVEN BOOLEAN NATURALN SIGNTYPE LONG PLS_INTEGER STRING LONG RAW POSITIVE Limbajul PL/SQL- Colecii i nregistrri Tabelele index-by initial nu sunt dense. Ex. DECLARE TYPE tip1 IS TABLE OF emp%ROWTYPE INDEX BY BINARY_INTEGER; emp_tab_by tip1; BEGIN SELECT * INTO emp_tab_by(100) FROM emp WHERE empno=100; END; Limbajul PL/SQL- Colecii i nregistrri Folosim %TYPE ce d tipul unei variabile sau coloan a unei tabele.

  • Folosim %ROWTYPE ce d tipul de linie a unui cursor sau tabel. DECLARE TYPE lista_emp IS TABLE OF emp.ename%TYPE; CURSOR c1 IS SELECT * FROM dept; TYPE tip_dept IS VARRAY(15) OF c1%ROWTYPE; BEGIN . Limbajul PL/SQL- Colecii i nregistrri DECLARE TYPE inreg1 IS RECORD ( nume VARCHAR2(20), nrcopii NATURAL); TYPE persoane IS VARRAY(100) OF inreg1; BEGIN Limbajul PL/SQL- Colecii i nregistrri Declararea coleciilor identificator numetip; Exemplu: CREATE TYPE lista_cursuri AS TABLE OF VARCHAR2(10) / CREATE TYPE Student AS OBJECT ( marca INTEGER(4), nume VARCHAR2(15), cursuri lista_cursuri) / Limbajul PL/SQL- Colecii i nregistrri CREATE TYPE Proiect AS OBJECT( nr_proiect NUMBER(2), cost NUMBER(7,2)) / CREATE TYPE lista_proiecte AS VARRAY(20) OF proiect / CREATE TABLE depart2 ( id_dept NUMBER(2), nume VARCHAR2(20), proiecte lista_proiecte) / Limbajul PL/SQL- Colecii i nregistrri Iniializarea i referirea coleciilor. -Dup declarare colecia este cu valoarea NULL. -Pentru iniializare folosim constructor. Ex. DECLARE cursuri_felea lista_cursuri; BEGIN cursuri_felea:=lista_cursuri(Baze de date I,

  • Baze de date II, Baze de date orientate obiect); sau cursuri_felea lista_cursuri:=lista_cursuri(Baze de date I,); Putem utiliza NULL. Limbajul PL/SQL- Colecii i nregistrri Ex. DECLARE proiecte_info lista_proiecte; BEGIN proiecte_info := lista_proiecte(proiect(1,1000), proiect(2,1500),proiect(3,1600)); Constructor fr argumente d colecie vid dar NOT NULL. Ex. DECLARE TYPE clientela IS VARRAY(50) OF Customer; clientela_felea clientele:=clientela(); --tablou vid BEGIN IF clientela_felea IS NOT NULL THEN -TRUE Limbajul PL/SQL- Colecii i nregistrri -Constructorii sunt permii in clauze ca VALUES,SET, componente din SELECT Ex. BEGIN INSERT INTO depart2 VALUES( 1,info,lista_proiecte(proiect(20,1000), proiect(30,1400),proiect(40,12000))); Referirea coleciilor nume_colectie(indice) indice: 1..2147483647(2**31-1) tabele nested 1..maximum - varray Limbajul PL/SQL- Colecii i nregistrri Ex. DECLARE TYPE filme IS TABLE OF VARCHAR2(30); filme_rom filme:=filme(Mihai Viteazul,Rascoala,); i BINARY_INTEGER; x VARCHAR2(30); BEGIN i:=1; IF filme_rom(i)=xxxx THEN nume_procedura(filme_rom(i)); x:=nume_functie(par1,par2,,parn)(i) Limbajul PL/SQL- Colecii i nregistrri Asignarea coleciilor: INSERT, UPDATE, FETCH, SELECT, comanda de asignare sau chemare de subprogram. Ex. DECLARE TYPE clientela1 IS VARRAY(50) OF Customer; TYPE clientela2 IS VARRAY(50) OF Customer; clientela_soc1 clientela1:=clientela1();

  • clientela_soc2 clientela1:=clientela1(); clientela_soc3 clientela2:=clientela2(); BEGIN clientela_soc2:=clientela_soc1; clientela_soc3:=clientela_soc2; -- incorect Limbajul PL/SQL- Colecii i nregistrri Ex. DECLARE TYPE clientela iS TABLE OF Customer; grup1 clientela:=clientela(); grup2 clientela; -- NULL grup3 clientela:=clientela(); BEGIN IF grup1 IS NULL THEN --FALSE grup1:=grup2; IF grup2 IS NULL THEN -- TRUE grup2:=grup3; If grup2 IS NULL THEN --FALSE Limbajul PL/SQL- Colecii i nregistrri Asignarea elementelor coleciilor nume_colectie(indice):=expresie; Dac indice este NULL sau neconvertibil la un intreg, atunci avem excepia VALUE_ERROR Dac colecia este NULL, atunci avem excepia COLLECTION_IS_NULL Ex. DECLARE TYPE lista IS TABLE OF INTEGER; nume1 lista:=lista(100,200,300); nume2 lista; Limbajul PL/SQL- Colecii i nregistrri BEGIN nume1(2):=150; nume1(1):=nume1(2); nume1(3):=ASCII(G); nume1(H):=400; -- excepie VALUE_ERROR nume2(2):= 145; -- excepie COLLECTION_IS_NULL - Coleciile nu pot fi comparate cu = sau -Coleciile nu pot apare n DISTINCT, GROUP BY, ORDER Limbajul PL/SQL- Colecii i nregistrri CREATE TYPE curs AS OBJECT ( nr_curs NUMBER(5), titlu VARCHAR(30), credite NUMBER(1));

  • CREATE TYPE list_cursuri AS TABLE OF curs; CREATE TABLE depart3 ( nume VARCHAR2(25), director VARCHAR2(30), cursuri list_cursuri) NESTED TABLE cursuri STORE AS Tcursuri; Limbajul PL/SQL- Colecii i nregistrri BEGIN INSERT INTO depart3 VALUES (INFO,POPESCU,list_cursuri(curs(1,ALGORITMI,6),curs(2,BAZE DE DATE,6))); DECLARE noua_lista list_cursuri:= list_cursuri(curs(10,Programare,6), curs(20,Logica,6)); BEGIN UPDATE depart3 SET cursuri=noua_list Limbajul PL/SQL- Colecii i nregistrri Ex. DECLARE cursuri_info list_cursuri; BEGIN SELECT cursuri INTO cursuri_info FROM depart3 WHERE nume= INFO; Limbajul PL/SQL- Colecii i nregistrri Prelucrarea elementelor individuale - Pentru elementele unei tabele nested THE - Pentru elementele unui VARRAY proceduri Ex. BEGIN INSERT INTO THE(SELECT cursuri FROM depart3 WHERE nume=INFO) VALUES(22,Teoria algoritmilor,6); UPDATE THE(SELECT cursuri FROM depart3 WHERE nume=INFO) SET credite=credite+1 WHERE nr_curs IN(1,22);

  • Limbajul PL/SQL- Colecii i nregistrri DECLARE nr_cursv NUMBER(5); titluv VARCHAR2(30); BEGIN SELECT nr_curs,titlu INTO nr_cursv,titluv FROM THE(SELECT cursuri FROM depart3 WHERE nume=INFO) WHERE nr_curs=1; DELETE THE(SELECT cursuri FROM depart3 WHERE nume=INFO) WHERE titlu=BD2; Limbajul PL/SQL- Colecii i nregistrri CREATE PROCEDURE adauga_proiect( nr_dept IN NUMBER; proiect_nou IN Proiect; pozitie IN NUMBER) AS proiecte_dept lista_proiecte; BEGIN SELECT proiecte INTO proiecte_dept FROM depart2 WHERE id_dept=nr_dept FOR UPDATE OF proiecte; /* Returneaza lista de proiecte in variabila proiecte_dept*/ proiecte_dept.EXTENDED; /*Extinde tabloul pentru a face loc noului element*/ Limbajul PL/SQL- Colecii i nregistrri FOR i IN REVERSE pozitie..proiecte_dept.LAST1 LOOP proiecte_dept(i+1):=proiecte_dept(i); END LOOP; /* Deplaseaza elementele tabloului spre dreapta incepind cu indicele pozitie */ proiecte_dept(pozitie):= proiect_nou; /* Insereaza noul proiect */ UPDATE depart2 SET proiecte= proiecte_dept WHERE id_dept= nr_dept; /* Actualizeaza tabela depart2 */ END adauga_proiect; Limbajul PL/SQL- Colecii i nregistrri CREATE PROCEDURE actualiz_proiect( nr_dept IN NUMBER; nr_proiect IN NUMBER; cost_nou IN NUMBER DEFAULT NULL)AS proiecte_dept lista_proiecte;

  • BEGIN SELECT proiecte INTO proiecte_dept FROM depart2 WHERE id_dept=nr_dept FOR UPDATE OF proiecte; FOR i IN proiecte_dept.FIRST..proiecte_dept.LAST LOOP IF proiecte_dept(i).nr_proiect=nr_proiect THEN Limbajul PL/SQL- Colecii i nregistrri IF cost_nou IS NOT NULL THEN proiecte_dept(i).cost:=cost_nou; END IF; EXIT; END IF; END LOOP; UPDATE depart2 SET proiecte=proiecte_dept WHERE id_dept=nr_dept; END actualiz_proiect; Limbajul PL/SQL- Colecii i nregistrri Ex. Apelul procedurii actualiz_proiect DECLARE nr_deptv NUMBER :=10; nr_proiectv NUMBER :=100; cost_nouv NUMBER :=2000; BEGIN . acualiz_proiect(nr_deptv,nr_proiectv,cost_nouv); acualiz_proiect(nr_deptv,nr_proiectv,cost_nou=>1700); Limbajul PL/SQL- Colecii i nregistrri Metode ale coleciilor: - EXISTS - COUNT - LIMIT - FIRST, LAST - PRIOR, NEXT - EXTEND - TRIM - DELETE Apelul unei metode: nume_colectie.nume_metoda[(lista_de_parametri)]

  • Limbajul PL/SQL- Colecii i nregistrri Numai EXISTS se poate aplica la colecii nule. Dac o alt metod se aplic la o colecie nul, atunci se apeleaz COLLECTION_IS_NULL. -EXISTS(n) , n este intreg. Ex. IF cursuri.EXISTS(i) THEN cursuri(i):= -COUNT returneaz nr. de elemente ale coleciei. -Pentru VARRAY COUNT=LAST -LIMIT pentru VARRAY d numrul maxim de elemente, pentru tabele nested are valoarea NULL. -FIRST, LAST primul i ultimul indice din colecie. Pentru VARRAY FIRST =1, LAST=COUNT Limbajul PL/SQL- Colecii i nregistrri PRIOR(n) indicele ce precede indicele n. NEXT(n) - indicele ce succede indicele n. Dac elementul n nu are predecesor, PRIOR(n) este NULL. Dac elementul n nu are succesor, NEXT(n) este NULL. Ex. Traversarea unei tabele nested: i:=cursuri.FIRST; WHILE i IS NOT NULL LOOP .prelucreaz curs(i).. i:=cursuri.NEXT(i); END LOOP; La traversare PRIOR i NEXT ignor elementele terse Limbajul PL/SQL- Colecii i nregistrri EXTEND mrete dimensiunea coleciei. - EXTEND adaug un element null. - EXTEND(n) - adaug n elemente null. - EXTEND(n,i) - adaug n copii ale elementului i. Nu se poate folosi EXTEND pentru a initializa o colecie nul. Dac impunem NOT NULL pentru tipul TABLE sau VARRAY, atunci nu trebuie folosit EXTEND de primele 2 tipuri. DECLARE TYPE lista_cursuri1 IS TABLE OF VARCHAR2(10); cursuri1 lista_cursuri1; Limbajul PL/SQL- Colecii i nregistrri BEGIN cursuri1:=lista_cursuri1(Algoritmi,Baze de date I,Limbaje formale,Tehnici de compilare); cursuri1.DELETE(3);

  • cursuri1.EXTEND; - adaug un element null. cursuri1(5):=Programare obiect; END; Dac se utilizeaz cursuri1(i), unde i>5, atunci se iniiaz excepia SUBSCRIPT_BEYOND_COUNT Elementele terse sunt socotite n calculul dimensiunii. COUNT pentru tabele nested returneaz nr. de elemente neterse Limbajul PL/SQL- Colecii i nregistrri TRIM are dou forme: - TRIM ndeprteaz un element de la sfritul coleciei - TRIM(n) ndeprteaz n elemente Dac n>COUNT atunci se lanseaz excepia SUBSCRIPT_BEYOND_COUNT TRIM consider elementele terse. DELETE are trei forme: - DELETE terge toate elementele unei colecii, - DELETE(n) terge al n-lea element din tabel nested, - DELETE(m,n) terge toate elementele cu indici m..n Dac m>n sau m is null sau n is null, atunci DELETE nu terge nimic. Limbajul PL/SQL- Colecii i nregistrri Varrays sunt dense, deci nu folosim proc. DELETE PL/SQL ine o eviden a elementelor terse. O tabel nested sau un varray poate fi parametru formal al unei proceduri sau funcii. Evitarea excepiilor. - Referirea la un element inexistent produce o excepie predefinit. Ex. DECLARE TYPE numlist IS TABLE OF NUMBER; nums numlist; -- colecie atomic nul. BEGIN nums(1):=10; -- excepia: COLLECTION_IS_NULL nums:=numlist(15,20); --iniializarea tabelei Limbajul PL/SQL- Colecii i nregistrri nums(NULL):=5; -- VALUE_ERROR nums(0):= 15; --SUBSCRIPT_OUTSIDE_LIMIT nums(3):=40; --SUBSCRIPT_BEYOND_COUNT nums.DELETE(1); - terge elementul 1 IF nums(1)= 15 THEN --NO_DATA_FOUND Excepie Apare cnd.. COLLECTION_is_NULL colecia este atomic nul NO_DATA_FOUND indicele specific un element ters SUBSCRIPT_BEYOND_FOUND indicele depete numrul de elemente din colecie. SUBSCRIPT_OUTSIDE_LIMIT indice n afara domeniului legal. VALUE_ERROR indice null sau neconvertibil la un intreg Limbajul PL/SQL- Inregistrri

  • Definirea: TYPE tip_inreg IS RECORD (cimp1,cimp2,); cimpi are forma general: numecimp tip [[NOT NULL] {:=|DEFAULT} expresie] Tipul inregistrare nu poate fi creat si memorat in baza de date. Putem folosi %TYPE si %ROWTYPE pentru a specifica tipul cimpurilor. Tipul obiect nu poate avea ca atribute tipul RECORD. Inregistrarile pot contine obiecte, colectii si alte inregistrari, numite inregistrari nested. Limbajul PL/SQL- Inregistrri DECLARE TYPE TimeRec IS RECORD ( seconds SMALLINT, minutes SMALLINT, hours SMALLINT); TYPE FlightRec IS RECORD ( flight_no INTEGER, plane_id VARCHAR2(10), captain Employee, --obiect passengers PassengerList, --varray depart_time TimeRec, airport_code VARCHAR2(10)); Limbajul PL/SQL- Inregistrri Declararea: var_inregistrare tip_inregistrare; -var_inregistrare poate fi parametru formal pentru proceduri sau funcii. Iniializarea i referirea nregistrrilor: - numecimp tip [[NOT NULL] {:=|DEFAULT} expresie] Referirea: var_inregistrare.numecimp Dac o funcie returneaz o inregistrare, atunci referirea unui cimp se face: nume_functie(lista_parametri).numecimp Limbajul PL/SQL- Inregistrri DECLARE TYPE EmpRec IS RECORD ( emp_id NUMBER(4), job_title CHAR(14), salary REAL(7,2)); middle_sal REAL; FUNCTION F1(n INTEGER) RETURN EmpRec Is emp_info EmpRec; BEGIN RETURN emp_info;

  • END; Limbajul PL/SQL- Inregistrri BEGIN middle_sal:=F1(10).salary; END; Folosim notaia . pentru referirea la cimpuri nested i la obiecte memorate ntr-un cimp. Asignarea nregistrrilor: var_inregistrare_numecimp:=expresie; ex. emp_info.name :=UPPER(emp_info.name); var_inreg1:=var_inreg2; -- acelai tip; Limbajul PL/SQL- Inregistrri DECLARE TYPE DeptRec IS RECORD ( dept_num NUMBER(2), dept_name CHAR(14), location CHAR(13)); dept1_info DeptRec; dept2_info dept%ROWTYPE; BEGIN SELECT * INTO dept2_info FROM dept WHERE deptno=10; dept1_info:=dept2_info; sau SELECT * INTO dept1_info FROM dept WHERE deptno=10; Limbajul PL/SQL- Inregistrri - Nu putem folosi var_inregistrare n INSERT. - Nu putem folosi: var_inregistrare:=(v1,v2,); - Nu putem compara nregistrrile, nici cu IS NULL sau IS NOT NULL. Prelucrarea nregistrrilor: SQL> CREATE TYPE Passenger AS OBJECT ( flight_no NUMBER(3), name VARCHAR2(20), seat CHAR(5)); SQL> CREATE TYPE PassengerList AS VARRAY(300) OF Passenger; SQL> CREATE TABLE flights ( Limbajul PL/SQL- Inregistrri flight_no NUMBER(3), gate CHAR(5), departure CHAR(15), arrival CHAR(15), passengers PassengerList); BEGIN INSERT INTO flights

  • VALUES(100,L25,BUC 6:50PM,IASI 7.50PM, PassengerList(Passenger(100,Popescu,3A), Passenger(100,Ionescu,4A), Passenger(100,Eftimie,5A))); Ex.Program pentru citirea tabelei flights folosind o var de tip inregistrare. Limbajul PL/SQL- Interactiunea cu Oracle Functii SQL: PL/SQL permite utilizarea functiilor SQL, inclusiv AVG,MIN, MAX,COUNT, SUM, STDDEV, VARIANCE - nume_functie ([ALL|DISTINCT] expresie) - functiile de grupare ignora NULL,cu exceptia lui COUNT(*) Pseudocoloane SQL: CURRVAL, LEVEL, NEXTVAL, ROWID, ROWNUM - Se folosesc in instr.SQL, nu in cele procedurale. - CURRVAL si NEXTVAL: -O secventa este o schema ce genereaza numere secventiale. Limbajul PL/SQL- Interactiunea cu Oracle CREATE SEQUENCE nume_secv INCREMENT BY pas MINVALUE val1 MAXVALUE val2 NOCYCLE NOCACHE ORDER - Secventa este initializata prin NEXTVAL. - Exista tabela USER_SEQUENCES cu LAST_VAL LEVEL ROWID returneaza adresa binara a unei linii. - Tipul de data este ROWID DECLARE mid1 ROWID; mname emp.name%TYPE; mjob emp.job%TYPE; CURSOR C1 IS SELECT ename, job, ROWID FROM emp; Limbajul PL/SQL- Interactiunea cu Oracle BEGIN OPEN C1; LOOP FETCH C1 INTO mname, mjob, mid1; EXIT WHEN C1%NOTFOUND; UPDATE emp SET sal=sal*1.1 WHERE ROWID=mid1; COMMIT; END LOOP: CLOSE C1; END; Limbajul PL/SQL- Interactiunea cu Oracle ROWNUM asigneaza un numar unic fiecarei linii.

  • CURSOR C1 IS SELECT empno, sal FROM emp WHERE sal>2000 AND ROWNUM v1,): --notatie cu nume, OPEN nume cursor(v1,p2=>v2,); -- mixta Comanda pe un cursor inchis produce exceptia: INVALID_CURSOR. Limbajul PL/SQL- Interactiunea cu Oracle Cursori in pachete. CREATE PACKAGE pachet1 AS CURSOR c1 RETURN emp%ROWTYPE; /* Declaratie specificare cursor*/ . END pachet1; CREATE PACKAGE BODY pachet1 AS CURSOR c1 RETURN emp%ROWTYPE IS SELECT * FROM emp WHERE sal >4000; /*Definirea corpului cursorului */

  • END pachet1; Limbajul PL/SQL- Interactiunea cu Oracle Folosirea cursorului in Ciclu FOR DECLARE result NUMBER(5); CURSOR c1 IS SELECT cimp1,cimp2 FROM T1 WHERE marca=10; BEGIN FOR c1_rec IN c1 LOOP result:=c1_rec.cimp1+c1_rec.cimp2; INSERT INTO temp VALUES(result,NULL,NULL); END LOOP; COMMIT; END; Limbajul PL/SQL- Interactiunea cu Oracle Folosirea subinterogarilor. DECLARE bonus REAL; BEGIN FOR emp_rec IN( SELECT ampno, sal,comm FROM emp) LOOP bonus:=(emp_rec.sal*0.1)+(emp_rec.comm*0.05); INSERT INTO bonuses VALUES (emp_rec.empno,bonus); END LOOP; COMMIT; END; Limbajul PL/SQL- Interactiunea cu Oracle Cursor cu parametri. CURSOR nume_c (p1,p2,) IS SELECT FOR v1 IN nume_c(v1,v2,) LOOP . END LOOP; Variabile cursor. - Are tipul REF CURSOR - Definirea: TYPE ref_type_name IS REF CURSOR RETURN return_type; Ex. TYPE tipc1 IS REF CURSOR RETURN emp%ROWTYPE; TYPE tipc2 IS REF CURSOR; - Declararea: var_cursor tip_cursor; Limbajul PL/SQL- Interactiunea cu Oracle Variabile cursor parametri formali. TYPE tip_c IS REF CURSOR RETURN emp%ROWTYPE; PROCEDURE proc1 (par1 IN OUT tip_c) IS Controlul variabilelor cursor:OPEN-FOR, FETCH, CLOSE.

  • - OPEN nume_var_cursor |:nume_var_cursor_host} FOR SELECT; atribute: %FOUND, %NOTFOUND, %ISOPEN, %ROWCOUNT. IF NOT nume_var_cursor%ISOPEN THEN OPEN nume_var_cursor FOR SELECT * FROM emp; END IF; Limbajul PL/SQL- Interactiunea cu Oracle OPEN-FOR poate deschide aceeasi variabila cursor pentru diferite interogari. Ex. CREATE PACKAGE p1 AS TYPE tipemp IS REF CURSOR RETURN emp%ROWTYPE; PROCEDURE open_emp (emp_c IN OUT tipemp); END p1; CREATE PACKAGE BODY p1 AS PROCEDURE open_emp (emp_c IN OUT tipemp) IS BEGIN OPEN emp_c FOR SELECT * FROM emp; END open_mp; END p1; Limbajul PL/SQL- Interactiunea cu Oracle Ex. CREATE PACKAGE p2 AS TYPE generic1 IS REF CURSOR; TYPE emptip IS REF CURSOR RETURN emp%ROWTYPE; TYPE depttip IS REF CURSOR RETURN dept%ROWTYPE; END p2; CREATE PROCEDURE open_emp(emp_cv IN OUT p2.emptip) AS BEGIN OPEN emp_cv FOR SELECT * FROM emp WHERE ; END open_mp; Limbajul PL/SQL- Interactiunea cu Oracle CREATE PACKAGE p3 AS TYPE generic2 IS REF CURSOR; TYPE emptip IS REF CURSOR RETURN emp%ROWTYPE; PROCEDURE open_emp(emp_c IN OUT emptip, I IN NUMBER); END p3; CREATE PACKAGE BODY p3 AS PROCEDURE open_emp(emp_c IN OUT emptip, I IN NUMBER) IS BEGIN IF I=1 THEN

  • OPEN emp_c FOR SELECT * FROM emp WHERE comm =0; IF I=2 THEN OPEN emp_c FOR SELECT * FROM emp WHERE sal>1000; END IF; END open_emp; END p3; Limbajul PL/SQL- Interactiunea cu Oracle CREATE PACKAGE BODY p3 AS PROCEDURE open_emp(generic_cv IN OUT generic2, I IN NUMBER) IS BEGIN IF I=1 THEN OPEN generic_cv FOR SELECT * FROM emp; ELSIF I=2 THEN OPEN generic_cv FOR SELECT * FROM dept; ELSIF OPEN generic_cv FOR SELECT * FROM salgrade; END IF; END open_emp; END p3; Limbajul PL/SQL- Interactiunea cu Oracle Evitarea exceptiilor. var_cursor1:=var_cursor2; -- trebuie sa fie de acelasi tip. DECLARE TYPE TypEmp IS REF CURSOR RETURN emp%ROWTYPE; TYPE TypTmp IS REF CURSOR RETURN emp%ROWTYPE; PROCEDURE open_cursor (emp_cv IN OUT TypEmp, tmp_cv IN OUT TypTmp) IS BEGIN emp_cv:=tmp_cv; -- eroare wrong type END; Daca unul este slab tipizat, atunci cei doi nu trebuie sa aiba acelasi tip Limbajul PL/SQL- Interactiunea cu Oracle DECLARE TYPE TypEmp IS REF CURSOR RETURN emp%ROWTYPE; emp_cv1 TypEmp; emp_cv2 TypEmp; emp_rec emp%ROWTYPE; BEGIN emp_cv2:=emp_cv1; -- inutil

  • OPEN emp_cv1 FOR SELECT * FROM emp; /* emp_cv1 pointeaza catre o zona de lucru */ FETCH emp_cv1 INTO emp_rec; FETCH emp_cv2 INTO emp_rec; --exceptia INVALID_CURSOR EXCEPTION WHEN INVALID_CURSOR THEN /* facem ca emp_cv2 si emp_cv1 sa pointeze aceeasi zona de lucru*/ Limbajul PL/SQL- Interactiunea cu Oracle emp_cv2:=emp_cv1; FETCH emp_cv2 INTO emp_rec; -- returneaza a doua linie. OPEN emp_cv2 FOR SELECT * FROM emp1; /* reutilizarea zonei de lucru pentru alta interogare */ FETCH emp_cv1 INTO rep_rec; /* furnizeaza prima linie din tabela emp1 */ END; Daca parametrii actuali si cei formali nu au acelasi tip- exceptia ROWTYPE_MISMATCH emp_cv2:=emp_cv1; -- primul este un alias pentru al doilea PROCEDURE proc1 (emp_cv1 IN OUT TypEmp, emp_cv2 IN OUT TypEmp) IS emp_rec emp%ROWTYPE; Limbajul PL/SQL- Interactiunea cu Oracle BEGIN OPEN emp_cv1 FOR SELECT * FROM emp; emp_cv2:=emp_cv1; FETCH emp_cv1 INTO emp_rec; -- prima linie FETCH emp_cv2 INTO emp_rec; -- a doua linie FETCH emp_cv1 INTO emp_rec; -- a treia linie CLOSE emp_cv1; FETCH emp_cv2 INTO emp_rec; -- exceptia INVALID_CURSOR; END proc1; Aceeasi eroare apare cind un parametru apare de 2 ori intr-un apel. Procedure proc2 (emp_cv1 IN OUT TypEmp,emp_cv2 IN OUT TypEmp) IS emp_cv TypEmp; proc2(emp_cv,emp_cv); Limbajul PL/SQL- Interactiunea cu Oracle Restrictii asupra variabilelor cursor: - Nu se pot declara in pachete deoarece nu au o stare persistenta. - O interogare asociata cu o variabila cursor intr-o instructiune OPEN-FOR nu poate fi FOR UPDATE. -Nu putem folosi variabile cursor in operatori de comparare:=,!=, NULL - Nu putem asigna NULL la variabile cursor - Nu putem folosi tipul REF CURSOR pentru o coloana in comenzile CREATE TABLE si CREATE VIEW.

  • - Nu putem folosi REF CURSOR sa specificam tipul elementelor unei colectii. -Cursorii si variabilele cursor nu sunt interoperabile. CURSOR emp_1 IS SELECT * FROM emp; TYPE TypEmp IS REF CURSOR RETURN emp%ROWTYPE; emp_cv TypEmp; FOR emp_rec IN emp_cv LOOP --ilegal Limbajul PL/SQL- Interactiunea cu Oracle DECLARE TYPE EmpTyp IS REF CURSOR RETURN emp%ROWTYPE; empv EmpTyp; PROCEDURE process_emp_cv (emp_cv IN EmpTyp) IS person emp%ROWTYPE; BEGIN dbms_output.put_line(e*****'); LOOP FETCH emp_cv INTO person; EXIT WHEN emp_cv%NOTFOUND; dbms_output.put_line('Nume = ' || person.first_name || ' ' || person.last_name); END LOOP; END; Limbajul PL/SQL- Interactiunea cu Oracle BEGIN OPEN empv FOR SELECT * FROM emp WHERE ROWNUM < 10; process_emp_cv(empv); CLOSE emp; END; Expresii cursor: Returneaza un cursor imbricat. O linie returnata de un cursor obisnuit poate contine valori sau o submultime de alte linii produse de subinterogari. Sintaxa expresiei cursor: CURSOR(interogare SELECT) Expresiile cursor pot apare in declaratii cursor, declaratii REF CURSOR, interogari SQL. Limbajul PL/SQL- Interactiunea cu Oracle DECLARE TYPE emp_typ IS REF CURSOR; emp_c emp_typ; dept_name departments.department_name%TYPE; emp_name emp.last_name%TYPE; CURSOR c1 IS SELECT department_name, CURSOR ( SELECT e.last_name FROM emp e WHERE e.department_id = d.department_id ) employees FROM departments d WHERE department_name like eINFO%'; BEGIN OPEN c1; LOOP FETCH c1 INTO dept_name, emp_c; EXIT WHEN c1%NOTFOUND;

  • Limbajul PL/SQL- Interactiunea cu Oracle dbms_output.put_line('Department: ' || dept_name); -- Pentru fiecare linie a rezultatului prelucram submultimea definita de subinterogare. LOOP FETCH emp_c INTO emp_name; EXIT WHEN emp_c%NOTFOUND; dbms_output.put_line(' Employee: ' || emp_name); END LOOP; END LOOP; CLOSE c1; END; Restrictii: -Nu putem folosi o expresie cursor cu un cursor implicit -Nu pot apare in declaratii view - Nu putem realiza operatii EXECUTE pe expresii cursor Limbajul PL/SQL- Interactiunea cu Oracle Atribute cursor : %FOUND, %ISOPEN, %NOTFOUND, %ROWCOUNT CURSOR C1 IF C1%ISOPEN THEN cursor deschis ELSE -- il deschidem OPEN C1; END IF; Inainte de FETCH, %NOTFOUND este NULL. EXIT WHEN C1%NOTFOUND OR C1%NOTFOUND IS NULL Inainte de deschiderea unui cursor sau variabila cursor %ROWCOUNT este 0. Limbajul PL/SQL- Interactiunea cu Oracle LOOP FETCH C1 INTO inreg; IF C1%ROWCOUNT >11 THEN END IF; END LOOP; In cazul cind cursorul e nedeschis referirea la %ROWCOUNT produce exceptia INVALID_CURSOR. Dupa prima executie FETCH daca nu exista linii in multimea respectiva, atunci %FOUND este FALSE, %NOTFOUND este TRUE si %ROWCOUNT este 0. Atributele pentru cursori impliciti sunt aceleasi, dar returneaza informatii despre executia comenzilor INSERT, UPDATE, DELETE, SELECT. Limbajul PL/SQL- Interactiunea cu Oracle %FOUND Inainte ca instructiunea SQL sa fie executata, %FOUND este NULL. Apoi %FOUND este TRUE daca INSERT, UPDATE sau DELETE a afectat cel putin o linie, sau SELECT INTO returneaza cel putin o linie. Altfel %FOUND este FALSE.

  • DELETE FROM emp WHERE empno=emp1; IF SQL%FOUND THEN stergere cu succes INSERT INTO emp_new VALUES(emp1,..); %ISOPEN Oracle inchide automat cursorul SQL dupa executia instructiunii SQL. Deci%ISOPEN este mereu FALSE. %NOTFOUND Produce TRUE daca INSERT, UPDATE sau DELETE nu afecteaza nicio linie, sau SELECT INTO nu returneaza nicio linie.Altfel, ea produce FALSE. Limbajul PL/SQL- Interactiunea cu Oracle %ROWCOUNT Produce numarul de linii afectate de INSERT, UPDATE, DELETE sau returnate de SELECT INTO. Daca SELECT INTO returneaza cel putin 2 linii, atunci apare exceptia TOO_MANY_ROWS si %ROWCOUNT este 1. Valorile atributelor cursor se refera la cea mai recenta instructiune SQL executata. Daca SELECT INTO nu returneaza nicio linie , atunci PL/SQL produce exceptia NO_DATA_FOUND. SELECT INTO cu o functie de grupare nu produce exceptia de sus, deoarece functia de grupare produce o valoare sau NULL. Atunci %NOTFOUND este FALSE. Limbajul PL/SQL- Interactiunea cu Oracle Prelucrarea tranzactiilor -COMMIT Face permanente schimbarile din timpul tranzactiei. BEGIN SELECT suma INTO suma1 FROM cont WHERE nrcont=1500; UPDATE cont SET suma= suma1-debit WHERE nrcont=1500; UPDATE cont SET suma=suma1+debit WHERE nrcont=1600; COMMIT WORK; END; COMMIT COMENT mesaj; Limbajul PL/SQL- Interactiunea cu Oracle ROLLBACK DECLARE emp_id INTEGER; BEGIN SELECT ampno, INTO emp_id, FROM ..

  • INSERT INTO emp VALUES (emp_id,); INSERT INTO emp1 VALUES (emp_id,); INSERT INTO emp2 VALUES (emp_id,); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN ROLLBACK; END; Limbajul PL/SQL- Interactiunea cu Oracle SAVEPOINT Numeste si marcheaza un punct curent in prelucrarea unei tranzactii. DECLARE emp_id emp.empno%TYPE: BEGIN UPDATE emp SET WHERE empno=emp_id; DELETE FROM emp WHERE SAVEPOINT insert; INSERT INTO emp VALUES (emp_id,); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN ROLLBACK TO insert; END; Limbajul PL/SQL- Interactiunea cu Oracle SET TRANSACTION DECLARE vinzari_zi REAL; vinzari_saptamina REAL; vinzari_luna REAL; BEGIN COMMIT; SET TRANSACTION READ ONLY; SELECT SUM(cant) INTO vinzari_zi FROM sales WHERE data=SYSDATE; SELECT SUM(cant) INTO vinzari_saptamina FROM sales WHERE data >SYSDATE-7; SELECT SUM(cant) INTO vinzari_luna FROM sales WHERE data>SYSDATE-30; COMMIT; END; Limbajul PL/SQL- Interactiunea cu Oracle Restrictii -Numai SELECT INTO, OPEN, FETCH, CLOSE, LOCK TABLE, COMMIT si ROLLBACK sunt permise in tranzactii read-only. -Interogarile nu pot contine FOR UPDATE

  • Blocari - Oracle blocheaza linia ce apare pentru UPDATE sau DELETE. - Folosim FOR UPDATE sa blocam toate liniile inainte de comanda UPDATE sau DELETE. - Blocarea intregii tabele cu LOCK TABLE DECLARE CURSOR C1 IS SELECT empno, sal FROM emp WHERE job=saleman AND comm >sal FOR UPDATE NOWAIT; BEGIN OPEN C1; -- toate liniile lui C1 sunt blocate, deblocarea:COMMIT -- sau ROLLBACK Limbajul PL/SQL- Interactiunea cu Oracle In interogari cu mai multe tabele putem bloca numai linii din anumite tabele. DECLARE CURSOR C1 IS SELECT ename, dname FROM emp, dept WHERE emp.deptno=dept.deptno AND job=MANAGER FOR UPDATE OF sal; In instructiunea UPDATE sau DELETE folosim CURRENT OF: DECLARE CURSOR C1 IS SELECT empno, job, sal FROM emp FOR UPDATE; BEGIN OPEN C1; LOOP FETCH c1 INTO UPDATE emp SET sal =new_sal WHERE CURRENT OF C1; END LOOP; Limbajul PL/SQL- Interactiunea cu Oracle FETCH si COMMIT. FETCH nu poate urma lui COMMIT. DECLARE CURSOR C1 IS SELECT ename FROM emp FOR UPDATE OF sal; ctr NUMBER:=0; BEGIN FOR emp_rec IN C1 LOOP ctr:=ctr+1; INSERT INTO temp VALUES (ctr,info); IF ctr>=10 THEN COMMIT; END IF; END LOOP; END; Limbajul PL/SQL- Interactiunea cu Oracle In loc de FOR UPDATE si CURRENT OF ROWID DECLARE CURSOR C1 IS SELECT ename, job, rowid FROM emp; ename1 emp.ename%TYPE;

  • job1 emp.ename%TYPE; rowid1 ROWID; BEGIN OPEN C1; LOOP FETCH C1 INTO ename1, job1, rowid1; EXIT WHEN C1%NOTFOUND; UPDATE emp SET sal=sal *1.1 WHERE ROWID= rowid1; COMMIT; END LOOP; CLOSE C1; END; Limbajul PL/SQL- Interactiunea cu Oracle Utilizarea atributului %ROWTYPE cu cursori ce refera ROWID DECLARE CURSOR C1 IS SELECT ename, sal, rowid FROM emp; emp_rec C1%ROWTYPE; BEGIN OPEN C1; LOOP FETCH C1 INTO emp_rec; EXIT WHEN C1%NOTFOUND; IF THEN DELETE FROM emp WHERE ROWID=emp_rec.ROWID; END IF; END LOOP; CLOSE C1; END; Limbajul PL/SQL-Subprograme Proceduri PROCEDURE nume[(p1,p2,)] IS declaratii locale BEGIN instructiuni executabile [EXCEPTION tratarea exceptiilor] END [nume]; p1 [IN|OUT|IN OUT] tip [{:=|DEFAULT} expresie] Nu este permisa restrictia NOT NULL pentru parametri formali. Nu se poate specifica restrictia pe un tip de date: p1 NUMBER(4) Chemarea procedurii: BEGIN nume[(a1,a2,)]; Limbajul PL/SQL-Subprograme Functii

  • FUNCTION numef [(p1,p2,)] RETURN tip_returnat IS declaratii locale BEGIN instructiuni executabile [EXCEPTION tratarea exceptiilor] END [numef]; P1 [IN|OUT| IN OUT] tip [{:=|DEFAULT } expresie] Apel: numef[(a1,a2,)] ce apare intr-o expresie. Trebuie sa existe instr.RETURN exp; Daca nu exista se produce exceptia: PROGRAM_ERROR Putem declara subprograme in blocuri PL/SQL,subprograme sau pachete, dar in partea finala a sectiunii DECLARE Limbajul PL/SQL-Subprograme Declaratii forward. PL/SQL cere declararea unui identificator inainte de folosirea lui. DECLARE PROCEDURE P1 IS BEGIN P2(); END; PROCEDURE P2() IS BEGIN END; /* incorect */ Limbajul PL/SQL-Subprograme 1) Declaratie forward prin prototip. DECLARE PROCEDURE P2(); --prototipul lui P2 /*Definirea subprogramelor */ PROCEDURE P1 IS BEGIN P2(); END; PROCEDURE P2() IS BEGIN END; Limbajul PL/SQL-Subprograme In pachete

  • Prototipurile subprogramelor se dau in specificarea pachetului. Corpul subprogramelor se dau in corpul pachetului. Subprograme memorate Crearea si memorarea subprogramelor permanent in baza Oracle se realizeaza prin CREATE PROCEDURE sau CREATE FUNCTION AS , date intr-un script SQL. Parametrii actuali si formali trebuie sa aiba tipuri compatibile. Altfel se produce eroarea: VALUE_ERROR Lista parametrilor in apel: notatie pozitionala, sau cu nume p1=>expresie Modurile IN, OUT, IN OUT p1 IN p1:= expresie; --eroare de sintaxa Parametrul actual pentru p1 de tip OUT trebuie sa fie o variabila. Limbajul PL/SQL-Subprograme Parametrii actuali corespunzatori parametrilor formali IN OUT trebuie sa fie variabile. Valori default PROCEDURE PR1 (p1 DEFAULT v1,p2 DEFAULT v2,); La apel: PR1; PR1(w1); PR1(w1,w2); PR1(w1,w2,,pi=>wi,); Trecerea parametrilor prin valoare si prin referinta Tipurile compuse se trec prin referinta. Supraincarcarea subprogramelor Putem da acelasi nume pentru diferite subprograme, lista parametrilor lor formali difera in numar, ordine sau familie de tip Limbajul PL/SQL-Subprograme DECLARE TYPE Tip_data IS TABLE OF DATE INDEXED BY BINARY_INTEGER; TYPE Tip_real IS TABLE OF REAL INDEXED BY BINARY_INTEGER; tabela_date Tip_data; tabela_salarii Tip_real; PROCEDURE initializare (tab OUT tip_data, n INTEGER) IS BEGIN FOR i IN 1..n LOOP tab(i) := SYSDATE; END LOOP; END initializare; Limbajul PL/SQL-Subprograme PROCEDURE initializare (tab OUT Tip_real, n INTEGER) IS BEGIN

  • FOR i IN 1..n LOOP tab(i) := 0.0; END LOOP; END initializare; DECLARE TYPE Tip_data IS TABLE OF DATE INDEX BY TYPE Tip_real IS TABLE OF REAL INDEX BY Tabela1 Tip_data; Tabela2 Tip_real; nr BINARY_INTEGER :=10; BEGIN initializare(Tabela1,nr); initializare(Tabela2,nr); END; Limbajul PL/SQL-Subprograme Restrictii - Numai subprogramele locale sau incluse in pachete pot fi supraincarcate - Nu putem supraincarca subprogramele ce difera numai prin nume sau modul IN, OUT, IN OUT. - Nu putem supraincarca subprograme ce difera numai in tipul de date, dar aceste tipuri sunt din aceeasi familie. - Nu putem supraincarca subprograme daca parametrii formali difera numai in subtip, dar aceste subtipuri sunt definite prin subtipuri din aceeasi familie. DECLARE SUBTYPE D1 IS CHAR; SUBTYPE Text IS LONG; PROCEDURE PR1 (z D1) IS BEGIN PROCEDURE PR1(z Text) IS Limbajul PL/SQL-Subprograme - Nu putem supraincarca doua functii ce difera numai in tipul returnat, chiar daca aceste tipuri sunt din aceeasi familie. Functiile standard PL/SQL declara functiile stadard in pachetul STANDARD. Redeclararea lor local produce eroare. DECLARE X NUMBER; BEGIN DECLARE FUNCTION SIGN (n NUMBER) RETURN NUMBER IS BEGIN IF n
  • X:= SIGN(0); -- X ia valoarea 0 END; Pentru a chema o functie standard folosim notatia STANDARD.numef X:= STANDARD.SIGN(0); -- X ia valoarea 0. Recursie Cu fiecare chemare a unui program recursiv se creaza o noua instanta a tuturor elementelor declarate in program: parametri, variabile, cursori, exceptii, instructiuni SQL. Daca subprogramul are cursor FOR LOOP, sau instructiuni OPEN, CLOSE, atunci e posibil sa se depasesca limita setata de parametrul OPEN_CURSORS. Daca subprogramul executa la infinit va apare eroarea: STORAGE_ERROR. Limbajul PL/SQL-Subprograme FUNCTION factorial (n POSITIVE) RETURN INTEGER IS BEGIN IF n=1 THEN RETURN 1; ELSE RETURN n*factorial(n-1); END IF; END factorial; Recursie mutuala FUNCTION impar (n NATURAL) RETURN BOOLEAN; FUNCTION par (n NATURAL) RETURN BOOLEAN IS BEGIN IF n=0 THEN RETURN TRUE; ELSE RETURN IMPAR(n-1); END IF; END par; Limbajul PL/SQL-Subprograme FUNCTION impar (n NATURAL) RETURN BOOLEAN IS BEGIN IF n=0 THEN RETURN FALSE; ELSE RETURN par(n-1); END IF; END impar; Versiune recursiva -> versiune iterativa. Limbajul PL/SQL-Pachete Un pachet este o schema de obiect ce grupeaza tipuri, variabile, subprograme, cursori. Are 2 parti: o specificatie si un corp. Pachetele nu pot fi chemate, parametrizate sau imbricate.

  • CREATE PACKAGE numepachet AS -- tipuri si variabile -- specificatii de subprograme END [numepachet]; CREATE PACKAGE BODY numepachet AS --corpul -- declaratii de tip si variabile -- corpuri de subprograme BEGIN --instructiuni END [numepachet]; Limbajul PL/SQL-Pachete Specificatia pachetului contine declaratii publice. Referirea la tipuri, variabile, subprograme dintr-un pachet se face: nume_pachet.nume_tip nume_pachet.nume_variabla nume_pachet.nume_subprogram Putem referi continutul unui pachet din subprogram memorat, aplicatie OCI, SQL Plus. SQL> EXECUTE nume_pachet.nume_procedura(a1,a2,); Corpul pachetului contine definitia fiecarui cursor si subprogram declarate in specificatia pachetului. Declaratiile de tipuri si variabile sunt accesibile numai in interiorul pachetului. Putem avea supraincarcarea subprogramelor in cadrul unui pachet. Pachetul STANDARD defineste tipurile, exceptiile, subprogramele disponibile pentru programe PL/SQL. Ex.ABS, STANDARD.ABS Limbajul PL/SQL-Pachete Pachete specifice: - DBMS_STANDARD -interactiunea cu Oracle ex. Raise_application_error -DBMS_OUTPUT -- afisam iesirea din blocuri PL/SQL, procedura PUT_LINE, GET_LINE - DBMS_PIPE -- permite diferitelor sesiuni sa comunice cu diferite zone pack_message, send_message, receive_message, unpack_message - UTL_FILE permite programelor PL/SQL sa citeasca si sa scrie fisiere text ale sistemului de operare. fopen, put_line, get_line - UTL_HTTP permite programelor PL/SQL sa faca chemari HTTP, se pot prelua date din internet. -DBMS_SQL permite executia comenzilor SQL - DBMS_ALERT permite utilizarea trigerilor pentru a alerta o aplicatie cind se schimba anumite valori in baza de date. Limbajul PL/SQL- Obiecte Object Type and Objects (Instances) Limbajul PL/SQL- Obiecte Structura unui tip obiect

  • Limbajul PL/SQL- Obiecte CREATE TYPE tip_obiect AS OBJECT( var1 tip1, var2 tip2, MEMBER FUNCTION f1(lista1) RETURN tipf1, MEMBER FUNCTION f2(lista2) RETURN tipf2, MEMBER PROCEDURE p1(lista21), MEMBER PROCEDURE p2(lista22), ); CREATE TYPE BODY tip_obiect AS MEMBER FUNCTION f1(lista1) RETURN tipf1 IS BEGIN END f1; END; Limbajul PL/SQL- Obiecte Componentele unui tip obiect Atributele: nume si tip. Tip diferit de: LONG, LONG RAW, NCHAR, NCLOB, NVARCHAR2, MLSLABEL, ROWID, BINARY_INTEGER, RECORD, REF CURSOR, %TYPE, %ROWTYPE, tipuri definite in pachete. - Nu se poate initializa un atribut prin asignare sau DEFAULT. - Nu putem impune NOT NULL pe un atribut. - Obiectele pot fi memorate in tabele pe care se pot impune NOT NULL> Metodele = subprograme precedate de MEMBER sau STATIC. Fiecare metoda are o specificare si un corp. Intr-un tip obiect, metodele pot referi atribute si alte metode fara a folosi calificarea. Limbajul PL/SQL- Obiecte Parametrul SELF: Orice metoda a unui tip obiect accepta o instanta a acelui tip drept prim parametru. Numele acestui parametru este SELF. Indiferent daca SELF este sau nu declarat, el este mereu primul parametru de apel al metodei. In functii membru SELF nedeclarat este de tip IN, in proceduri nedeclarat el este de tip IN OUT. Nu se specifica tipul lui SELF. In corpul metodei SELF specifica obiectul pentru care a fost apelata metoda. Metodele statice nu accepta sau refera SELF, ele se adreseaza tipului obiect si nu unui obiect. CREATE FUNCTION cmmdc(x INTEGER, y INTEGER) RETURN INTEGER AS z INTEGER; BEGIN IF( y
  • numarator INTEGER, numitor INTEGER, MEMBER PROCEDURE normalizare, ) / CREATE TYPE BODY Rational AS MEMBER PROCEDURE IS g INTEGER; BEGIN g:=cmmdc(SELF.numarator,SELF.numitor); --sau g:=cmmdc(numarator,numitor); numarator:=numarator/g; numitor:=numitor/g; END normalizare; END; Limbajul PL/SQL- Obiecte Supraincarcarea. Metodele de acelasi tip(proceduri sau functii) pot fi supraincarcate. Nu se pot supraincarca doua metode daca parametrii formali difera numai in modul parametru. Nu putem supraincarca doua functii membru ce difera numai in tipul returnat. Metodele ORDER si MAP Tipurile de date scalare (CHAR, REAL,..) au o ordine predefinita, ce permite compararea lor. Instantele obiectelor nu au o ordine predefinita. Vom folosi metoda MAP. CREATE TYPE Rational AS OBJECT ( numarator INTEGER, numitor INTEGER, MAP MEMBER FUNCTION conversie RETURN REAL; ); Limbajul PL/SQL- Obiecte CREATE TYPE BODY Rational AS MAP MEMBER FUNCTION conversie RETURN REAL IS -- conversie obiect Rational la un numar REAL BEGIN RETURN numarator/numitor; END conversie; END; Ordonarile sunt necesare in realizarea clauzelor DISTINCT, GROUP BY, ORDER BY. Un tip obiect poate contine numai o metoda MAP, cu tipul returnat unul din: DATE, NUMBER, VARCHAR2, CHARACTER, REAL. Putem folosi metoda ORDER, cu doi parametri: primul SELF, al doilea de acelasi tip. Limbajul PL/SQL- Obiecte O comparare a doua obiecte implica automat invocarea metodei definite de ORDER. CREATE TYPE Student AS OBJECT ( marca NUMBER,

  • nume VARCHAR2(15), adresa VARCHAR2(20), ORDER MEMBER FUNCTION comparare (par2 Student) RETURN INTEGER ); CREATE TYPE BODY Student AS ORDER MEMBER FUNCTION comparare (par2 Student) RETURN INTEGER ) IS BEGIN IF marca par2.marca THEN RETURN 1; ELSE RETURN 0; END IF; END; END; Limbajul PL/SQL- Obiecte Metoda constructor Fiecare tip obiect are o metoda constructor, folosita pentru initializarea si returnarea unei instante de tipul respectiv. Parametrii formali ai constructorului au acelasi tip cu atributele obiectului. Putem defini metode constructor proprii prin supraincarcarea constructorului sistem sau definind noi functii cu signatura diferita. Apelul constructorului trebuie facut explicit de catre program. Modificarea atributelor si metodelor unui tip existent: ALTER TYPE pentru adaugare, modificare, stergere atribute, adaugare, stergere metode pentru un tip existent. ALTER TYPE tip_obiect ADD ATTRIBUTE (nume1 tip1, ) CASCADE; ALTER TYPE tip_obiect DROP ATTRIBUTE nume1,.. ; Limbajul PL/SQL- Obiecte Declararea obiectelor Dupa definirea tipului obiect,acesta poate fi utilizat sa declare obiecte in blocuri PL/SQL, subprograme, pachete. In bloc sau subprogram, la intrare se creaza obiecte, care se sterg la iesire. In pacete obiectele se instantiaza la prima referire si se sterg la sfirsitul sesiunii. DECLARE nume_obiect tip_obiect; Putem declara obiectele ca parametri formali ai functiilor sau procedurilor: PROCEDURE nume_p (par1 IN OUT tip_obiect) IS FUNCTION nume_f (lista) RETURN tip_obiect IS Initializarea obiectelor: Inainte de initializare un obiect este atomic null. Compararea unui obiect null cu altul produce NULL. nume_ob1:=nume_ob2; nume_ob:=NULL; nume_obiect tip_obiect:= constructor Limbajul PL/SQL- Obiecte In expresii atributele unui obiect neinitializat au valoarea NULL. nume_obiect.atribut:=expresie; cind nume_obiect este neinitializat produce ACCES_INTO_NULL.

  • Apel de metoda cu obiect neintializat este permis, SELF este NULL. nume_obiect neinitializat ca parametru formal IN atributele NULL. Cind OUT sau IN OUT apare exceptia daca se asigneaza. Referinta la atribute: nume_obiect.atribut Apelul constructorului implica definirea de valori initiale atributelor (nu se poate folosi DEFAULT). Putem folosi notatia pozitionala. Apelul metodelor: nume_obiect.metoda(a1,); -- sau inlantuiri de chemari de metode. In instructiuni procedurale lista vida este optionala, dar in apel inlantuit trebuie dat () pentru functii. o.f1().F2() prima trebuie sa returneze un obiect. Limbajul PL/SQL- Obiecte Tipuri obiecte imbricate CREATE TYPE Adresa AS OBJECT ( strada VARCHAR2(20), oras VARCHAR2(15), codpostal INTEGER ) / CREATE TYPE persoana AS OBJECT ( nume VARCHAR2(20), prenume VARCHAR2(20), datanasterii DATE, adresa_domiciliu Adresa, telefon VARCHAR2(12) ) / Un obiect are un identificator de obiect. Vom utiliza REF care este pointer la un obiect. Procesul sharing. Avantaje: nereplicare si modificarea unui obiect implica actualizarea referintelor. CREATE TYPE persoana AS OBJECT ( nume VARCHAR2(20), prenume VARCHAR2(20), datanasterii DATE, adresa_domiciliu Adresa, telefon VARCHAR2(12) , tata REF persoana, mama REF persoana) Limbajul PL/SQL- Obiecte Putem declara REF pentru variabile, parametri, cimpuri, atribute, variabile de intrare/iesire in instructiuni SQL. Nu putem naviga prin aceste elemente REF: nume_referinta.atribut --nu poate specifica obiectul referit. DEREF Definitii forward de tip: CREATE TYPE Emp AS OBJECT ( nume VARCHAR2(15), dept REF departament, --incorect ) CREATE TYPE departament AS OBJECT ( numar INTEGER, manager Emp,) CREATE TYPE departament; -- definitie forward tip obiect incomplet. CREATE TYPE Emp AS OBJECT Putem folosi tip de obiect in CREATE TABLE, INSERT, nume de Metode in UPDATE CREATE TABLE Tab1 OF Rational --tabela de obiecte Limbajul PL/SQL- Obiecte Tratarea obiectelor neinitializate

  • In expresii atributele unui obiect neinitializat sunt evaluate la NULL. Asignarea de valori pentru un atributele unui obiect neinitializat produce exceptia ACCESS_INTO_NULL. Operatorul IS NULL aplicat obiectului neinitializat sau atributelor acestuia da TRUE. DECLARE rat Rational; -- rat este atomic null BEGIN IF rat IS NULL THEN --expresia este TRUE IF rat.numarator IS NULL THEN -- TRUE rat:=Rational(NULL,NULL); -- initializeaza rat rat.numarator:=10; -- nu produce exceptie rat:=NULL; -- rat devine atomic nul rat.numarator:=20; -- produce exceptia ACCESS_INTO_NULL EXCEPTION WHEN ACCESS_INTO_NULL THEN .. END; Limbajul PL/SQL- Obiecte Definitii de tip forward CREATE TYPE Emp AS OBJECT ( nume VARCHAR2(15), dept REF departament, --incorect ); CREATE TYPE departament AS OBJECT ( numar INTEGER, manager Emp, ); CREATE TYPE departament; -- definitie forward inainte de Emp departament tip incomplet tip obiect incomplet are atribute dar se refera la tipuri nedefinite CREATE TABLE nume_tabela OF tip_obiect -- tabela de obiecte O linie in tabela de obiecte are un identificator de obiect si serveste ca referinta la acel obiect Limbajul PL/SQL- Obiecte Selectarea obiectelor CREATE TYPE persoana AS OBJECT ( nume VARCHAR2(15), prenume VARCHAR2(15), data_nasterii DATE, adresa Address, telefon VARCHAR2(15) ) / CREATE TABLE persoane OF persoana / BEGIN INSERT INTO emp SELECT * FROM persoane p WHERE p.nume LIKE A%;

  • Limbajul PL/SQL- Obiecte VALUE returneaza valoarea unui obiect BEGIN INSERT INTO emp SELECT VALUE(p) FROM persoane p WHERE p.nume LIKE A%; --------------------------------------------------------- DECLARE p1 persoane; p2 persoane; BEGIN SELECT VALUE(p) INTO p1 FROM persoane p WHERE p.nume=IONESCU; p2:=p1; p1.nume:=expresie; END; Limbajul PL/SQL- Obiecte Operatorul REF Variabila corelata= variabila de linie sau alias pentru o tabela de obiecte REF are ca argument o variabila corelata si returneaza referinta. BEGIN INSERT INTO persoane_ref SELECT REF(p) FROM persoane p WHERE p.nume LIKE A%; ------------------------------------------------------- DECLARE p_ref REF persoana; telefon VARCHAR2(15); BEGIN SELECT REF(p),p.telefon INTO p_ref, telefon FROM persoane p WHERE p.nume=IONESCU; -- trebuie o singura linie END; Limbajul PL/SQL- Obiecte DECLARE p_ref REF persoana; wnume VARCHAR2(15); BEGIN SELECT REF(p) INTO p_ref FROM persoane p WHERE p.nume=wnume; UPDATE persoane p SET p= persoana(ION,ION,) WHERE REF(p)= p_ref; END; Referinte dangling (pointeaza la un obiect inexistent), IS DANGLING. BEGIN

  • UPDATE departament SET manager=NULL WHERE manager IS DANGLING; Limbajul PL/SQL- Obiecte Operatorul DEREF argumentul =referinta la obiect, returneaza valoarea (obiectul) la care pointeaza. Daca ref este dangling, atunci se returneaza obiectul nul. DECLARE p1 persoana; p1_ref REF persoana; wnume VARHAR2(15); BEGIN SELECT REF(p) INTO p1_ref FROM persoane p WHERE p.marca=10; SELECT DEREF(p1_ref) INTO p1 FROM DUAL; wnume:=p1.nume; DBMS_OUTPUT.PUT_LINE(Numele este; ||wnume); END; / Limbajul PL/SQL- Obiecte Operatorul DEREF poate fi folosit in dereferinte succesive CREATE TYPE persoanan_ref AS OBJECT (p_ref REF persoana) / CREATE TABLE persoanen_ref OF persoanan_ref / DECLARE wnume VARCHAR2(15); obiect_1 persoanan_ref :=persoanan_ref(NULL); ref_ref_p REF persoanan_ref; p persoana; ref_p REF persoana; ref_p1 persoanan_ref; BEGIN Limbajul PL/SQL- Obiecte SELECT REF(a) INTO ref_p FROM persoane a WHERE a.marca=10; obiect_1.p_ref:=ref_p; INSERT INTO persoanen_ref VALUES(obiect_1); SELECT REF(c) INTO ref_ref_p FROM persoanen_ref c WHERE c.p_ref=ref_p; SELECT DEREF(ref_ref_p) INTO ref_p1 FROM DUAL; SELECT DEREF(ref_p1.p_ref) INTO p FROM DUAL; wnume:=p.nume; DBMS_OUTPUT.PUT_LINE(wnume); END; / Limbajul PL/SQL- Obiecte

  • Operatorul DEREF nu poate fi folosit in instructiuni procedurale: P1:=DEREF(p_ref); --incorect In comenzi SQL folosim notatia . Pentru a naviga de la coloane obiect la atribute REF si de la atribute REF la alt atribut REF. alias_tabela.coloana_obiect.atribut_ref alias_tabela.coloana_obiect.atribut_ref.atribut alias_tabela.coloana_ref.atribut CREATE TYPE Address AS OBJECT ( strada VARCHAR2(15), oras VARCHAR2(15), cod_postal INTEGER) / CREATE TYPE Person AS OBJECT (nume VARCHAR2(15),prenume VARCHAR2(15),adresa_dom REF Address,telefon VARCHAR2(15),strada VARCHAR2(15)) / CREATE TABLE persons OF Person / Limbajul PL/SQL- Obiecte DECLARE addr1 Address; addr2 Address; wstrada VARCHAR2(15); BEGIN SELECT DEREF(adresa_dom) INTO addr1 FROM persons p WHERE p.nume=ION; SELECT p.adresa_dom.strada INTO wstrada FROM persons p WHERE p.prenume=ioana; Inserarea de obiecte INSERT INTO persons VALUES(Person(ION,ioana,)); Utilizam clauza RETURNING sa memoram referinte in variabile locale Limbajul PL/SQL- Obiecte DECLARE p1_ref REF person; p2_ref REF person; BEGIN INSERT INTO persons p VALUES(Person(IONESCU,dorin,)) RETURNING REF(p) INTO p1_ref; INSERT INTO persons1 SELECT VALUE(p) FROM persons p WHERE p.prenume LIKE A%; UPDATE persons p SET adresa_dom=Iasi. WHERE; DELETE FROM persons p WHERE ;

  • Limbajul PL/SQL- Obiecte DECLARE p_ref REF Person; wprenume VARCHAR2(15); BEGIN wprenume:=bill; SELECT REF(p) INTO p_ref FROM persons p WHERE p.prenume = wprenume; UPDATE persons p SET p = Person('Jill', 'Anders', '11-NOV-67', ...) WHERE REF(p) = p_ref; END; / Limbajul PL/SQL- Obiecte Mostenirea tipurilor CREATE TYPE T1 AS OBJECT () NOT FINAL; CREATE TYPE T2 UNDER T1() {NOT FINAL|FINAL}; T1- supertip(parinte) pentru T2, iar T2 subtip(fiu)al lui T1 FINAL- nu se pot deriva subtipuri din el Subtipul contine toate atributele si metodele tipului parinte si poate contine atribute si metode suplimentare care pot supraincarca metodele tipului parinte. FINAL MEMBER FUNCTION f () in tipul parinte implica imposibilitatea supraincarcarii lui f in orice subtip al celui curent. CREATE TYPE tip_persoana AS OBJECT ( nume VARCHAR2(20),cnp CHAR(13),adresa VARCHAR2(25)) NOT FINAL; CREATE TYPE tip_student UNDER tip_persoana (cod_fac NUMBER) NOT FINAL; CREATE TYPE tip_functionar UNDER tip_persoana(marca NUMBER); CREATE TYPE student1 UNDER tip_student (bursa NUMBER); Limbajul PL/SQL- Obiecte CREATE TYPE T AS OBJECT (,MEMBER PROCEDURE P1, FINAL MEMBER FUNCTION f1()) NOT FINAL; ----------------------------------------------------------------------------------- CREATE TYPE tip_adresa AS OBJECT() NOT INSTANTIABLE NOT FINAL; CREATE TYPE tip_adresa1 UNDER tip_adresa(); CREATE TYPE tip_adresa2 UNDER tip_adresa(); ----------------------------------------------------------------------------------- CREATE TABLE person_v OF tip_persoana Operatorul TREAT returneaza obiecte de un tip specificat SELECT TREAT(REF(p) AS REF tip_student); FROM Person_v p; --returneaza referintele persoanelor ce sunt --instante ale subtipului tip_student

  • SELECT REF(p) FROM Person_v p WHERE VALUE(p) IS OF (tip_functionar, tip_student) ; SELECT REF(p) FROM Person_v p WHERE VALUE(p) IS OF(ONLY tip_student); Limbajul PL/SQL- Obiecte Constructor definit de utilizator CONSTRUCTOR FUNCTION tip_obiect( lista) RETURN SELF AS RESULT CREATE OR REPLACE TYPE paralelipiped AS OBJECT ( -- Tipul are 3 atribute lungime NUMBER, latime NUMBER, inaltime NUMBER,volum NUMBER, -- Definim un constructor cu 3 parametri. CONSTRUCTOR FUNCTION paralelipiped (plungime NUMBER, platime NUMBER,pinaltime NUMBER) RETURN SELF AS RESULT ); / CREATE OR REPLACE TYPE BODY paralelipiped AS CONSTRUCTOR FUNCTION paralelipiped (plungime NUMBER, platime NUMBER,pinaltime NUMBER) RETURN SELF AS RESULT Limbajul PL/SQL- Obiecte AS BEGIN SELF.lungime := plungime; SELF.latime:= platime; SELF.inaltime:=pinaltime; SELF.volum:=plungime*platime*pinaltime; RETURN; END; END; / DECLARE par1 paralelipiped; par2 paralelipiped; BEGIN par1:=NEW paralelipiped(10,20,30,6000); par2:= NEW paralelipiped(10,20,30); Limbajul PL/SQL- Obiecte Parametrul SELF Fiecare metoda are primul parametru cu numele SELF. In mod implicit orice atribut necalificat in functie membru sau procedura membru este calificat prin SELF. CREATE OR REPLACE TYPE cladire AS OBJECT ( Numecladire VARCHAR2(40), Adresacladire address, Managercladire INTEGER, MEMBER PROCEDURE SchimbareManager (SELF IN OUT cladire, NouManager IN INTEGER), ORDER MEMBER FUNCTION Comparare (SELF IN cladire, altacladire IN cladire) RETURN INTEGER

  • ) / Limbajul PL/SQL- Obiecte CREATE OR REPLACE TYPE BODY cladire AS MEMBER PROCEDURE SchimbareManager(SELF IN OUT cladire, NouManager IN INTEGER) IS BEGIN SELF.Managercladire:= NouManager; END; ORDER MEMBER FUNCTION Comparare (SELF IN cladire, altacladire IN cladire) RETURN INTEGER IS Numecladire1 VARCHAR2(40); Numecladire2 cladire.Numecladire%TYPE; BEGIN Numecladire1 := upper(ltrim(rtrim(SELF.Numecladire))); Numecladire2:= upper(ltrim(rtrim(altacladire.Numecladire))); IF Numecladire1 = Numecladire2 THEN RETURN 0; ELSIF Numecladire1 < Numecladire2 THEN RETURN -1; ELSE RETURN 1; END IF; END; END; / Limbajul PL/SQL- Tratarea erorilor Tratarea erorilor In PL/SQL o eroare este numita exceptie. Exceptiile pot fi predefinite(interne) sau definite de utilizator. Exemple de exceptii predefinite: division by zero, out of memory . ZERO_DIVIDE and STORAGE_ERROR. Exceptiile interne sunt activate automat. Exceptiile utilizator sunt activate de instructiuni RAISE. SET SERVEROUTPUT ON; DECLARE pret_stoc NUMBER := 9.73; Pret_vinzare NUMBER := 0; Coeficient NUMBER; BEGIN coeficient:= pret_stoc / pret_vinzare; dbms_output.put_line('Pretul stoc/pret vinzare = ' ||coeficient); EXCEPTION prelucrarea exceptiilor BEGIN Limbajul PL/SQL- Tratarea erorilor WHEN ZERO_DIVIDE THEN --tratarea impartirii prin zero dbms_output.put_line(Pretul de vinzare este zero'); coeficient:= NULL; WHEN OTHERS THEN -- tratarea altor erori dbms_output.put_line(Alte tipuri de erori:'); coeficient := null; END; END; / BEGIN

  • coeficient := CASE pret_vinzare WHEN 0 THEN NULL ELSE pret_stoc/ pret_vinzare END; END; / Limbajul PL/SQL- Tratarea erorilor Avantajele exceptiilor Fara rutina de prelucrare a exceptiilor, cind se executa o comanda trebuie sa vedem daca nu au aparut situatii de eroare: BEGIN SELECT INTO --verificarea daca nu a aparut eroare SELECT INTO --verificarea daca nu a aparut eroare END; BEGIN SELECT SELECT SELECT EXCEPTION WHEN NO_DATA_FOUND THEN --tratarea tuturor erorilor no data found Limbajul PL/SQL- Tratarea erorilor Exception Oracle Error SQLCODE Value 1.ACCESS_INTO_NULL ORA-06530 -6530 2.CASE_NOT_FOUND ORA-06592 -6592 3.COLLECTION_IS_NULL ORA-06531 -6531 4.CURSOR_ALREADY_OPEN ORA-06511 -6511 5.DUP_VAL_ON_INDEX ORA-00001 -1 6.INVALID_CURSOR ORA-01001 -1001 7.INVALID_NUMBER ORA-01722 -1722 8.LOGIN_DENIED ORA-01017 - 1017 9.NO_DATA_FOUND ORA-01403 +100 10.NOT_LOGGED_ON ORA-01012 -1012 11.PROGRAM_ERROR ORA-06501 -6501 12.ROWTYPE_MISMATCH ORA-06504 - 6504 13.SELF_IS_NULL ORA-30625 -30625 14.STORAGE_ERROR ORA-06500 -6500 Limbajul PL/SQL- Tratarea erorilor 15.SUBSCRIPT_BEYOND_COUNT ORA-06533 -6533 16.SUBSCRIPT_OUTSIDE_LIMIT ORA-06532 -6532 17.SYS_INVALID_ROWID ORA-01410 -1410 18.TIMEOUT_ON_RESOURCE ORA-00051 -51 19.TOO_MANY_ROWS ORA-01422 -1422 20.VALUE_ERROR ORA-06502 -6502

  • 21.ZERO_DIVIDE ORA-01476 -1476 ------------------------------------------------------------------------------------- 1.Programul asigneaza valori la un atribut al unui obiect neinitializat. 2.Nu s-a selectat niciun WHEN din CASE si nu exista clauza ELSE. 3.Programul aplica o metoda(alta decit EXISTS) la o colectie neinitia-lizata sau se asigneaza valori la elementele colectiei neinitializata. 4.Programul incearca sa deschida un cursor deja deschis. Un cursor FOR LOOP este deschis automat. Limbajul PL/SQL- Tratarea erorilor 5.Programul incearca sa memoreze valori duplicate ale cimpului cu restrictia PRIMARY KEY sau UNIQUE KEY. 6.Programul incearca o operatie nepermisa pe un cursor, de ex. Inchiderea unui cursor nedeschis. 7.Conversia unui sir de caractere la un numar esueaza,deoarece sirul nu are numai caractere numerice(pentru instr.SQL).Pentru instructiuni procedurale eroarea:VALUE_ERROR. Exceptia apare si cind expresia LIMIT din FETCH cu BULK COLLECTION nu se evalueaza la un numar pozitiv. 8.Programul incearca o logare la Oracle cu nume sau password gresit. 9.Instr. SELECT INTO nu returneaza nicio linie sau programul refera un element sters dintr-o tabela nested sau un element neinitializat dintr-o tabela index by. 10.Programul face o chemare de baza de date fara a fi conectat la Oracle. 11.PL/SQL are o problema interna. Limbajul PL/SQL- Tratarea erorilor 12.Variabila cursor intr-o asignare returneaza valori in variabile de tipuri diferite de elementele cursorului. 13.Programul incearca chemarea unei metode cu un obiect neinitializat. 14.PL/SQL executa in afara memoriei sau memoria a fost corupta. 15.Programul face referinta la un element al unei colectii folosind un indice mai mare decit numarul elementelor colectiei. 16. .Programul face referinta la un element al unei colectii folosind un indice in afara domeniului declarat pentru elementele colectiei. 17.Conversia unui sir de caractere la ROWID esueaza deoarece sirul nu este un ROWID corect. 18.S-a depasit timpul de cind Oracle asteapta o resursa. 19.O instructiune SELECT INTO returneaza cel putin 2 linii. 20.A aparut o eroare in evaluarea unei expresii aritmetice, de conversie, de trunchiere sau din cauza unei restrictii de dimensiune. 21.Programul incearca o impartire prin zero. Limbajul PL/SQL- Tratarea erorilor Definirea exceptiilor utilizator -Declararea in partea declarativa a unui bloc PL/SQL, subprogram sau pachet: DECLARE nume_exceptie EXCEPTION;

  • --nume_exceptie nu poate sa apara in asignari sau instructiuni SQL. --nu se poate declara o exceptie de 2 ori in acelasi bloc, dar aceeasi exceptie poate sa apara in blocuri diferite. --exceptiile declarate intr-un bloc sunt locale acelui bloc si globale pentru toate subblocurile acelui bloc. --daca redeclaram exceptia globala