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

