joi, 30 octombrie 2008

Oracle si functii ce returneaza mai multe inregistrari

Aceasta ideea mi-a venit intrucat am folosit destul de mult serverul de baze de date opensource PostgreSQL. In Postgres exista posibilitatea ca o functie sa apara in clauza from a unui select, fapt ce are mari avantaje. Acest lucru poate fi realizat si in oracle. Daca va intrebati de ce am avea nevoie de asa ceva, exemplul de mai jos ar trebui sa va lamureasca.

EX: Presupun ca folosesc un sistem de BI(Business Intelligence) pentru a realiza anumite rapoarte. Birt, Oracle Reports, Crystal Reports, etc. Este cunoscut faptul ca exista probleme de integrare intre Crystal Report in Eclipse si proceduri stocate ce returneaza cursoare.

Intrucat pot folosi functii in clauza from a unui select nu am decat sa scriu ca model al datelor pentru raport un query in loc de o procedura stocata. In realitate voi folosi tot functia stocata astfel incat decuplez logica din baza de date de partea de client.

Rezolvarea pentru problema descrisa consta in rezolvarea functiilor pipelined. Vom lua un caz simplu in care presupun ca am o tabela persoane(cnp, nume, prenume) si as vrea o functie care sa returneze toate inregistrarile.

Pasul 1:
Declar un tip persoana:
create or replace type tp_Persoana is object(CNP NUMBER,
Nume VARCHAR2(200),
Prenume VARCHAR2(200));


Pasul 2:
Declar un tip tabel de tp_Persoana.

create or replace type tp_TblPersoana is table of tp_persoana index by binary_integer;

Pasul 3:
Creez functia stocata:

create or replace function fc_TestPersoane return tp_tblpersoana pipelined
as
cursor c is select * from persoane;
rec tp_Persoana;
begin
OPEN c;

rec := tp_Persoana(null, null, null);

LOOP
FETCH c INTO rec.cnp, rec.nume, rec.prenume;
exit when c%notfound;

pipe row(rec);
END LOOP;

CLOSE c;
return;
end fc_TestPersoane;


Pasul 4:

In fine ultimul pas este apelul propriu-zis.

SELECT * FROM table(fc_TestPersoane());

Cateva observatii:

Aceasta facilitate este extrem de utila si de flexibila. Totusi trebuie sa o folositi doar in cazuri in care nu aveti alta solutie intrucat se obtine o utilizare suplimentara a memorie prin deschiderea cursorului si parcurgerea lui. Sper ca acest post sa fie util.

Cosnita Radu Viorel!

Niciun comentariu:

Trimiteți un comentariu