Oracle PL/SQL-samlinger: Varrays, Nested & Index by Tables

Hvad er samling?

En samling er en ordnet gruppe af elementer af bestemte datatyper. Det kan vรฆre en samling af simple datatyper eller komplekse datatyper (som brugerdefinerede eller registreringstyper).

I samlingen er hvert element identificeret med et udtryk kaldet "subscript." Hvert element i samlingen er tildelt et unikt abonnement. Dataene i denne samling kan manipuleres eller hentes ved at henvise til det unikke subscript.

Samlinger er mest nyttige ting, nรฅr store data af samme type skal behandles eller manipuleres. Samlinger kan udfyldes og manipuleres som helhed ved at bruge 'BULK'-indstillingen i Oracle.

Samlinger klassificeres baseret pรฅ strukturen, abonnementet og lagringen som vist nedenfor.

  • Indeks-for-tabeller (ogsรฅ kendt som Associative Array)
  • Indlejrede borde
  • Varrays

Pรฅ ethvert tidspunkt kan data i samlingen henvises til med tre termer Samlingsnavn, Subscript, Felt/Kolonnenavn som " ( ). โ€. Du kommer til at lรฆre om disse ovennรฆvnte samlingskategorier lรฆngere i nedenstรฅende afsnit.

Varrays

Varray er en indsamlingsmetode, hvor stรธrrelsen af โ€‹โ€‹arrayet er fastsat. Matrixstรธrrelsen kan ikke overskrides end dens faste vรฆrdi. Varray'ens underskrift har en numerisk vรฆrdi. Fรธlgende er egenskaberne for Varrays.

  • Den รธvre grรฆnsestรธrrelse er fast
  • Udfyldes sekventielt startende med sรฆnket "1"
  • Denne samlingstype er altid tรฆt, dvs. vi kan ikke slette nogen array-elementer. Varray kan slettes som en helhed, eller den kan trimmes fra slutningen.
  • Da det altid er tรฆt i naturen, har det meget mindre fleksibilitet.
  • Det er mere passende at bruge, nรฅr array-stรธrrelsen er kendt, og at udfรธre lignende aktiviteter pรฅ alle array-elementerne.
  • Sรฆnkningen og sekvensen forbliver altid stabile, dvs. sรฆnkningen og antallet af samlingen er altid det samme.
  • De skal initialiseres, fรธr de bruges i programmer. Enhver handling (undtagen EXISTS operation) pรฅ en ikke-initialiseret samling vil give en fejl.
  • Det kan oprettes som et databaseobjekt, som er synligt i hele databasen eller inde i underprogrammet, som kun kan bruges i det underprogram.

Nedenstรฅende figur vil forklare hukommelsesallokeringen af โ€‹โ€‹Varray (tรฆt) diagrammatisk.

Sรฆnket 1 2 3 4 5 6 7
Vรฆrdi xyz Dfv Sde Cxs Vbc Blรธd Qwe

Syntaks for VARRAY:

TYPE <type_name> IS VARRAY (<SIZE>) OF <DATA_TYPE>;
  • I ovenstรฅende syntaks er typenavn erklรฆret som VARRAY af typen 'DATA_TYPE' for den givne stรธrrelsesgrรฆnse. Datatypen kan enten vรฆre enkel eller kompleks.

Indlejrede tabeller

En indlejret tabel er en samling, hvor stรธrrelsen af โ€‹โ€‹arrayet ikke er fastsat. Den har den numeriske subscripttype. Nedenfor er flere beskrivelser om indlejret tabeltype.

  • Det indlejrede bord har ingen รธvre stรธrrelsesgrรฆnse.
  • Da den รธvre stรธrrelsesgrรฆnse ikke er fast, skal samlingen, hukommelsen udvides hver gang, fรธr vi bruger den. Vi kan udvide samlingen ved at bruge 'EXTEND' nรธgleordet.
  • Udfyldes sekventielt startende med sรฆnket "1".
  • Denne samlingstype kan vรฆre af begge tรฆt og sparsomt, dvs. vi kan oprette samlingen som en tรฆt, og vi kan ogsรฅ slette det enkelte array-element tilfรฆldigt, hvilket gรธr det sรฅ sparsomt.
  • Det giver mere fleksibilitet med hensyn til sletning af array-elementet.
  • Den er gemt i den systemgenererede databasetabel og kan bruges i valgforespรธrgslen til at hente vรฆrdierne.
  • Sรฆnkningen og sekvensen er ikke stabile, dvs. sรฆnkningen og antallet af array-elementet kan variere.
  • De skal initialiseres, fรธr de bruges i programmer. Enhver operation (undtagen EXISTS operation) pรฅ den ikke-initialiserede samling vil give en fejl.
  • Det kan oprettes som et databaseobjekt, som er synligt i hele databasen eller inde i underprogrammet, som kun kan bruges i det underprogram.

Nedenstรฅende figur vil forklare hukommelsesallokeringen af โ€‹โ€‹Nested Table (tรฆt og sparsom) diagrammatisk. Det sortfarvede elementrum angiver det tomme element i en samling, dvs. sparsomt.

Sรฆnket 1 2 3 4 5 6 7
Vรฆrdi (tรฆt) xyz Dfv Sde Cxs Vbc Blรธd Qwe
Vรฆrdi (sparsom) Qwe asd Afg asd Wer

Syntaks for indlejret tabel:

TYPE <tvpe name> IS TABLE OF <DATA TYPE>;
  • I ovenstรฅende syntaks er typenavn erklรฆret som indlejret tabelsamling af typen 'DATA_TYPE'. Datatypen kan enten vรฆre enkel eller kompleks.

Indeks-for-tabel

Indeks-for-tabel er en samling, hvor array-stรธrrelsen ikke er fast. I modsรฆtning til de andre samlingstyper kan subscriptet i indeks-for-tabel-samlingen bestรฅ defineres af brugeren. Fรธlgende er egenskaberne for indeks-for-tabel.

  • Den sรฆnkede kan af heltal eller strenge. Pรฅ tidspunktet for oprettelse af samlingen skal abonnenttypen nรฆvnes.
  • Disse samlinger gemmes ikke sekventielt.
  • De er altid sparsomme i naturen.
  • Matrixstรธrrelsen er ikke fast.
  • De kan ikke gemmes i databasekolonnen. De skal oprettes og bruges i ethvert program i den pรฅgรฆldende session.
  • De giver mere fleksibilitet i forhold til at opretholde abonnement.
  • Sรฆnkningen kan ogsรฅ vรฆre af negativ sรฆnket sekvens.
  • De er mere passende at bruge til relativt mindre kollektive vรฆrdier, hvor samlingen kan initialiseres og bruges inden for de samme underprogrammer.
  • De behรธver ikke initialiseres, fรธr du begynder at bruge dem.
  • Det kan ikke oprettes som et databaseobjekt. Det kan kun oprettes inde i underprogrammet, som kun kan bruges i det underprogram.
  • BULK COLLECT kan ikke bruges i denne samlingstype, da subscriptet skal angives eksplicit for hver post i samlingen.

Nedenstรฅende figur vil forklare hukommelsesallokeringen af โ€‹โ€‹Nested Table (spare) diagrammatisk. Det sortfarvede elementrum angiver det tomme element i en samling, dvs. sparsomt.

Subscript (varchar) Fร˜RST ANDEN TREDJE FJERDE Femte SJETTE SYVENDE
Vรฆrdi (sparsom) Qwe asd Afg asd Wer

Syntaks for indeks-for-tabel

TYPE <type_name> IS TABLE OF <DATA_TYPE> INDEX BY VARCHAR2 (10);
  • I ovenstรฅende syntaks er typenavn erklรฆret som en indeks-for-tabel samling af typen 'DATA_TYPE'. Datatypen kan enten vรฆre enkel eller kompleks. Subsciprt/indeksvariablen er angivet som VARCHAR2-type med maksimal stรธrrelse som 10.

Konstruktรธr og initialiseringskoncept i samlinger

Konstruktรธrer er den indbyggede funktion leveret af oraklet, der har samme navn som objektet eller samlingerne. De udfรธres fรธrst, nรฅr objekt eller samlinger henvises for fรธrste gang i en session. Nedenfor er de vigtige detaljer om konstruktรธr i samlingssammenhรฆng:

  • For samlinger bรธr disse konstruktรธrer kaldes eksplicit for at initialisere den.
  • Bรฅde Varray- og Nested-tabeller skal initialiseres gennem disse konstruktรธrer, fรธr de henvises til programmet.
  • Constructor udvider implicit hukommelsesallokeringen for en samling (undtagen Varray), og derfor kan konstruktรธren ogsรฅ tildele variablerne til samlingerne.
  • At tildele vรฆrdier til samlingen gennem konstruktรธrer vil aldrig gรธre samlingen sparsom.

