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

⚡ Smart oppsummering

PL/SQL-samlinger er ordnede grupper av elementer av samme datatype, som hver nås av et indeksert tabell. Tre typer, Varray, nestet tabell og indeksert tabell, skiller seg ut i om størrelsen er fast, hvordan indeksert tabell fungerer og om de kan lagres i databasen.

  • 🧺 Definisjon: En samling inneholder mange elementer av én type, som hver identifiseres av et unikt indeksnummer.
  • 📐 Varray: Fast øvre størrelse, alltid tett, numerisk senket skrift, må initialiseres før bruk.
  • 📚 Nestet tabell: Ingen størrelsesgrense, kan være tett eller sparsom, lagret i en systemtabell, utvidet med EXTEND.
  • 🔑 Indeksert etter tabell: Ingen størrelsesbegrensning, senket skript kan være en streng eller et negativt heltall, ikke lagret i databasen.
  • 🏗️ Konstruktør: Varray og nestet tabell trenger en eksplisitt konstruktør for å initialisere før referanse.
  • 🛠️ Metoder: COUNT, EXISTS, FIRST, LAST, EXTEND, TRIM og DELETE administrerer en samling.
  • Bulk: BULK COLLECT fyller ut en samling i ett trinn for rask behandling.

Oracle PL/SQL-samlinger

Hva er en samling?

En samling er en ordnet gruppe av elementer av en bestemt datatype. Det kan være en samling av en enkel datatype eller en kompleks datatype, for eksempel brukerdefinerte datatyper eller posttyper.

I en samling identifiseres hvert element med et begrep som kalles en "subscript." Hvert element er tilordnet et unikt abonnement, og dataene kan manipuleres eller hentes ved å referere til det unike abonnementet.

Samlinger er mest nyttige når en stor mengde data av samme type må behandles eller manipuleres. Samlinger kan fylles ut og manipuleres som en helhet ved å bruke alternativet «MASSE» i Oracle.

Samlinger klassifiseres basert på struktur, abonnement og lagring, som vist nedenfor:

  • Indekserte tabeller (også kjent som assosiative matriser)
  • Nestede bord
  • Varrays

Data i en samling kan når som helst refereres til med tre termer: samlingsnavn, indeks og felt- eller kolonnenavn, som « ( ). Du vil lære om disse samlingskategoriene i avsnittene nedenfor.

Oversikt over samlingstyper

De tre samlingstypene har ulike avveininger. Tabellen nedenfor viser dem side om side før hver enkelt blir dekket i detalj.

Aspekt Varray Nestet tabell Indekser etter tabell
Størrelse Fast øvre grense Ingen grense Ingen grense
Senket Numerisk Numerisk Heltall eller streng
Tetthet Alltid tett Tett eller sparsom Alltid sparsom
Lagret i databasen Ja Ja Nei
Trenger initialisering Ja Ja Nei

Varrays

En Varray er en samling der størrelsen på tabellen er fast og ikke kan overskrides. Indekset til en Varray er en numerisk verdi. Attributtene til Varrayer er:

  • Den øvre grensen for størrelsen er fast.
  • Fylles ut sekvensielt, startende med senket '1'.
  • Denne samlingstypen er alltid tett; vi kan ikke slette individuelle array-elementer. En Varray kan slettes som en helhet eller trimmes fra slutten.
  • Fordi den alltid er tett, har den svært liten fleksibilitet.
  • Det er mer passende når arraystørrelsen er kjent og lignende aktiviteter utføres på alle elementene.
  • Samlingens abonnement og antall forblir alltid stabilt.
  • Den må initialiseres før bruk. Enhver operasjon unntatt EXISTS på en uinitialisert samling gir en feil.
  • Den kan opprettes som et databaseobjekt som er synlig i hele databasen, eller i et underprogram for bruk kun der.

Figuren nedenfor forklarer minneallokeringen til en Varray (tett).

Senket 1 2 3 4 5 6 7
Verdi X Y Z Dfv Sde Cxs Vbc Myk Qwe

Syntaks for VARRAY:

TYPE <type_name> IS VARRAY (<SIZE>) OF <DATA_TYPE>;
  • I syntaksen ovenfor er type_name deklarert som en VARRAY av typen 'DATA_TYPE' for den gitte størrelsesgrensen. Datatypen kan være enten enkel eller kompleks.

Nestede tabeller

En nestet tabell er en samling der størrelsen på tabellen ikke er fast. Den har en numerisk indeksert type. Mer om den nestede tabelltypen:

  • Den nestede tabellen har ingen øvre størrelsesgrense.
  • Fordi den øvre grensen ikke er fast, må minnet utvides hver gang før bruk, ved å bruke nøkkelordet 'EXTEND'.
  • Fylles ut sekvensielt, startende med senket '1'.
  • Denne samlingstypen kan være begge deler tett og sparsomt; vi kan lage den som tett og også slette individuelle elementer tilfeldig, noe som gjør den sparsom.
  • Det gir mer fleksibilitet for å slette array-elementer.
  • Den lagres i en systemgenerert databasetabell og kan brukes i en utvalgsspørring for å hente verdier.
  • Subskriptet og antallet kan variere.
  • Den må initialiseres før bruk. Enhver operasjon unntatt EXISTS på en uinitialisert samling gir en feil.
  • Den kan opprettes som et databaseobjekt som er synlig i hele databasen, eller i et underprogram for bruk kun der.

Figuren nedenfor forklarer minneallokeringen til en nestet tabell (tett og sparsom). Et tomt elementrom betegner et sparsomt element.

Senket 1 2 3 4 5 6 7
Verdi (tett) X Y Z Dfv Sde Cxs Vbc Myk Qwe
Verdi (sparsom) Qwe asd Afg asd Wer

Syntaks for nestet tabell:

TYPE <type_name> IS TABLE OF <DATA_TYPE>;
  • I syntaksen ovenfor er type_navn deklarert som en nestet tabellsamling av typen 'DATA_TYPE'. Datatypen kan være enten enkel eller kompleks.

Indekser etter tabell

En indeksert tabell er en samling der arraystørrelsen ikke er fast. I motsetning til andre samlingstyper kan indeksen til en indeksert tabell defineres av brukeren. Attributtene til en indeksert tabell er:

  • Indekset kan være et heltall eller en streng. Indekstypen bør nevnes når samlingen opprettes.
  • Disse samlingene lagres ikke sekvensielt.
  • De er alltid sparsomme i naturen.
  • Matrisestørrelsen er ikke fast.
  • De kan ikke lagres i en databasekolonne. De opprettes og brukes i en bestemt økt.
  • De gir mer fleksibilitet i vedlikeholdet av abonnementet.
  • Indeksene kan være en negativ sekvens.
  • De er mer passende for relativt mindre samlingsverdier som brukes i samme underprogram.
  • De trenger ikke å initialiseres før bruk.
  • De kan ikke opprettes som et databaseobjekt; de opprettes bare i et underprogram.
  • BULK COLLECT kan ikke brukes med denne samlingstypen, fordi abonnementet må oppgis eksplisitt for hver post.

Figuren nedenfor forklarer minneallokeringen til en indeksert tabell (spars). Et tomt elementrom betegner et spars element.

Subscript (varchar) FØRST SECOND TREDJE FJERDE FEMTE SJETTE SYVENDE
Verdi (sparsom) Qwe asd Afg asd Wer

Syntaks for indeksert tabell:

TYPE <type_name> IS TABLE OF <DATA_TYPE> INDEX BY VARCHAR2 (10);
  • I syntaksen ovenfor er type_name deklarert som en indeksert tabellsamling av typen 'DATA_TYPE'. Den indekserte variabelen er gitt som VARCHAR2-typen med en maksimal størrelse på 10.

Konstruktør og initialiseringskonsept i samlinger

Konstruktører er innebygde funksjoner levert av Oracle som har samme navn som objektet eller samlingen. De kjøres først hver gang et objekt eller en samling refereres til for første gang i en økt. Viktige detaljer om en konstruktør i samlingskonteksten:

  • For samlinger må disse konstruktørene kalles eksplisitt for å initialisere samlingen.
  • Både Varray- og nestede tabeller må initialiseres gjennom disse konstruktørene før de refereres til i programmet.
  • En konstruktør utvider implisitt minneallokeringen for en samling (unntatt Varray), slik at den også kan tilordne variabler til samlingen.
  • Å tilordne verdier gjennom konstruktører gjør aldri samlingen sparsom.

Innsamlingsmetoder

Oracle tilbyr mange funksjoner for å manipulere og arbeide med samlinger. Disse funksjonene bestemmer og endrer de ulike attributtene til en samling. Tabellen nedenfor viser de ulike funksjonene og beskrivelsene av dem.

Metode Tekniske beskrivelser syntax
FINNES (n) Returnerer et boolsk resultat. Returnerer TRUE hvis det n-te elementet finnes, ellers FALSE. Bare EXISTS kan brukes på en uinitialisert samling. .EXISTS(element_posisjon)
COUNT Gir det totale antallet elementer som finnes i en samling. .TELLE
BEGRENSE Returnerer samlingens maksimale størrelse. For Varray returneres den faste størrelsen; for nestede og indekserte tabeller returneres NULL. .BEGRENSE
FØRST Returnerer verdien til det første abonnementet i samlingen. .FØRST
SISTE Returnerer verdien til det siste indeksen i samlingen. .SISTE
PRIOR (n) Returnerer det foregående subskriptet til det n-te elementet. Hvis ingen, returneres NULL. .PRIOR(n)
NESTE (n) Returnerer det påfølgende indekset for det n-te elementet. Hvis ingen, returneres NULL. .NESTE(n)
FORLENGE Utvider ett element på slutten av en samling. .FORLENGE
FORLENG (n) Utvider n elementer på slutten av en samling. .EXTEND(n)
FORLENG (n,i) Utvider n kopier av det i-te elementet på slutten av samlingen. .EXTEND(n,i)
TRIM Fjerner ett element fra slutten av samlingen. .TRIM
TRIM (n) Fjerner n elementer fra slutten av samlingen. .TRIM (n)
SLETT Sletter alle elementer fra samlingen, og gjør den tom. .SLETT
SLETT (n) Sletter det n-te elementet. Hvis det n-te elementet er NULL, skjer ingenting. .DELETE(n)
SLETT (m,n) Sletter elementene i området mth til nth i samlingen. .DELETE(m,n)

Eksempel 1: Posttype på underprogramnivå

I dette eksemplet ser vi hvordan man fyller ut samlingen ved hjelp av 'MASSESAMLINGog hvordan man refererer til samlingsdataene.

PL/SQL-samling fylt ut med BULK COLLECT-eksempel

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 Forklaring

  • Code linje 2–8: Record type 'emp_det' deklareres med kolonnene emp_no, emp_name, manager og salary av datatypene NUMBER, VARCHAR2, NUMBER og NUMBER.
  • Code linje 9: Oppretter samlingen 'emp_det_tbl' av posttypeelementet 'emp_det'.
  • Code linje 10: Deklarerer variabelen 'guru99_emp_rec' som typen 'emp_det_tbl' og initialiserer den med en nullkonstruktør.
  • Code linje 12–15: Setter inn eksempeldataene i 'emp'-tabellen.
  • Code linje 16: Begår innsettingstransaksjonen.
  • Code linje 17: Henter postene fra tabellen 'emp' og fyller ut samlingsvariabelen samtidig ved hjelp av «BULK COLLECT». Variabelen 'guru99_emp_rec' inneholder nå alle postene som finnes i tabellen 'emp'.
  • Code linje 19–26: Setter «FOR»-løkken til å skrive ut alle postene i samlingen én etter én. Innsamlingsmetodene FIRST og LAST brukes som nedre og øvre grenser for sløyfe.

Utgang: Når koden ovenfor kjøres, får du følgende utdata.

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

Spørsmål og svar

En Varray har en fast øvre størrelse og er alltid tett. En nestet tabell har ingen størrelsesgrense, kan være sparsom og kan utvides, noe som gjør den mer fleksibel for voksende eller gapende data.

Fordi det er en assosiativ matrise i minnet, ikke en lagret tabell. Senkeskriptet fungerer som en oppslagsnøkkel, så en streng eller et negativt heltall fungerer, noe som er nyttig for nøkkelbaserte oppslag i en økt.

En uinitialisert Varray eller nestet tabell er atomisk null, så referanse til et element genererer en feil. Kalling av konstruktøren allokerer det, hvoretter EXTEND og tildelinger kan legge til data.

Ja. Gitt om størrelsen er fast, om dataene er lagret og om en strengnøkkel er nødvendig, kan AI peke på en Varray, en nestet tabell eller en indeksert tabell og forklare avveiningen.

BULK COLLECT laster alle rader inn i en samling i en enkelt kontekstbryter mellom SQL- og PL/SQL-motorene, i stedet for én bryter per rad, noe som reduserer overhead betraktelig på store resultatsett.

Oppsummer dette innlegget med: