Usando Matrizes Associativas

Um array associativo é um tipo de conjunto.

Consulte também:

Para obter mais informações sobre as coleções:

Sobre Coleções

Uma coleção abrange uma variável composta PL/SQL que armazena elementos do mesmo tipo em uma ordem especificada, semelhante a uma matriz unidimensional. Os componentes internos de uma coleção são chamados elementos. Cada elemento tem um subscript exclusivo que identifica sua posição na coleta.

Para acessar um elemento de coleta, use notação de subscrito : collection_name(element_subscript).

Você pode tratar elementos de coleta·como variáveis escalares. Você também pode passar coleções inteiras como parâmetros do subprograma (se o subprograma de envio e recebimento não for um subprograma independente).

Um método de cobrança é um subprograma PL/SQL integrado que retorna informações sobre uma coleção ou opera em uma coleção. Para chamar um método de coleta, use notação de ponto: collection_name.method_name. Por exemplo, collection_name.COUNT retorna o número de elementos da coleção.

O PL/SQL tem três tipos de coleta:

Este documento explica apenas arrays associativos.

Consulte também:

Sobre Arrays Associativos

Um array associativo é um conjunto ilimitado de pares de chave/valor. Cada par é exclusivo e atua como subscript do elemento que contém o valor correspondente. Assim, você pode acessar elementos sem conhecer suas posições no array e sem percorrer o array.

O tipo de dados da chave pode ser PLS_INTEGER ou VARCHAR2 (comprimento).

Se o tipo de dados da chave for PLS_INTEGER e a matriz associativa for indexada por inteiro e for densa (ou seja, não tiver lacunas entre elementos), todos os elemento entre o primeiro e último elemento serão definidos e terão um valor (que pode ser NULL).

Se o tipo de chave for VARCHAR2 (comprimento), a matriz associativa será indexada por string (de caracteres de tamanho) e esparsa; ou seja, poderá haver lacunas entre elementos.

Ao percorrer um array associativo denso, você não precisará se importar com as lacunas entre os elementos; ao percorrer um array associativo esparso, você o faz.

Para atribuir um valor a um elemento de matriz associativa, você pode usar um operador de atribuição:

array_name(key) := value

Se a chave não estiver no array, a instrução de atribuição adicionará o par chave-valor ao array. Caso contrário, a instrução alterará o valor de array_name(key) para valor.

Os arrays associativos são úteis para armazenar dados temporariamente. Eles não usam o espaço em disco ou operações de rede exigidos pelas tabelas. No entanto, como os arrays associativos são destinados ao armazenamento temporário, não é possível manipulá-los com instruções DML.

Se você declarar um array associativo em um pacote e atribuir valores à variável no corpo do pacote, o array associativo existirá durante a vida útil da sessão do banco de Dados. Caso contrário, ele existirá durante a vigência do subprograma no qual você o declara.

Consulte também: Referência de Linguagem PL/SQL do Oracle Database para mais informações sobre arrays associativos

Declarando Arrays Associativos

Para declarar uma matriz associativa, declare um tipo de matriz associativa e, em seguida, declare uma variável desse tipo.

O código a seguir mostra a sintaxe mais simples:

TYPE array_type IS TABLE OF element_type INDEX BY key_type;

array_name  array_type;

Uma maneira eficiente de declarar um array associativo é com um cursor, usando o procedimento a seguir. O procedimento usa cada instrução necessária em sua forma mais simples, mas fornece referências a sua sintaxe complexa.

Para usar um cursor para declarar um array associativo:

  1. Na parte declarativa:

    1. Declare o cursor:

       CURSOR cursor_name IS query;
      

      Para obter a sintaxe completa da declaração de cursor declarada, consulte Referência de Linguagem PL/SQL do Oracle Database.

    2. Declare o·tipo de array associativo:

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

      Para obter a sintaxe completa da declaração do tipo de array associativo, consulte Referência de Linguagem PL/SQL do Oracle Database.

    3. Declare uma variável de·array associativo desse tipo:

       array_name  array_type;
      

      Para obter a sintaxe completa da declaração da variável, consulte Referência da Linguagem PL/SQL do Oracle Database.

Exemplo 5-9 usa o procedimento anterior para declarar dois arrays associativos, employees_jobs e jobs_ e, em seguida, declara um terceiro array associativo, job_titles, sem usar um cursor. Os dois primeiros arrays são indexados por número inteiro; o terceiro é indexado por string.

Observação: A cláusula ORDER BY na declaração employees_jobs_cursor determina a ordem de armazenamento dos elementos da matriz associativa employee_jobs.

Exemplo 5-9 Declarando Matrizes Associativas

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

Consulte também:

Preenchendo Matrizes Associativas

A maneira mais eficiente de preencher uma matriz associativa densa é geralmente com uma instrução SELECT com uma cláusula BULK COLLECT INTO.

Observação: Se um array associativo denso for tão grande que uma instrução SELECT retornaria um conjunto de resultados muito grande para caber na memória, não use uma instrução SELECT. Em vez disso, preencha a matriz com um cursor e a instrução FETCH com as cláusulas BULK COLLECT INTO e LIMIT. Para obter informações sobre como usar a instrução FETCH com a cláusula BULK COLLECT INTO, consulte Oracle Database PL/SQL Language Reference.

Você não pode usar uma instrução SELECT para preencher uma matriz associativa esparsa (como job_titles em "Declaring Associative Arrays"). Em vez disso, use uma instrução de designação em uma instrução de loop. Para obter informações sobre instruções do loop, consulte "Controlando o Fluxo do Programa". Exemplo 5-10 usa instruções SELECT para preencher os arrays associativos employees_jobs e jobs_, que são indexados por inteiro. Em seguida, ele usa uma instrução da atribuição dentro de uma instrução FOR LOOP para preencher o job_titles da matriz associativa, que é indexado por string.

Exemplo 5-10 Preenchendo Matrizes Associativas

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

Consulte Também: "Sobre Cursores"

Percorrendo Matrizes Associativas Densas

Um array associativo denso (indexado por inteiro) não tem lacunas entre elementos - cada elemento entre o primeiro e último elemento é definido e tem um valor (que pode ser NULO).

Você pode percorrer um array denso com uma instrução FOR LOOP, como no Exemplo 5-11.

Quando inserido na parte executável do Exemplo 5-10, após o código que preenche a matriz employees_jobs, a instrução FOR LOOP no Exemplo 5-11 imprime os elementos da matriz employees_jobs na ordem em que foram armazenados. Sua ordem de armazenamento foi determinada pela cláusula ORDER BY na declaração employees_jobs_cursor, que foi usada para declarar employees_jobs (consulte Exemplo 5-9).

O limite superior da instrução FOR LOOP, employees_jobs.COUNT, chama um método da coleta que retorna o número de elementos na matriz. Para obter mais informações sobre COUNT, consulte Referência de Linguagem PL/SQL do Oracle Database.

Exemplo 5-11 Percorrendo uma Matriz Associativa Densa

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

Resultado:

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

Percorrendo Matrizes Associativas Dispersas

Uma array associativa esparsa (indexada por string) pode ter lacunas entre elementos.

Você pode percorrê-lo com uma instrução WHILE LOOP, como no Exemplo 5-12.

Para executar o código no Exemplo 5-12, que imprime os elementos da matriz job_titles, execute as seguintes etapas:

  1. No final da parte declarativa do Exemplo 5-9, insira esta declaração da variável:

     i jobs.job_id%TYPE;
    
  2. Na parte executável do Exemplo 5-10, após o código que preenche o array job_titles, insira o código do Exemplo 5-12.

Exemplo 5-12 Percorrendo uma Matriz Associativa Esparsa

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

Resultado:

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

O Exemplo 5-12 inclui duas invocações de método de coleta, job_titles.FIRST e job_titles.NEXT(i). job_titles.FIRST retorna o primeiro elemento de job_titles e job_titles.NEXT(i) retorna o subscrito que é bem-sucedido i. Para obter mais informações sobre PRIMEIRO, consulte Referência de Linguagem PL/SQL do Oracle Database. Para obter mais informações sobre PRÓXIMO, consulte Oracle Database PL/SQL Language Reference.