Indsamlingsmetoder

Oracle giver mange funktioner til at manipulere og arbejde med samlingerne. Disse funktioner er meget nyttige i programmet til at bestemme og รฆndre samlingernes forskellige egenskaber. Den fรธlgende tabel vil give de forskellige funktioner og deres beskrivelse.

Metode Beskrivelse SYNTAKS
FINDER (n) Denne metode vil returnere booleske resultater. Det vil returnere 'TRUE' hvis nth element findes i den samling, ellers vil det returnere FALSE. Kun EXISTS-funktioner kan bruges i uinitialiseret samling .EXISTS(element_position)
COUNT Giver det samlede antal af elementerne i en samling .Tร†LLE
GRร†NSE Det returnerer samlingens maksimale stรธrrelse. For Varray vil den returnere den faste stรธrrelse, der er blevet defineret. For indlejrede tabel og indeks-for-tabel giver det NULL .BEGRร†NSE
Fร˜RST Returnerer vรฆrdien af โ€‹โ€‹den fรธrste indeksvariabel (sรฆnket) af samlingerne .Fร˜RST
LAST Returnerer vรฆrdien af โ€‹โ€‹den sidste indeksvariabel (sรฆnket) af samlingerne .SIDST
FORUD (n) Returnerer gรฅr forud for indeksvariabel i en samling af nth element. Hvis der ikke er nogen forudgรฅende indeksvรฆrdi returneres NULL .PRIOR(n)
Nร†STE (n) Returnerer efterfรธlger indeksvariabel i en samling af nth element. Hvis der ikke er nogen succes, returneres indeksvรฆrdien NULL .Nร†STE(n)
FORLร†NGE Udvider รฉt element i en samling i slutningen .FORLร†NGE
FORLร†NG (n) Udvider n elementer i slutningen af โ€‹โ€‹en samling .EXTEND(n)
FORLร†NG (n,i) Udvider n kopier af ith element i slutningen af โ€‹โ€‹samlingen .EXTEND(n,i)
TRIMME Fjerner รฉt element fra slutningen af โ€‹โ€‹samlingen .TRIMME
TRIM (n) Fjerner n elementer fra slutningen af โ€‹โ€‹samlingen .TRIM (n)
SLET Sletter alle elementer fra samlingen. Gรธr samlingen tom .SLET
SLET (n) Sletter det n'te element fra samlingen. Hvis sรฅth element er NULL, sรฅ vil dette ikke gรธre noget .DELETE(n)
SLET (m,n) Sletter elementet i omrรฅdet mth denne nth i samlingen .DELETE(m,n)

Eksempel 1: Optagetype pรฅ underprogramniveau

I dette eksempel skal vi se, hvordan man udfylder samlingen ved hjรฆlp af 'MASSEINDSAMLING' og hvordan man henviser til indsamlingsdataene.

Record Type pรฅ underprogramniveau

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;
/

Kodeforklaring:

  • Kodelinje 2-8: Record type 'emp_det' er deklareret med kolonnerne emp_no, emp_name, lรธn og manager af datatype NUMBER, VARCHAR2, NUMBER, NUMBER.
  • Kodelinje 9: Oprettelse af samlingen 'emp_det_tbl' af posttypeelementet 'emp_det'
  • Kodelinje 10: Erklรฆrer variablen 'guru99_emp_rec' som 'emp_det_tbl'-type og initialiseret med null-konstruktรธr.
  • Kodelinje 12-15: Indsรฆttelse af eksempeldata i 'emp'-tabellen.
  • Kodelinje 16: Forpligtelse af indsรฆttelsestransaktionen.
  • Kodelinje 17: Henter posterne fra 'emp'-tabellen og udfylder samlingsvariablen som en bulk ved hjรฆlp af kommandoen "BULK COLLECT". Nu indeholder variablen 'guru99_emp_rec' alle de poster, der er til stede i tabellen 'emp'.
  • Kodelinje 19-26: Indstilling af 'FOR'-lรธkken med at udskrive alle poster i samlingen รฉn for รฉn. Indsamlingsmetoden Fร˜RST og SIDST bruges som nedre og hรธjere grรฆnse for loop.

Produktion: Som du kan se pรฅ ovenstรฅende skรฆrmbillede, nรฅr ovenstรฅende kode udfรธres, fรฅr du fรธlgende output

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
----------------------------------------------

Opsummer dette indlรฆg med: