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

Che cos'รจ la raccolta?

Una Collection รจ un gruppo ordinato di elementi di particolari tipi di dati. Puรฒ essere una collection di tipo di dati semplice o di tipo di dati complesso (come i tipi definiti dall'utente o di record).

Nella collezione ogni elemento รจ identificato da un termine chiamato โ€œpediceโ€. A ogni elemento della raccolta viene assegnato un pedice univoco. I dati in quella raccolta possono essere manipolati o recuperati facendo riferimento a quel pedice univoco.

Le raccolte sono molto utili quando รจ necessario elaborare o manipolare dati di grandi dimensioni dello stesso tipo. Le raccolte possono essere popolate e manipolate nel loro insieme utilizzando l'opzione 'BULK' in Oracle.

Le raccolte sono classificate in base alla struttura, al pedice e all'archiviazione come mostrato di seguito.

  • Indice per tabelle (noto anche come array associativo)
  • Tabelle nidificate
  • Varray

In qualsiasi momento, i dati nella raccolta possono essere indicati con tre termini Nome raccolta, Pedice, Nome campo/colonna come " ( ). โ€. Imparerai a conoscere queste categorie di raccolta sopra menzionate piรน avanti nella sezione seguente.

Varray

Varray รจ un metodo di raccolta in cui la dimensione dell'array รจ fissa. La dimensione dell'array non puรฒ essere superata rispetto al suo valore fisso. L'indice di Varray รจ di un valore numerico. Di seguito sono riportati gli attributi di Varray.

  • La dimensione del limite superiore รจ fissa
  • Compilato in sequenza iniziando con il pedice "1"
  • Questo tipo di raccolta รจ sempre densa, ovvero non รจ possibile eliminare alcun elemento dell'array. Varray puรฒ essere eliminato completamente oppure tagliato dalla fine.
  • Poichรฉ รจ sempre di natura densa, ha una flessibilitร  molto minore.
  • รˆ piรน appropriato da utilizzare quando la dimensione dell'array รจ nota ed eseguire attivitร  simili su tutti gli elementi dell'array.
  • Il pedice e la sequenza rimangono sempre stabili, cioรจ il pedice e il conteggio della raccolta sono sempre gli stessi.
  • Devono essere inizializzati prima di utilizzarli nei programmi. Qualsiasi operazione (tranne l'operazione EXISTS) su una raccolta non inizializzata genererร  un errore.
  • Puรฒ essere creato come oggetto di database, visibile in tutto il database o all'interno del sottoprogramma, che puรฒ essere utilizzato solo in quel sottoprogramma.

La figura seguente spiegherร  schematicamente l'allocazione della memoria di Varray (densa).

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, type_name รจ dichiarato come VARRAY del tipo 'DATA_TYPE' per il limite di dimensione specificato. Il tipo di dati puรฒ essere semplice o complesso.

Tabelle annidate

Una tabella nidificata รจ una raccolta in cui la dimensione dell'array non รจ fissa. Ha il tipo di pedice numerico. Di seguito sono riportate ulteriori descrizioni sul tipo di tabella nidificata.

  • La tabella nidificata non ha limiti di dimensione superiore.
  • Poichรฉ il limite di dimensione superiore non รจ fisso, la memoria della raccolta deve essere estesa ogni volta prima di utilizzarla. Possiamo estendere la raccolta utilizzando la parola chiave "EXTEND".
  • Compilato in sequenza a partire dal pedice "1".
  • Questo tipo di raccolta puรฒ essere di entrambi denso e scarno, ovvero possiamo creare una raccolta densa e possiamo anche eliminare i singoli elementi dell'array in modo casuale, rendendolo sparso.
  • Offre maggiore flessibilitร  per quanto riguarda l'eliminazione dell'elemento dell'array.
  • Viene memorizzato nella tabella del database generata dal sistema e puรฒ essere utilizzato nella query di selezione per recuperare i valori.
  • Il pedice e la sequenza non sono stabili, ovvero il pedice e il conteggio dell'elemento dell'array possono variare.
  • Devono essere inizializzati prima di utilizzarli nei programmi. Qualsiasi operazione (tranne l'operazione EXISTS) sulla raccolta non inizializzata genererร  un errore.
  • Puรฒ essere creato come oggetto di database, visibile in tutto il database o all'interno del sottoprogramma, che puรฒ essere utilizzato solo in quel sottoprogramma.

La figura seguente spiegherร  schematicamente l'allocazione di memoria della tabella annidata (densa e sparsa). Lo spazio dell'elemento di colore nero denota l'elemento vuoto in una raccolta, cioรจ sparsa.

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 <tvpe name> IS TABLE OF <DATA TYPE>;
  • Nella sintassi sopra, type_name รจ dichiarato come Nested table collection del tipo 'DATA_TYPE'. Il tipo di dati puรฒ essere semplice o complesso.

Indice per tabella

Index-by-table รจ una raccolta in cui la dimensione dell'array non รจ fissa. A differenza degli altri tipi di raccolta, nella raccolta index-by-table l'indice puรฒ essere definito dall'utente. Di seguito sono riportati gli attributi di index-by-table.

  • Il pedice puรฒ contenere numeri interi o stringhe. Al momento della creazione della raccolta, รจ necessario menzionare il tipo di pedice.
  • Queste raccolte non vengono archiviate in sequenza.
  • Sono sempre sparsi in natura.
  • La dimensione dell'array non รจ fissa.
  • Non possono essere archiviati nella colonna del database. Dovranno essere creati e utilizzati in qualsiasi programma in quella particolare sessione.
  • Danno maggiore flessibilitร  in termini di mantenimento dell'indice.
  • I pedici possono anche avere una sequenza di pedici negativi.
  • Sono piรน appropriati da utilizzare per valori collettivi relativamente piรน piccoli in cui la raccolta puรฒ essere inizializzata e utilizzata all'interno degli stessi sottoprogrammi.
  • Non รจ necessario inizializzarli prima di iniziare a utilizzarli.
  • Non puรฒ essere creato come oggetto di database. Puรฒ essere creato solo all'interno del sottoprogramma, che puรฒ essere utilizzato solo in quel sottoprogramma.
  • BULK COLLECT non puรฒ essere utilizzato in questo tipo di raccolta poichรฉ il pedice deve essere fornito esplicitamente per ciascun record nella raccolta.

La figura seguente spiegherร  schematicamente l'allocazione di memoria della tabella annidata (sparsa). Lo spazio dell'elemento di colore nero denota l'elemento vuoto in una raccolta, cioรจ sparsa.

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, type_name รจ dichiarato come una raccolta indice-per-tabella del tipo 'DATA_TYPE'. Il tipo di dati puรฒ essere semplice o complesso. La variabile subsciprt/index รจ data come tipo VARCHAR2 con dimensione massima pari a 10.

Costruttore e concetto di inizializzazione nelle raccolte

I costruttori sono la funzione integrata fornita dall'oracolo che ha lo stesso nome dell'oggetto o delle raccolte. Vengono eseguiti per primi ogni volta che l'oggetto o le raccolte vengono referenziati per la prima volta in una sessione. Di seguito sono riportati i dettagli importanti del costruttore nel contesto della raccolta:

  • Per le raccolte, questi costruttori dovrebbero essere chiamati esplicitamente per inizializzarli.
  • Sia le tabelle Varray che quelle Nested devono essere inizializzate tramite questi costruttori prima di essere inserite nel programma.
  • Il costruttore estende implicitamente l'allocazione di memoria per una raccolta (eccetto Varray), quindi il costruttore puรฒ anche assegnare le variabili alle raccolte.
  • L'assegnazione di valori alla raccolta tramite i costruttori non renderร  mai la raccolta sparsa.

Metodi di raccolta

Oracle fornisce molte funzioni per manipolare e lavorare con le collezioni. Queste funzioni sono molto utili nel programma per determinare e modificare i diversi attributi delle collezioni. La seguente tabella fornirร  le diverse funzioni e la loro descrizione.

Metodo Descrizione SINTASSI
ESISTE (n) Questo metodo restituirร  risultati booleani. Restituirร  'TRUE' se il nth L'elemento esiste in quella raccolta, altrimenti restituirร  FALSE. Solo le funzioni EXISTS possono essere utilizzate nella raccolta non inizializzata .EXISTS(posizione_elemento)
COUNT Fornisce il conteggio totale degli elementi presenti in una raccolta .CONTARE
LIMITE Restituisce la dimensione massima della raccolta. Per Varray, restituirร  la dimensione fissa che รจ stata definita. Per la tabella nidificata e l'indice per tabella, restituisce NULL .LIMITE
PRIMO Restituisce il valore della prima variabile indice (pedice) delle raccolte .PRIMO
ULTIMO Restituisce il valore dell'ultima variabile indice (pedice) delle raccolte .SCORSO
PRECEDENTE (n) Returns precede la variabile indice in una raccolta di nth elemento. Se non รจ presente alcun valore di indice precedente, viene restituito NULL .PRIOR(n)
SUCCESSIVO (n) Restituisce la variabile indice successiva in una raccolta di nth elemento. Se non ci sono risultati positivi, viene restituito il valore di indice NULL .NEXT(n)
ESTENDERE Estende un elemento in una raccolta alla fine .ESTENDERE
ESTENDERE (n) Estende n elementi alla fine di una raccolta .ESTENDERE(n)
ESTENDERE (n,i) Estende n copie di ith elemento alla fine della raccolta .ESTENDERE(n,i)
TRIM Rimuove un elemento dalla fine della raccolta .ORDINARE
TRIM (n) Rimuove n elementi dalla fine della raccolta .TRIM (n)
DELETE Elimina tutti gli elementi dalla raccolta. Rende la raccolta vuota .ELIMINARE
ELIMINA (n) Elimina l'ennesimo elemento dalla raccolta. Se poith l'elemento รจ NULL, ciรฒ non farร  nulla .DELETE(n)
CANCELLA (m,n) Elimina l'elemento nell'intervallo mth tonnellatath nella collezione .DELETE(m,n)

Esempio 1: tipo di record a livello di sottoprogramma

In questo esempio vedremo come popolare la collection utilizzando 'RITIRO IN BLOCCO' e come fare riferimento ai dati di raccolta.

Tipo di record a livello di sottoprogramma

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

Spiegazione del codice:

  • Riga di codice 2-8: Tipo di registrazione 'emp_det' viene dichiarato con le colonne emp_no, emp_name, stipendio e manager di tipo dati NUMBER, VARCHAR2, NUMBER, NUMBER.
  • Riga di codice 9: Creazione della raccolta 'emp_det_tbl' dell'elemento di tipo record 'emp_det'
  • Riga di codice 10: Dichiarando la variabile 'guru99_emp_rec' come tipo 'emp_det_tbl' e inizializzata con costruttore null.
  • Riga di codice 12-15: Inserimento dei dati di esempio nella tabella 'emp'.
  • Riga di codice 16: Commiting della transazione di inserimento.
  • Riga di codice 17: Recuperando i record dalla tabella 'emp' e popolando la variabile di raccolta in blocco utilizzando il comando "BULK COLLECT". Ora la variabile 'guru99_emp_rec' contiene tutti i record presenti nella tabella 'emp'.
  • Riga di codice 19-26: Impostazione del ciclo 'FOR' utilizzando per stampare tutti i record nella raccolta uno per uno. Il metodo di raccolta FIRST e LAST viene utilizzato come limite inferiore e superiore del loop.

Uscita: Come puoi vedere nello screenshot qui sopra, quando il codice sopra viene eseguito otterrai 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
----------------------------------------------

Riassumi questo post con: