Utiliser des tableaux associatifs

Un tableau associatif est un type de collection.

Voir aussi :

Pour plus d'informations sur les collections :

À propos des collections

Une collection est une variable composite PL/SQL qui stocke des éléments du même type dans un ordre spécifié, similaire à un tableau unidimensionnel. Les composants internes d'une collection sont appelés éléments. Chaque élément a un indice unique qui identifie sa position dans la collection.

Pour accéder à un élément de collecte, vous utilisez la notation par script : collection_name(element_subscript).

Vous pouvez traiter des éléments de collecte tels que des variables scalaires. Vous pouvez également transmettre des collections entières en tant que paramètres de sous-programme (si le sous-programme d'envoi et de réception n'est pas un sous-programme autonome).

Une méthode de collecte est un sous-programme PL/SQL intégré qui retourne des informations sur une collection ou qui s'exécute sur une collection. Pour appeler une méthode de collecte, utilisez la notation par points : collection_name.method_name. Par exemple, collection_name.COUNT retourne le nombre d'éléments de la collection.

Le langage PL/SQL comporte trois types d'ensemble :

Ce document explique uniquement les tableaux associatifs.

Voir aussi :

À propos des tableaux associatifs

Un tableau associatif est un jeu non limité de paires clé-valeur. Chaque clé est unique et sert d'indice de l'élément qui contient la valeur correspondante. Par conséquent, vous pouvez accéder aux éléments sans connaître leur position dans le tableau, et sans traverser le tableau.

Le type de données de la clé peut être PLS_INTEGER ou VARCHAR2 (longueur).

