Oracle PL/SQL zbirke: Varrays, Nested & Index by Tables
⚡ Pametni sažetak
PL/SQL kolekcije su uređene skupine elemenata istog tipa podataka, do kojih se dolazi indeksom. Tri tipa, Varray, ugniježđena tablica i tablica s indeksom, razlikuju se po tome je li veličina fiksna, kako funkcionira indeks i mogu li se pohraniti u bazu podataka.

Što je zbirka?
Kolekcija je uređena skupina elemenata određenog tipa podataka. Može biti kolekcija jednostavnog tipa podataka ili složenog tipa podataka kao što su korisnički definirani ili tipovi zapisa.
U kolekciji, svaki element je identificiran terminom koji se naziva "potpis." Svakoj stavci dodijeljen je jedinstveni indeks, a podaci se mogu manipulirati ili dohvaćati pozivanjem na taj jedinstveni indeks.
Kolekcije su najkorisnije kada je potrebno obraditi ili manipulirati velikom količinom podataka iste vrste. Kolekcije se mogu popuniti i manipulirati kao cjelina pomoću opcije 'BULK' u Oracle.
Kolekcije su klasificirane na temelju strukture, indeksa i pohrane, kao što je prikazano u nastavku:
- Tablice s indeksom (također poznate kao asocijativni nizovi)
- Ugniježđene tablice
- Varrays
U bilo kojem trenutku, podaci u kolekciji mogu se opisati pomoću tri termina: naziva kolekcije, indeksa i naziva polja ili stupca, kao što je " ( ). ". O ovim kategorijama zbirki saznat ćete više u odjeljcima u nastavku.
Vrste zbirki na prvi pogled
Tri vrste zbirki imaju različite prednosti. Tablica u nastavku ih navodi jednu pored druge prije nego što se svaka detaljnije obradi.
| Aspekt | Varray | Ugniježđena tablica | Tablica s indeksom |
|---|---|---|---|
| Veličina | Fiksna gornja granica | Nema granica | Nema granica |
| Potpisan | Numerički | Numerički | Cijeli broj ili niz znakova |
| Gustoća | Uvijek gusto | Gusto ili rijetko | Uvijek rijetko |
| Pohranjeno u bazi podataka | Da | Da | Ne |
| Potrebna je inicijalizacija | Da | Da | Ne |
Varrays
Varray je kolekcija u kojoj je veličina polja fiksna i ne može se prekoračiti. Indeks Varray-a je numerička vrijednost. Atributi Varray-a su:
- Gornja granica veličine je fiksna.
- Popunjava se sekvencijalno počevši od indeksa '1'.
- Ovaj tip kolekcije je uvijek gust; ne možemo brisati pojedinačne elemente niza. Varray se može izbrisati u cijelosti ili odrezati od kraja.
- Budući da je uvijek gust, ima vrlo malo fleksibilnosti.
- Prikladnije je kada je veličina polja poznata i slične aktivnosti se izvode na svim elementima.
- Indeks i broj u kolekciji uvijek ostaju stabilni.
- Mora se inicijalizirati prije upotrebe. Bilo koja operacija osim EXISTS na neinicijaliziranoj kolekciji izbacuje grešku.
- Može se kreirati kao objekt baze podataka vidljiv u cijeloj bazi podataka ili unutar potprograma za upotrebu samo tamo.
Donja slika objašnjava alokaciju memorije za Varray (gustu).
| Potpisan | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| Još malo brojeva | X Y Z | Dfv | Sde | Cxs | Vbc | Mekana | Qwe |
Sintaksa za VARRAY:
TYPE <type_name> IS VARRAY (<SIZE>) OF <DATA_TYPE>;
- U gornjoj sintaksi, naziv_typea je deklariran kao VARRAY tipa 'DATA_TYPE' za zadano ograničenje veličine. Tip podataka može biti jednostavan ili složen.
Ugniježđene tablice
Ugniježđena tablica je kolekcija u kojoj veličina polja nije fiksna. Ima numerički tip indeksa. Više o tipu ugniježđene tablice:
- Ugniježđena tablica nema gornju granicu veličine.
- Budući da gornja granica nije fiksna, memoriju je potrebno proširiti svaki put prije upotrebe pomoću ključne riječi 'EXTEND'.
- Popunjava se sekvencijalno počevši od indeksa '1'.
- Ova vrsta kolekcije može biti oboje gusta i rijetka; možemo ga stvoriti kao gustog, a također i nasumično brisati pojedinačne elemente, što ga čini rijetkim.
- Pruža veću fleksibilnost za brisanje elemenata niza.
- Pohranjuje se u tablici baze podataka koju generira sustav i može se koristiti u upitu za odabir za dohvaćanje vrijednosti.
- Indeks i broj mogu varirati.
- Mora se inicijalizirati prije upotrebe. Bilo koja operacija osim EXISTS na neinicijaliziranoj kolekciji izbacuje grešku.
- Može se kreirati kao objekt baze podataka vidljiv u cijeloj bazi podataka ili unutar potprograma za upotrebu samo tamo.
Donja slika objašnjava alokaciju memorije ugniježđene tablice (guste i rijetke). Prazan prostor elemenata označava rijedak element.
| Potpisan | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| Vrijednost (gusta) | X Y Z | Dfv | Sde | Cxs | Vbc | Mekana | Qwe |
| Vrijednost (rijetka) | Qwe | asd | Afg | asd | Wer |
Sintaksa za ugniježđenu tablicu:
TYPE <type_name> IS TABLE OF <DATA_TYPE>;
- U gornjoj sintaksi, naziv_typea je deklariran kao ugniježđena kolekcija tablica tipa 'DATA_TYPE'. Tip podataka može biti jednostavan ili složen.
Tablica s indeksom
Indeksna tablica je kolekcija u kojoj veličina polja nije fiksna. Za razliku od drugih vrsta kolekcija, indeks indeksne tablice može definirati korisnik. Atributi indeksne tablice su:
- Indeks može biti cijeli broj ili niz znakova. Tip indeksa treba spomenuti prilikom stvaranja kolekcije.
- Ove zbirke se ne pohranjuju uzastopno.
- U prirodi su uvijek rijetki.
- Veličina niza nije fiksna.
- Ne mogu se pohraniti u stupac baze podataka. Stvaraju se i koriste unutar određene sesije.
- Pružaju veću fleksibilnost u održavanju indeksa.
- Indeksi mogu biti negativni niz.
- Prikladniji su za relativno manje vrijednosti kolekcija korištene unutar istog potprograma.
- Nije ih potrebno inicijalizirati prije upotrebe.
- Ne mogu se kreirati kao objekt baze podataka; kreiraju se samo unutar potprograma.
- SKUPNO PRIKUPLJANJE ne može se koristiti s ovom vrstom kolekcije jer se indeks mora eksplicitno navesti za svaki zapis.
Donja slika objašnjava alokaciju memorije tablice indeksiranja (rijetka). Prazan prostor elemenata označava rijedak element.
| indeks (varchar) | PRVI | DRUGI | TREĆA | ČETVRTI | PETI | ŠESTI | SEDMI |
| Vrijednost (rijetka) | Qwe | asd | Afg | asd | Wer |
Sintaksa za tablicu indeksiranja:
TYPE <type_name> IS TABLE OF <DATA_TYPE> INDEX BY VARCHAR2 (10);
- U gornjoj sintaksi, type_name je deklariran kao kolekcija tablica tipa 'DATA_TYPE' po indeksu. Varijabla indeksa je zadana kao tip VARCHAR2 s maksimalnom veličinom od 10.
Konstruktor i koncept inicijalizacije u zbirkama
Konstruktori su ugrađene funkcije koje pruža Oracle koji imaju isto ime kao objekt ili kolekcija. Izvršavaju se prvi kad god se na objekt ili kolekciju prvi put poziva u sesiji. Važni detalji konstruktora u kontekstu kolekcije:
- Za kolekcije, ovi konstruktori moraju se eksplicitno pozvati za inicijalizaciju kolekcije.
- I Varray i ugniježđene tablice moraju se inicijalizirati putem ovih konstruktora prije nego što se na njih pozove program.
- Konstruktor implicitno proširuje alokaciju memorije za kolekciju (osim Varray), tako da može i dodijeliti varijable kolekciji.
- Dodjeljivanje vrijednosti putem konstruktora nikada ne čini kolekciju rijetkom.
Metode prikupljanja
Oracle pruža mnoge funkcije za manipuliranje i rad s kolekcijama. Ove funkcije određuju i mijenjaju različite atribute kolekcije. Tablica u nastavku daje različite funkcije i njihove opise.
| način | Description | Sintaksa |
|---|---|---|
| POSTOJI (n) | Vraća logičku vrijednost. Vraća TRUE ako n-ti element postoji, inače FALSE. Samo EXISTS se može koristiti na neinicijaliziranoj kolekciji. | .EXISTS(pozicija_elementa) |
| TOČKA | Daje ukupan broj elemenata prisutnih u kolekciji. | .RAČUNATI |
| OGRANIČAVA | Vraća maksimalnu veličinu kolekcije. Za Varray vraća fiksnu veličinu; za ugniježđene i indeksirane tablice vraća NULL. | .OGRANIČITI |
| PRVI | Vraća vrijednost prvog indeksa kolekcije. | .PRVI |
| LAST | Vraća vrijednost posljednjeg indeksa kolekcije. | .POSLJEDNJI |
| PRIJE (n) | Vraća prethodni indeks n-tog elementa. Ako ga nema, vraća se NULL. | .PRIJED(n) |
| DALJE (n) | Vraća sljedeći indeks n-tog elementa. Ako ga nema, vraća se NULL. | .DALJE(n) |
| PRODUŽI | Proširuje jedan element na kraju kolekcije. | .PRODUŽITI |
| PRODUŽITI (n) | Proširuje n elemenata na kraju kolekcije. | .EXTEND(n) |
| PRODUŽITI (n,i) | Proširuje n kopija i-tog elementa na kraju kolekcije. | .EXTEND(n,i) |
| TRIM | Uklanja jedan element s kraja kolekcije. | .STRIM |
| TRIM (n) | Uklanja n elemenata s kraja kolekcije. | .TRIM (n) |
| DELETE | Briše sve elemente iz kolekcije, čineći je praznom. | .IZBRISATI |
| IZBRIŠI (n) | Briše n-ti element. Ako je n-ti element NULL, ne radi ništa. | .DELETE(n) |
| IZBRIŠI (m,n) | Briše elemente u rasponu od m-tog do n-tog u kolekciji. | .DELETE(m,n) |
Primjer 1: Vrsta zapisa na razini potprograma
U ovom primjeru vidimo kako popuniti kolekciju pomoću 'RASINSKO SAKUPLJANJE' i kako se pozivati na podatke o prikupljanju.
DECLARE TYPE emp_det IS RECORD ( EMP_NO NUMBER, EMP_NAME VARCHAR2(150), MANAGER NUMBER, SALARY NUMBER ); TYPE emp_det_tbl IS TABLE OF emp_det; guru99_emp_rec emp_det_tbl:= emp_det_tbl(); BEGIN INSERT INTO emp (emp_no,emp_name, salary, manager) VALUES (1000,'AAA',25000,1000); INSERT INTO emp (emp_no,emp_name, salary, manager) VALUES (1001,'XXX',10000,1000); INSERT INTO emp (emp_no, emp_name, salary, manager) VALUES (1002,'YYY',15000,1000); INSERT INTO emp (emp_no,emp_name,salary, manager) VALUES (1003,'ZZZ',7500,1000); COMMIT; SELECT emp_no,emp_name,manager,salary BULK COLLECT INTO guru99_emp_rec FROM emp; dbms_output.put_line ('Employee Detail'); FOR i IN guru99_emp_rec.FIRST..guru99_emp_rec.LAST LOOP dbms_output.put_line ('Employee Number: '||guru99_emp_rec(i).emp_no); dbms_output.put_line ('Employee Name: '||guru99_emp_rec(i).emp_name); dbms_output.put_line ('Employee Salary:'|| guru99_emp_rec(i).salary); dbms_output.put_line('Employee Manager Number:'||guru99_emp_rec(i).manager); dbms_output.put_line('--------------------------------'); END LOOP; END; /
Code Objašnjenje
- Code redak 2-8: Vrsta zapisa 'emp_det' je deklariran sa stupcima emp_no, emp_name, manager i salary tipa podataka NUMBER, VARCHAR2, NUMBER i NUMBER.
- Code redak 9: Izrada kolekcije 'emp_det_tbl' elementa tipa zapisa 'emp_det'.
- Code redak 10: Deklariranje varijable 'guru99_emp_rec' kao tipa 'emp_det_tbl' i inicijalizacija s null konstruktorom.
- Code redak 12-15: Umetanje uzorka podataka u 'emp' tablicu.
- Code redak 16: Izvršavanje transakcije umetanja.
- Code redak 17: Dohvaćanje zapisa iz tablice 'emp' i popunjavanje varijable kolekcije skupno pomoću "BULK COLLECT". Varijabla 'guru99_emp_rec' sada sadrži sve zapise prisutne u tablici 'emp'.
- Code redak 19-26: Postavljanje petlje 'FOR' za ispis svih zapisa u kolekciji jedan po jedan. Metode kolekcije FIRST i LAST koriste se kao donja i gornja granica petlja.
Izlaz: Kada se izvrši gornji kod, dobijete sljedeći izlaz.
Employee Detail Employee Number: 1000 Employee Name: AAA Employee Salary: 25000 Employee Manager Number: 1000 ---------------------------------------------- Employee Number: 1001 Employee Name: XXX Employee Salary: 10000 Employee Manager Number: 1000 ---------------------------------------------- Employee Number: 1002 Employee Name: YYY Employee Salary: 15000 Employee Manager Number: 1000 ---------------------------------------------- Employee Number: 1003 Employee Name: ZZZ Employee Salary: 7500 Employee Manager Number: 1000 ----------------------------------------------

