Utilisation de tableaux associatifs

Un tableau associatif est un type de collection.

Voir aussi :

Pour plus d'informations sur les collections :

A propos des collections

Une collection est une variable composite PL/SQL qui stocke des éléments du même type dans un ordre indiqué, semblable à un tableau unidimensionnelle. Les composants internes d'une collection sont appelés éléments. Chaque élément dispose d'un sous-script unique qui identifie sa position dans la collection.

Pour accéder à un élément de collection, utilisez la " notation de sous-script : collection_name(element_subscript).

Les éléments de collection peuvent être traités comme des variables scalaires. Vous pouvez également transmettre des collections entières en tant que paramètres d'un sous-programme (si les sous-programmes d'envoi ou de réception ne sont ni autonomes).

Une méthode de collecte est un sous-programme PL/SQL intégré qui renvoie des informations concernant une collection ou son application à une collection. Pour appeler une méthode de collection, utilisez lanotation par points : collection_name.method_name. Par exemple, collection_name.COUNT renvoie le nombre d'éléments dans la collection.

PL/SQL comporte les trois types de collection suivants :

Ce document explique uniquement les tableaux associatifs.

Voir aussi :

A propos des tableaux associatifs

Un tableau associatif est un ensemble non limité de paires clé-valeur. Chaque clé est unique et sert de sous-script pour l'élément contenant la valeur correspondante. Par conséquent, vous pouvez accéder aux éléments sans connaître leur position dans le tableau et sans le parcourir.

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 entier et de type dense (il ne comporte pas de vide entre les éléments), chaque élément du premier au dernier est défini et dispose d'une valeur (pouvant être NULL).

Si le type de clé est VARCHAR2 (longueur), le tableau associatif est indexé par chaîne (de caractères de longueur) et de typedispersé : il peut donc comporter des vides entre les éléments.

Lors du parcours d'un tableau associatif dense, vous n'avez pas besoin d'être attentif aux vides entre les éléments, contrairement à des tableaux associatifs dispersés.

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

array_name(key) := value

Si key ne figure pas dans le tableau, l'instruction d'affectation ajoute la paire clé-valeur au tableau. Sinon, l'instruction remplace la valeur de array_name(key) par value.

Les tableaux associatifs sont utiles pour le stockage temporaire des données. Ils n'utilisent pas autant d'espace disque ou d'opérations réseau que les tables. Toutefois, étant donné que les tableaux associatifs sont destinés à un stockage temporaire, vous ne pouvez pas les manipuler à l'aide d'instructions DML.

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 pour la durée de la session de base de donnée. Sinon, il existe pendant l'exécution du sous-programme dans lequel il est déclaré.

Voir aussi : Oracle Database PL/SQL Language Reference, pour plus d'informations sur les tableaux associatifs.

Déclaration de tableaux associatifs

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

Le code suivant présente la syntaxe la plus simple :

TYPE array_type IS TABLE OF element_type INDEX BY key_type;

array_name  array_type;

Une méthode efficace pour déclarer un tableau associatif consiste à employer un curseur, à l'aide de la procédure suivante. Cette procédure utilise chaque instruction nécessaire sous sa forme la plus simple, mais fournit les références correspondantes avec la syntaxe complète.

Pour déclarer un tableau associatif à l'aide d'un curseur, procédez comme suit :

  1. Dans la partie de déclaration, effectuez les opérations suivantes :

    1. Déclarez le curseur :

       CURSOR cursor_name IS query;
      

      Pour connaître la syntaxe complète des déclarations de curseurs déclarés, reportez-vous à Oracle Database PL/SQL Language Reference.

    2. Déclarez le type de tableau associatif :

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

      Pour connaître les syntaxes complètes des déclarations du type de tableau associatif, reportez-vous au guide Oracle Database PL/SQL Language Reference.

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

       array_name  array_type;
      

      Pour connaître la syntaxe complète des déclarations des variables, reportez-vous au manuelOracle Database PL/SQL Language Reference.

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

Remarque : 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éclaration de 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 :

Remplissage de tableaux associatifs

La manière la plus efficace de remplir un tableau associatif dense consiste généralement à utiliser une instruction SELECT avec une clause BULK COLLECT INTO.

Remarque : si un tableau associatif dense est si volumineux qu'une instruction SELECT renvoie un ensemble de résultats trop volumineux pour tenir en mémoire, n'utilisez pas d'instruction 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'instruction FETCH avec la clause BULK COLLECT INTO, reportez-vous à Référence de langage Oracle Database PL/SQL.

Vous ne pouvez pas utiliser une instruction SELECT pour remplir un tableau associatif dispersé (tel que job_titles dans "Déclarer des tableaux associatifs"). Pour cela, vous devez utiliser une instruction d'affectation dans une instruction de boucle. Pour plus d'informations sur les instructions de boucle, reportez-vous à la rubrique "Contrôle du flux du programme". L'exemple 5-10 utilise des instructions SELECT pour remplir les tableaux associatifs employees_jobs et jobs_, indexés par un entier. Il utilise ensuite une instruction d'affectation au sein d'un ordre FOR LOOP pour remplir le tableau associatif job_titles, indexé par un chaîne.

Exemple 5-10 Remplissage de 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 : "A propos des curseurs"

Parcours de tableaux associatifs denses

Un tableau associatif dense (indexé par un entier) ne comporte aucun écart entre les éléments : chaque élément, du premier au dernier, est défini et dispose d'une valeur (pouvant être NULL).

Vous pouvez parcourir un tableau dense à l'aide d'une instruction FOR LOOP, comme dans l'Example 5-11.

Lorsqu'elle est insérée dans la partie exécutable de l'Example 5-10, à la suite d'un code permettant d'utiliser le tableau employees_jobs, l'instruction FOR LOOP de l'Example 5-11 affiche les éléments du tableau employees_jobs dans leur ordre de stockage. Leur ordre de stockage a été déterminé par la clause ORDER BY de la déclaration de employees_jobs_cursor, utilisée pour déclarer employees_jobs (reportez-vous à l'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, reportez-vous au guide Oracle Database PL/SQL Language Reference.

Exemple 5-11 Parcours d'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ésultats :

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

Parcours de tableaux associatifs dispersés

Un tableau associatif dispersé (indexé par une chaîne) peut avoir des intervalles entre les éléments qu'il contient.

Vous pouvez le parcourir à l'aide d'une instruction WHILE LOOP, comme dans l'Example 5-12.

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

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

     i jobs.job_id%TYPE;
    
  2. Dans la partie exécutable de l'Exemple 5-10, à la suite du code qui permet de remplir le tableau job_titles, insérez le code indiqué à l'Exemple 5-12.

Exemple 5-12 Parcours d'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ésultats :

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'exemple 5-12 comporte deux appels de méthode de collecte, job_titles.FIRST et job_titles.NEXT(i). job_titles.FIRST renvoie le premier élément du tableau job_titles et job_titles.NEXT(i) renvoie l'indice qui succède à i. Pour plus d'informations sur Oracle Database PL/SQL Language Reference, reportez-vous au manuel PREMIER. For more information about NEXT, see Oracle Database PL/SQL Language Reference.