Si le type de données de la clé est PLS_INTEGER et que le tableau associatif est indexé par un entier et est dense (c'est-à-dire qu'il n'y a aucun écart entre les éléments), chaque élément entre le premier et le dernier élément est défini et a une valeur (qui peut être NULL).

Si le type de clé est VARCHAR2 (longueur), le tableau associatif est indexé par une chaîne (de caractères de longueur) et sparse; c'est-à-dire qu'il peut y avoir des écarts entre les éléments.

Lorsque vous parcourez un tableau associatif dense, vous n'avez pas besoin de vous méfier des espaces entre les éléments; lorsque vous parcourez un tableau associatif dispersé, vous le faites.

Pour affecter une valeur à un élément de tableau associatif, vous pouvez utiliser un opérateur d'affectation :

array_name(key) := value

Si la clé n'est pas dans le tableau, l'instruction d'affectation ajoute la paire clé-valeur au tableau. Sinon, l'instruction change la valeur de array_name(key) en valeur.

Les tableaux associatifs sont utiles pour stocker temporairement des données. Ils n'utilisent pas l'espace disque ou les opérations réseau dont les tables ont besoin. Toutefois, comme les tableaux associatifs sont destinés au stockage temporaire, vous ne pouvez pas les manipuler à l'aide d'instructions LMD.

Si vous déclarez un tableau associatif dans un package et affectez des valeurs à la variable dans le corps du package, le tableau associatif existe pendant toute la durée de la session de base de données. Sinon, il existe pour la durée de vie du sous-programme dans lequel vous le déclarez.

Voir aussi : Informations de référence sur le langage PL/SQL pour Oracle Database pour plus d'informations sur les tableaux associatifs

Déclarer des tableaux associatifs

Pour déclarer un tableau associatif, vous déclarez un type de tableau associatif, puis vous déclarez une variable de ce type.

Le code suivant affiche la syntaxe la plus simple :

TYPE array_type IS TABLE OF element_type INDEX BY key_type;

array_name  array_type;

Un moyen efficace de déclarer un tableau associatif est avec un curseur, à l'aide de la procédure suivante. La procédure utilise chaque instruction nécessaire dans sa forme la plus simple, mais fournit des références à sa syntaxe complète.

Pour utiliser un curseur pour déclarer un tableau associatif :

  1. Dans la partie déclarative :

    1. Déclarez le curseur :

       CURSOR cursor_name IS query;
      

      Pour une syntaxe complète de déclaration de curseur déclaré, voir Informations de référence sur le langage PL/SQL pour Oracle Database.

    2. Déclarez le type de tableau associatif :

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

      Pour une syntaxe complète de déclaration de type tableau associatif, voir Informations de référence sur le langage PL/SQL pour Oracle Database.

    3. Déclarez une variable de tableau associatif de ce type :

       array_name  array_type;
      

      Pour une syntaxe complète de déclaration de variable, voir Informations de référence sur le langage PL/SQL pour Oracle Database.

Exemple 5-9 utilise la procédure précédente pour déclarer deux tableaux associatifs, employees_jobs et jobs_, puis déclare un troisième tableau associatif, job_titles, sans utiliser de curseur. Les deux premiers tableaux sont indexés par nombre entier; le troisième est indexé par chaîne.

Note : La clause ORDER BY dans la déclaration de employees_jobs_cursor détermine l'ordre de stockage des éléments du tableau associatif employee_jobs.

Exemple 5-9 : Déclarer des tableaux associatifs

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

Voir aussi :

Alimentation des tableaux associatifs

La méthode la plus efficace pour alimenter un tableau associatif dense consiste généralement à utiliser une instruction SELECT avec une clause BULK COLLECT INTO.

Note : Si un tableau associatif dense est si volumineux qu'un énoncé SELECT retournerait un jeu de résultats trop volumineux pour tenir en mémoire, n'utilisez pas d'énoncé SELECT. Remplissez plutôt le tableau avec un curseur et l'instruction FETCH avec les clauses BULK COLLECT INTO et LIMIT. Pour plus d'informations sur l'utilisation de l'énoncé FETCH avec la clause BULK COLLECT INTO, voir Informations de référence sur le langage PL/SQL pour Oracle Database.

Vous ne pouvez pas utiliser un énoncé SELECT pour alimenter un tableau associatif dispersé (tel que job_titles dans "Déclaration de tableaux associatifs"). Vous devez plutôt utiliser une instruction d'affectation dans une instruction de boucle. Pour plus d'informations sur les énoncés de boucle, voir "Contrôle du flux de programme". Exemple 5-10 utilise des énoncés SELECT pour alimenter les tableaux associatifs employees_jobs et jobs_, qui sont indexés par un nombre entier. Il utilise ensuite une instruction d'affectation dans une instruction FOR LOOP pour alimenter le tableau associatif job_titles, qui est indexé par chaîne.

Exemple 5-10 : Alimenter des tableaux associatifs

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

Voir aussi : "À propos des curseurs"

Parcourir les tableaux associatifs denses

Un tableau associatif dense (indexé par un entier) n'a aucun écart entre les éléments - chaque élément entre le premier et le dernier élément est défini et a une valeur (qui peut être NULL).

Vous pouvez parcourir un tableau dense avec un énoncé FOR LOOP, comme dans Exemple 5-11.

Lorsqu'il est inséré dans la partie exécutable de Exemple 5-10, après le code qui alimente le tableau employees_jobs, l'énoncé FOR LOOP dans Exemple 5-11 imprime les éléments du tableau employees_jobs dans l'ordre dans lequel ils ont été stockés. Leur ordre de stockage a été déterminé par la clause ORDER BY dans la déclaration of employees_jobs_cursor, qui a été utilisée pour déclarer employees_jobs (voir Exemple 5-9).

La limite supérieure de l'instruction FOR LOOP, employees_jobs.COUNT, appelle une méthode de collecte qui renvoie le nombre d'éléments dans le tableau. Pour plus d'informations sur COUNT, voir Informations de référence sur le langage PL/SQL pour Oracle Database.

Exemple 5-11 : Parcourir un tableau associatif dense

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

Résultat :

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

Parcourir les tableaux associatifs dispersés

Un tableau associé dispersé (indexé par une chaîne) peut comporter des espaces entre les éléments.

Vous pouvez le parcourir avec un énoncé WHILE LOOP, comme dans Exemple 5-12.

Pour exécuter le code dans Exemple 5-12, qui imprime les éléments du tableau job_titles, procédez comme suit :

  1. À la fin de la partie déclarative de l'exemple 5-9, insérez cette déclaration de variable :

     i jobs.job_id%TYPE;
    
  2. Dans la partie exécutable de Exemple 5-10, après le code qui alimente le tableau job_titles, insérez le code à partir de Exemple 5-12.

Exemple 5-12 : Parcourir un tableau associatif dispersé

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

Résultat :

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

Exemple 5-12 inclut deux appels de méthode de collecte, job_titles.FIRST et job_titles.NEXT(i). job_titles.FIRST retourne le premier élément de job_titles, et job_titles.NEXT(i) retourne l'indice qui succède à i. Pour plus d'informations sur FIRST, voir Informations de référence sur le langage PL/SQL pour Oracle Database. Pour plus d'informations sur NEXT, voir Informations de référence sur le langage PL/SQL pour Oracle Database.