Uso degli array associativi

Un array associativo è un tipo di collection.

Vedere anche:

Per ulteriori informazioni sulle raccolte, procedere come segue.

Informazioni sulle raccolte

Una collection è una variabile composta PL/SQL che memorizza elementi dello stesso tipo in un ordine specificato, in maniera simile a un array unidimensionali. I componenti interni di una raccolta sono denominati elementi. Ogni elemento ha un subscript che ne identifica la posizione nella collection.

Per accedere a un elemento di raccolta, utilizzare notazione di subscript : collection_name(element_subscript).

È possibile trattare gli elementi collection come variabili scalari. È inoltre possibile passare intere raccolte come parametri di sottoprogramma (se il sottoprogramma di invio e quello di ricezione non è sottoprogramma standalone).

Un metodo collection è un sottoprogramma PL/SQL incorporato che restituisce le informazioni su una raccolta oppure opera su una raccolta. Per richiamare un metodo collection, utilizzare la notazione a punto: collection_name.method_name. Ad esempio, collection_name.COUNT restituisce il numero di elementi nella raccolta.

PL/SQL ha tre tipi di collection:

In questo documento vengono descritti solo gli array associativi.

Vedere anche:

Informazioni sugli array associativi

Un array associativo è un set non limitato di coppie nome-valore. Ogni chiave è univoco e funge da subscript dell'elemento che contiene il valore corrispondente. Pertanto, è possibile accedere agli elementi senza conoscerne le posizioni nell'array e senza analizzare l'array.

Il tipo di dati della chiave può essere PLS_INTEGER o VARCHAR2 (lunghezza).

Se il tipo di dati della chiave è PLS_INTEGER e l'array associativo è indicizzato da un numero intero ed è denso, ovvero non ha spazi tra elementi, ogni elemento incluso tra il primo e l'ultimo è definito e ha un valore (che può essere NULL).

Se il tipo di chiave è VARCHAR2 (lunghezza), l'array associativo viene indicizzato in base a stringa (di caratteri di lunghezza) ed è con sparsità, ossia può esserci degli spazi tra gli elementi.

Quando si esegue l'attraversamento di un array associativo denso, non occorre tenere conto degli spazi tra gli elementi, al contrario di ciò che accade quando si esegue l'attraversamento di un array associativo sparso.

Per assegnare un valore a un elemento di array associativo, è possibile utilizzare un operatore di assegnazione:

array_name(key) := value

Se chiave non è presente nell'array, l'istruzione di assegnazione aggiunge la coppia chiave-valore all'array. Altrimenti, l'istruzione modifica il valore di array_name(key) in value.

Gli array associativi sono utili per la memorizzazione temporanea dei dati. Non utilizzano lo spazio su disco o le operazioni di rete richiesti dalle tabelle. Tuttavia, poiché gli array associativi sono destinati allo storage temporaneo, non è possibile manipolarli con le istruzioni DML.

Se si dichiara un array associativo in un package e si assegnano i valori alla variabile nel package body, l'array associativo esiste per la durata della sessione del database. Altrimenti, esiste per la durata del sottoprogramma in cui viene dichiarato.

Per ulteriori informazioni sugli array associativi, vedere anche: Oracle Database PL/SQL Language Reference

Dichiarazione degli array associativi

Per dichiarare un array associativo, si dichiara un tipo di array associativo e quindi una variabile del tipo indicato.

Il codice seguente mostra la sintassi più semplice:

TYPE array_type IS TABLE OF element_type INDEX BY key_type;

array_name  array_type;

Un modo efficace per dichiarare un array associativo è con un cursore, utilizzando la procedura descritta di seguito. La procedura utilizza ogni istruzione necessaria nella sua forma più semplice, ma fornisce i riferimenti alla sintassi completa.

Per utilizzare un cursore per dichiarare un array associativo:

  1. Nella parte dichiarativa:

    1. Dichiarare il cursore:

       CURSOR cursor_name IS query;
      

      Per la sintassi completa di dichiarazione di cursore dichiarata, vedere Oracle Database PL/SQL Language Reference.

    2. Dichiarare il tipo di array associativo:

       TYPE array_type IS TABLE OF cursor_name%ROWTYPE
         INDEX BY { PLS_INTEGER | VARCHAR2 length }
      

      Per la sintassi completa delle dichiarazioni del tipo di array associativo, vedere Oracle Database PL/SQL Language Reference.

    3. Dichiarare una variabile di array associativo del tipo specificato:

       array_name  array_type;
      

      Per la sintassi completa della dichiarazione delle variabili, vedere Oracle Database PL/SQL Language Reference.

L'Esempio 5-9 utilizza la procedura precedente per dichiarare due array associativi, employee_jobs e jobs_, quindi dichiara un terzo array associativo, job_titles, senza utilizzare un cursore. I primi due array sono indicizzati in base a un numero intero; il terzo è indicizzato in base a una stringa.

Nota: la clausola ORDER BY nella dichiarazione di impiegati_jobs_cursor determina l'ordine di memorizzazione degli elementi dell'array associativo employee_jobs.

Esempio 5-9 Dichiarazione di array associativi

DECLARE
  -- Declare cursor:

  CURSOR employees_jobs_cursor IS
    SELECT FIRST_NAME, LAST_NAME, JOB_ID
    FROM EMPLOYEES
    ORDER BY JOB_ID, LAST_NAME, FIRST_NAME;

  -- Declare associative array type:

  TYPE employees_jobs_type IS TABLE OF employees_jobs_cursor%ROWTYPE
    INDEX BY PLS_INTEGER;

  -- Declare associative array:

  employees_jobs  employees_jobs_type;

  -- Use same procedure to declare another associative array:

  CURSOR jobs_cursor IS
    SELECT JOB_ID, JOB_TITLE
    FROM JOBS;

  TYPE jobs_type IS TABLE OF jobs_cursor%ROWTYPE
    INDEX BY PLS_INTEGER;

  jobs_  jobs_type;

-- Declare associative array without using cursor:

  TYPE job_titles_type IS TABLE OF JOBS.JOB_TITLE%TYPE
    INDEX BY JOBS.JOB_ID%TYPE;  -- jobs.job_id%type is varchar2(10)

  job_titles  job_titles_type;

BEGIN
  NULL;
END;
/

Vedere anche:

Inserimento dei dati negli array associativi

Il modo più efficiente per popolare un array associativo denso è di solito con un'istruzione SELECT con una clausola BULK COLLECT INTO.

Nota: se un array associativo denso è così grande che un'istruzione SELECT restituisce un set di risultati troppo grande per adattarsi alla memoria, non utilizzare un'istruzione SELECT. Popolare invece l'array con un cursore e l'istruzione FETCH con le clausole BULK COLLECT INTO e LIMIT. Per informazioni sull'uso dell'istruzione FETCH con la clausola BULK COLLECT INTO, vedere Oracle Database PL/SQL Language Reference.

Non è possibile utilizzare un'istruzione SELECT per popolare un array associativo sparso (ad esempio job_titles in "Declaring Associative Arrays"). È necessario utilizzare un'istruzione di assegnazione in un'istruzione LOOP. Per informazioni sulle istruzioni LOOP, vedere "Controllo del flusso dei programmi". L'Esempio 5-10 utilizza le istruzioni SELECT per popolare gli array associativi employee_jobs e jobs_, che sono indicizzati per numero intero. Utilizza quindi un'istruzione di assegnazione all'interno dell'istruzione FOR LOOP per popolare l'array associativo job_titles, indicizzato in base alla stringa.

Esempio 5-10 Popolamento di array associativi

-- Declarative part from Example 5-9 goes here.

BEGIN
  -- Populate associative arrays indexed by integer:

SELECT FIRST_NAME, LAST_NAME, JOB_ID BULK COLLECT INTO employees_jobs
  FROM EMPLOYEES ORDER BY JOB_ID, LAST_NAME, FIRST_NAME;

SELECT JOB_ID, JOB_TITLE BULK COLLECT INTO jobs_ FROM JOBS;

  -- Populate associative array indexed by string:

  FOR i IN 1..jobs_.COUNT() LOOP
    job_titles(jobs_(i).job_id) := jobs_(i).job_title;
  END LOOP;
END;
/

Vedere anche: "Informazioni sui cursori"

Analisi degli array associativi con dati completi

Un array associativo con dati esauriti (indicizzato in base a numero intero) non ha spazi tra i vari elementi: ogni elemento tra il primo e l'ultimo è definito e ha un valore (che può essere NULL).

È possibile attraversare un array denso con un'istruzione FOR LOOP, come nell'Esempio 5-11.

Se inserita nella parte eseguibile dell'Esempio 5-10, dopo il codice che popola l'array impiegati_jobs, l'istruzione FOR LOOP nell'Esempio 5-11 stampa gli elementi dell'array impiegati_jobs nell'ordine in cui sono stati memorizzati. L'ordine di memorizzazione è determinato dalla clausola ORDER BY nella dichiarazione di impiegati_jobs_cursor, utilizzata per dichiarare impiegati_jobs (vedere l'Esempio 5-9).

Il limite superiore dell'istruzione FOR LOOP, Employees_jobs.COUNT, richiama un metodo collection che restituisce il numero di elementi nell'array. Per ulteriori informazioni su COUNT, vedere Oracle Database PL/SQL Language Reference.

Esempio 5-11 Analisi di un array associativo con dati completi

-- Code that populates employees_jobs must precede this code:

FOR i IN 1..employees_jobs.COUNT LOOP
  DBMS_OUTPUT.PUT_LINE(
    RPAD(employees_jobs(i).first_name, 23) ||
    RPAD(employees_jobs(i).last_name,  28) ||     employees_jobs(i).job_id);
  END LOOP;

Risultato:

William                Gietz                       AC_ACCOUNT
Shelley                Higgins                     AC_MGR
Jennifer               Whalen                      AD_ASST
Steven                 King                        AD_PRES
Lex                    De Haan                     AD_VP
Neena                  Kochhar                     AD_VP
John                   Chen                        FI_ACCOUNT
...
Jose Manuel            Urman                       FI_ACCOUNT
Nancy                  Greenberg                   FI_MGR
Susan                  Mavris                      HR_REP
David                  Austin                      IT_PROG
...
Valli                  Pataballa                   IT_PROG
Michael                Hartstein                   MK_MAN
Pat                    Fay                         MK_REP
Hermann                Baer                        PR_REP
Shelli                 Baida                       PU_CLERK
...
Sigal                  Tobias                      PU_CLERK
Den                    Raphaely                    PU_MAN
Gerald                 Cambrault                   SA_MAN
...
Eleni                  Zlotkey                     SA_MAN
Ellen                  Abel                        SA_REP
...
Clara                  Vishney                     SA_REP
Sarah                  Bell                        SH_CLERK
...
Peter                  Vargas                      ST_CLERK
Adam                   Fripp                       ST_MAN
...
Matthew                Weiss                       ST_MAN

Analisi degli array associativi con sparsità

Un array associativo con sparsità (indicizzato in base a stringa) può avere spazi tra i vari elementi.

È possibile attraversarlo con un'istruzione WHILE LOOP, come nell'Esempio 5-12.

Per eseguire il codice in Esempio 5-12, che stampa gli elementi dell'array job_titles, attenersi alla procedura riportata di seguito.

  1. Alla fine della parte dichiarativa dell'Esempio 5-9 inserire la dichiarazione di variabile seguente:

     i jobs.job_id%TYPE;
    
  2. Nella parte eseguibile dell'Esempio 5-10, dopo il codice che popola l'array job_titles, inserire il codice dell'Esempio 5-12.

Esempio 5-12 Analisi di un array associativo con sparsità

/* Declare this variable in declarative part:

   i jobs.job_id%TYPE;

   Add this code to the executable part,
   after code that populates job_titles:
*/

i := job_titles.FIRST;

WHILE i IS NOT NULL LOOP
  DBMS_OUTPUT.PUT_LINE(RPAD(i, 12) || job_titles(i));
  i := job_titles.NEXT(i);
END LOOP;

Risultato:

AC_ACCOUNT  Public Accountant
AC_MGR      Accounting Manager
AD_ASST     Administration Assistant
AD_PRES     President
AD_VP       Administration Vice President
FI_ACCOUNT  Accountant
FI_MGR      Finance Manager
HR_REP      Human Resources Representative
IT_PROG     Programmer
MK_MAN      Marketing Manager
MK_REP      Marketing Representative
PR_REP      Public Relations Representative
PU_CLERK    Purchasing Clerk
PU_MAN      Purchasing Manager
SA_MAN      Sales Manager
SA_REP      Sales Representative
SH_CLERK    Shipping Clerk
ST_CLERK    Stock Clerk
ST_MAN      Stock Manager

L'Esempio 5-12 include due richiami dei criteri collection, job_titles.FIRST e job_titles.NEXT(i). job_titles.FIRST restituisce il primo elemento di job_titles e job_titles.NEXT(i) restituisce il subscript che segue i. Per ulteriori informazioni su FIRST, vedere Oracle Database PL/SQL Language Reference. Per ulteriori informazioni su NEXT, vedere Oracle Database PL/SQL Language Reference.