Oracle Collezioni PL/SQL: Varray, annidati e indicizzati per tabelle

⚡ Riepilogo intelligente

Le collezioni PL/SQL sono gruppi ordinati di elementi dello stesso tipo di dati, ciascuno raggiungibile tramite un indice. Tre tipi, Varray, tabella nidificata e tabella indicizzata, si differenziano per la dimensione fissa, il funzionamento dell'indice e la possibilità di memorizzarle nel database.

  • 🧺 Definizione: Una collezione contiene molti elementi di un unico tipo, ciascuno identificato da un indice univoco.
  • 📐 Varray: Dimensione massima fissa, sempre denso, indice numerico, deve essere inizializzato prima dell'uso.
  • 📚 Tabella annidata: Nessun limite di dimensione, può essere denso o sparso, memorizzato in una tabella di sistema, estendibile con EXTEND.
  • 🔑 Indice per tabella: Nessun limite di dimensione, l'indice può essere una stringa o un numero intero negativo, non memorizzato nel database.
  • ???? ️ Costruttore: Varray e tabelle annidate necessitano di un costruttore esplicito per l'inizializzazione prima di poter essere referenziate.
  • Metodi: Le funzioni COUNT, EXISTS, FIRST, LAST, EXTEND, TRIM e DELETE gestiscono una collezione.
  • Massa: BULK COLLECT popola una collezione in un'unica operazione per una rapida elaborazione.

Oracle Collezioni PL/SQL

Che cos'è una raccolta?

Una collezione è un gruppo ordinato di elementi di un particolare tipo di dati. Può essere una collezione di un tipo di dati semplice o di un tipo di dati complesso, come ad esempio tipi definiti dall'utente o tipi record.

In una collezione, ogni elemento è identificato da un termine chiamato “pedice”. A ciascun elemento viene assegnato un indice univoco e i dati possono essere manipolati o recuperati facendo riferimento a tale indice.

Le raccolte sono più utili quando è necessario elaborare o manipolare una grande quantità di dati dello stesso tipo. Le raccolte possono essere popolate e manipolate nel loro complesso utilizzando l'opzione 'BULK' in Oracle.

Le collezioni sono classificate in base alla struttura, all'indice e alla modalità di conservazione, come illustrato di seguito:

  • Tabelle indicizzate (note anche come array associativi)
  • Tabelle nidificate
  • Varray

In qualsiasi momento, i dati in una raccolta possono essere indicati tramite tre termini: nome della raccolta, indice e nome del campo o della colonna, come “ ). Nelle sezioni seguenti potrai approfondire queste categorie di collezioni.

Tipologie di collezioni in sintesi

Le tre tipologie di collezione comportano compromessi diversi. La tabella seguente le mette a confronto prima di analizzarle nel dettaglio.

Aspetto Varray Tavolo impilabile Indice per tabella
Taglia limite superiore fisso Nessun limite Nessun limite
deponente Numerico Numerico Numero intero o stringa
Densità Sempre denso Denso o sparso Sempre scarso
Memorizzato nel database Si Si Non
Necessita di inizializzazione Si Si Non

Varray

Un Varray è una collezione in cui la dimensione dell'array è fissa e non può essere superata. L'indice di un Varray è un valore numerico. Gli attributi dei Varray sono:

  • La dimensione limite superiore è fissa.
  • I numeri vengono inseriti in sequenza a partire dal pedice '1'.
  • Questo tipo di collezione è sempre denso; non è possibile eliminare singoli elementi dell'array. Un Varray può essere eliminato per intero o troncato alla fine.
  • Essendo sempre denso, ha pochissima flessibilità.
  • È più appropriato quando la dimensione dell'array è nota e si eseguono attività simili su tutti gli elementi.
  • L'indice e il conteggio della collezione rimangono sempre stabili.
  • Deve essere inizializzata prima dell'uso. Qualsiasi operazione diversa da EXISTS su una collezione non inizializzata genera un errore.
  • Può essere creato come oggetto di database visibile in tutto il database, oppure all'interno di una sottoprogramma per essere utilizzato solo in quel contesto.

La figura seguente illustra l'allocazione della memoria di un Varray (denso).

deponente 1 2 3 4 5 6 7
Valore Xyz Dfv Qui Cx Vbc Morbido qwe

Sintassi per VARRAY:

TYPE <type_name> IS VARRAY (<SIZE>) OF <DATA_TYPE>;
  • Nella sintassi sopra riportata, type_name viene dichiarato come un VARRAY di tipo 'DATA_TYPE' per il limite di dimensione specificato. Il tipo di dati può essere semplice o complesso.

Tabelle annidate

Una tabella nidificata è una collezione in cui la dimensione dell'array non è fissa. Ha un tipo di indice numerico. Ulteriori informazioni sul tipo di tabella nidificata:

  • La tabella annidata non ha un limite massimo di dimensione.
  • Poiché il limite superiore non è fisso, la memoria deve essere estesa ogni volta prima dell'uso, utilizzando la parola chiave 'EXTEND'.
  • I numeri vengono inseriti in sequenza a partire dal pedice '1'.
  • Questo tipo di collezione può essere sia denso e scarno; possiamo crearlo denso e anche eliminare singoli elementi in modo casuale, rendendolo sparso.
  • Offre maggiore flessibilità per l'eliminazione degli elementi dell'array.
  • Viene memorizzato in una tabella di database generata dal sistema e può essere utilizzato in una query SELECT per recuperare i valori.
  • L'indice e il conteggio possono variare.
  • Deve essere inizializzata prima dell'uso. Qualsiasi operazione diversa da EXISTS su una collezione non inizializzata genera un errore.
  • Può essere creato come oggetto di database visibile in tutto il database, oppure all'interno di una sottoprogramma per essere utilizzato solo in quel contesto.

La figura seguente illustra l'allocazione della memoria di una tabella annidata (densa e sparsa). Uno spazio vuoto indica un elemento sparso.

deponente 1 2 3 4 5 6 7
Valore (denso) Xyz Dfv Qui Cx Vbc Morbido qwe
Valore (sparso) qwe Asd afg Asd Chi

Sintassi per la tabella nidificata:

TYPE <type_name> IS TABLE OF <DATA_TYPE>;
  • Nella sintassi sopra riportata, type_name viene dichiarato come una raccolta di tabelle nidificate di tipo 'DATA_TYPE'. Il tipo di dati può essere semplice o complesso.

Indice per tabella

Una tabella indicizzata è una collezione in cui la dimensione dell'array non è fissa. A differenza di altri tipi di collezione, l'indice di una tabella indicizzata può essere definito dall'utente. Gli attributi di una tabella indicizzata sono:

  • L'indice può essere un numero intero o una stringa. Il tipo di indice deve essere specificato al momento della creazione della collezione.
  • Queste raccolte non vengono archiviate in sequenza.
  • Sono sempre sparsi in natura.
  • La dimensione dell'array non è fissa.
  • Non possono essere memorizzati in una colonna di un database. Vengono creati e utilizzati all'interno di una sessione specifica.
  • Offrono maggiore flessibilità nel mantenimento del pedice.
  • Gli indici possono essere in sequenza negativa.
  • Sono più adatti per valori di raccolta relativamente piccoli utilizzati all'interno dello stesso sottoprogramma.
  • Non è necessario inizializzarli prima dell'uso.
  • Non possono essere creati come oggetti di database; vengono creati solo all'interno di un sottoprogramma.
  • L'opzione BULK COLLECT non può essere utilizzata con questo tipo di raccolta, poiché l'indice deve essere specificato esplicitamente per ogni record.

La figura seguente illustra l'allocazione della memoria di una tabella indicizzata (sparsa). Uno spazio vuoto indica un elemento sparso.

Pedice (varchar) PRIMO SECONDA TERZO IL QUARTO QUINTO SESTO SETTIMO
Valore (sparso) qwe Asd afg Asd Chi

Sintassi per Indice per tabella:

TYPE <type_name> IS TABLE OF <DATA_TYPE> INDEX BY VARCHAR2 (10);
  • Nella sintassi sopra riportata, type_name è dichiarato come una raccolta di tabelle indicizzate di tipo 'DATA_TYPE'. La variabile di indice è di tipo VARCHAR2 con una dimensione massima di 10.

Costruttore e concetto di inizializzazione nelle raccolte

I costruttori sono funzioni integrate fornite da Oracle che hanno lo stesso nome dell'oggetto o della collezione. Vengono eseguiti per primi ogni volta che un oggetto o una collezione viene menzionato per la prima volta in una sessione. Dettagli importanti di un costruttore nel contesto di una collezione:

  • Nel caso delle collezioni, questi costruttori devono essere chiamati esplicitamente per inizializzare la collezione.
  • Sia Varray che le tabelle annidate devono essere inizializzate tramite questi costruttori prima di poter essere richiamate nel programma.
  • Un costruttore estende implicitamente l'allocazione di memoria per una collezione (ad eccezione di Varray), quindi può anche assegnare variabili alla collezione.
  • L'assegnazione di valori tramite costruttori non rende mai la collezione sparsa.

Metodi di raccolta

Oracle Offre numerose funzioni per manipolare e lavorare con le collezioni. Queste funzioni determinano e modificano i diversi attributi di una collezione. La tabella seguente elenca le diverse funzioni e le relative descrizioni.

Metodo Descrizione Sintassi
ESISTE (n) Restituisce un risultato booleano. Restituisce TRUE se l'n-esimo elemento esiste, altrimenti FALSE. Solo EXISTS può essere utilizzato su una collezione non inizializzata. .EXISTS(posizione_elemento)
COUNT Indica il numero totale di elementi presenti in una collezione. .CONTARE
LIMITE Restituisce la dimensione massima della collezione. Per Varray, restituisce la dimensione fissa; per tabelle nidificate e indicizzate, restituisce NULL. .LIMITE
PRIMO Restituisce il valore del primo indice della collezione. .PRIMO
ULTIMO Restituisce il valore dell'ultimo indice della collezione. .SCORSO
PRECEDENTE (n) Restituisce l'indice precedente all'n-esimo elemento. Se non è presente alcun indice, viene restituito NULL. .PRIOR(n)
SUCCESSIVO (n) Restituisce l'indice successivo dell'n-esimo elemento. Se non ce n'è nessuno, viene restituito NULL. .NEXT(n)
ESTENDERE Estende un elemento alla fine di una collezione. .ESTENDERE
ESTENDERE (n) Estende n elementi alla fine di una collezione. .ESTENDERE(n)
ESTENDERE (n,i) Estende n copie dell'i-esimo elemento alla fine della collezione. .ESTENDERE(n,i)
TRIM Rimuove un elemento dalla fine della raccolta. .ORDINARE
TRIM (n) Rimuove n elementi dalla fine della collezione. .TRIM (n)
DELETE Elimina tutti gli elementi dalla collezione, rendendola vuota. .ELIMINARE
ELIMINA (n) Elimina l'n-esimo elemento. Se l'n-esimo elemento è NULL, non fa nulla. .DELETE(n)
CANCELLA (m,n) Elimina gli elementi compresi tra m-esimo e n-esimo nella collezione. .DELETE(m,n)

Esempio 1: Tipo di record a livello di sottoprogramma

In questo esempio, vediamo come popolare la collezione utilizzando 'RITIRO IN BLOCCOe come fare riferimento ai dati della raccolta.

Esempio di raccolta PL/SQL popolata con BULK COLLECT

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 Spiegazione

  • Code righe 2-8: Tipo di registrazione La tabella 'emp_det' è dichiarata con le colonne emp_no, emp_name, manager e salary di tipo dati NUMBER, VARCHAR2, NUMBER e NUMBER.
  • Code riga 9: Creazione della raccolta 'emp_det_tbl' di tipo record elemento 'emp_det'.
  • Code riga 10: Dichiarazione della variabile 'guru99_emp_rec' di tipo 'emp_det_tbl' e inizializzazione con un costruttore nullo.
  • Code righe 12-15: Inserimento dei dati di esempio nella tabella 'emp'.
  • Code riga 16: Commiting della transazione di inserimento.
  • Code riga 17: Recupero dei record dalla tabella 'emp' e popolamento in blocco della variabile di raccolta tramite "BULK COLLECT". La variabile 'guru99_emp_rec' ora contiene tutti i record presenti nella tabella 'emp'.
  • Code righe 19-26: Impostazione del ciclo 'FOR' per stampare tutti i record della collezione uno per uno. I metodi di collezione FIRST e LAST vengono utilizzati come limiti inferiore e superiore della collezione. loop.

Produzione: Quando il codice sopra riportato viene eseguito, si ottiene il seguente 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
----------------------------------------------

DOMANDE FREQUENTI

Un Varray ha una dimensione massima fissa ed è sempre denso. Una tabella annidata non ha limiti di dimensione, può essere sparsa ed estendibile, il che la rende più flessibile per dati in crescita o con lacune.

Poiché si tratta di un array associativo in memoria, non di una tabella memorizzata. L'indice funge da chiave di ricerca, quindi una stringa o un numero intero negativo funzionano, il che è utile per le ricerche tramite chiave all'interno di una sessione.

Un Varray non inizializzato o una tabella annidata sono atomicamente null, quindi fare riferimento a un elemento genera un errore. La chiamata al costruttore alloca l'elemento, dopodiché EXTEND e le assegnazioni possono aggiungere dati.

Sì. A seconda che la dimensione sia fissa, che i dati siano memorizzati e che sia necessaria una chiave di tipo stringa, l'IA può indicare un Varray, una tabella nidificata o una tabella indicizzata e spiegare il compromesso.

BULK COLLECT carica tutte le righe in una raccolta con un singolo cambio di contesto tra i motori SQL e PL/SQL, anziché un cambio per ogni riga, riducendo notevolmente il sovraccarico su set di risultati di grandi dimensioni.

Riassumi questo post con: