Uso de Matrices Asociativas
Una matriz asociativa es un tipo de recopilación.
Consulte además:
Para obtener más información sobre las recopilaciones, consulte:
Acerca de las Recopilaciones
Una recopilación es una variable compuesta PL/SQL que almacena elementos del mismo tipo en un orden específico, similar a una matriz de una sola dimensión. Los componentes internos de una recopilación se denominan elementos. Cada elemento tiene un subíndice único que identifica su posición en la recopilación.
Para acceder a un elemento de recopilación, use la notación de subíndice : collection_name(element_subscript).
Puede tratar los elementos de recopilación como variables escalares. También puede transferir las recopilaciones enteras como parámetros de subprograma (si ni el subprograma de envío ni el del de recepción es un subprograma autónomo).
Un método de recolección es un subprograma PL/SQL incorporado que devuelve información sobre una recopilación u opera sobre una recopilación. Para invocar un método de recopilación, utilice notación de punto: nombre_recolección.nombre_método. Por ejemplo, collection_name.COUNT devuelve el número de elementos en la recopilación.
PL/SQL tiene tres tipos de recopilaciones:
-
Matrices asociativas (antes llamadas "tablas PL/SQL" o "tablas por índice")
-
Tablas anidadas
-
Matrices de variables (varrays)
Este documento explica sólo las matrices asociativas.
Consulte además:
-
Referencia de lenguaje PL/SQL de Oracle Database para obtener más información sobre los tipos de recopilación PL/SQL
-
Referencia de lenguaje PL/SQL de Oracle Database para obtener más información sobre los métodos de recopilación
Acerca de las Matrices Asociativas
Una matriz asociativa es un juego sin enlazar de pares de clave-valor. Cada clave es única y sirve como el subíndice del elemento que contiene el valor correspondiente. Por lo tanto, puede acceder a elementos sin saber sus posiciones en la matriz y sin recorrer la matriz.
El tipo de dato de la clave puede ser PLS_INTEGER o VARCHAR2 (longitud).
Si el tipo de dato de la clave es PLS_INTEGER y la matriz asociativa es indexada por entero y es densa (es decir, sin intervalos entre elementos), significa que cada elemento entre el primer y la última elemento está definido con un valor (que puede ser NULL).
Si el tipo de clave es VARCHAR2 (longitud), la matriz asociativa es indexada por cadena (de caracteres de longitud) y es disperso; es decir, puede tener intervalos entre elementos.
Al recorrer una matriz asociativa densa, no tiene que tener cuidado de los intervalos entre elementos; al recorrer una matriz asociativa dispersa, sí.
Para asignar un valor a un elemento de matriz asociativa, puede utilizar un operador de asignación:
array_name(key) := value
Si la clave no está en la matriz, la sentencia de asignación agrega el par clave-valor a la matriz. De lo contrario, la sentencia cambia el valor array_name(key) a value.
Las matrices asociativas son útiles para almacenar datos temporalmente. No utilizan el espacio en disco ni las operaciones de red que exigen las tablas. Sin embargo, dado que las matrices asociativas están destinadas al almacenamiento temporal, no puede manipularlas con sentencias DML.
Si declara una matriz asociativa en un paquete y asigna valores a la variable en el cuerpo del paquete, la matriz asociativa existirá mientras dura la sesión de la base de Datos. De lo contrario, existirá mientras dure el subprograma en el qué se ha declarado.
Consulte también: Referencia de lenguaje PL/SQL de Oracle Database para obtener más información sobre las matrices asociativas
Declaración de Matrices Asociativas
Para declarar una matriz asociativa, declare un tipo de matriz asociativa y, a continuación, declare una variable de ese tipo.
El siguiente código muestra la sintaxis más sencilla:
TYPE array_type IS TABLE OF element_type INDEX BY key_type;
array_name array_type;
Una forma eficaz de declarar una matriz asociativa es mediante un cursor mediante el procedimiento siguiente. El procedimiento utiliza cada sentencia necesaria en su forma más simple, pero proporciona referencias a su sintaxis completa.
Para utilizar un cursor para declarar una matriz asociativa:
-
En la parte declarativa:
-
Declare el cursor:
CURSOR cursor_name IS query;Para obtener una sintaxis de declaración de cursor declarada completa, consulte Referencia de lenguaje PL/SQL de Oracle Database.
-
Declare el tipo de matriz asociativa:
TYPE array_type IS TABLE OF cursor_name%ROWTYPE INDEX BY { PLS_INTEGER | VARCHAR2 length }Para obtener una sintaxis de declaración de tipo de matriz asociativa completa, consulte Referencia de lenguaje PL/SQL de Oracle Database.
-
Declare una matriz asociativa de ese tipo:
array_name array_type;Para obtener una sintaxis de declaración de variables completa, consulte Referencia de lenguaje PL/SQL de Oracle Database.
-
El ejemplo 5-9 utiliza el procedimiento anterior para declarar dos matrices asociativas, employees_jobs y jobs_ y, después, declara una tercera matriz asociativa, job_titles, sin utilizar un cursor. Las primeras dos matrices se indexan por entero; la tercera se indexa por cadena.
Nota: La cláusula ORDER BY en la declaración de employees_jobs_cursor determina el orden de almacenamiento de los elementos de la matriz asociativa employee_jobs.
Ejemplo 5-9 Declaración de matrices asociativas
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 además:
-
Referencia de lenguaje PL/SQL de Oracle Database para la sintaxis de declaración de matriz asociativa
Relleno de Matrices Asociativas
La forma más eficaz de rellenar una matriz asociativa densa suele ser con una sentencia SELECT con una cláusula BULK COLLECT INTO.
Nota: Si una matriz asociativa densa es tan grande que una sentencia SELECT devolvería un juego de resultados demasiado grande para que quepa en la memoria, no utilice una sentencia SELECT. En su lugar, rellene la matriz con un cursor y la sentencia FETCH con las cláusulas BULK COLLECT INTO y LIMIT. Para obtener información sobre el uso de la sentencia FETCH con la cláusula BULK COLLECT INTO, consulte Referencia de lenguaje PL/SQL de Oracle Database.
No puede utilizar una sentencia SELECT para rellenar una matriz asociativa dispersa (como job_titles en "Declaring Associative Arrays"). En lugar de ello, debe utilizar una sentencia de asignación dentro de una sentencia LOOP. Para obtener información sobre las sentencias de bucle, consulte "Controlling Program Flow". El Ejemplo 5-10 utiliza las sentencias SELECT para rellenar las matrices asociativas employees_jobs y jobs_, que se indexan por entero. A continuación, utiliza una sentencia de asignación en una sentencia FOR LOOP, para rellenar la matriz asociativa job_titles, que se indexa por cadena.
Ejemplo 5-10 Relleno de matrices asociativas
-- 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 también: "Acerca de los Cursores"
Recorrido de Matrices Asociativas Densas
Una matriz asociativa densa (indexada por entero) no tiene intervalos entre elementos: cada elemento entre el primer y los últimos elementos está definido y tiene un valor (que puede ser NULL).
Puede recorrer una matriz densa con una sentencia FOR LOOP, como en el Example 5-11.
Al insertarla en la parte ejecutable del ejemplo que se muestra en Example 5-10, después del código que rellena la matriz employees_jobs, la sentencia FOR LOOP del ejemplo Example 5-11 imprime los elementos de la matriz employees_jobs en la orden en la que se han almacenado. Su orden de almacenamiento ha sido determinado por la cláusula ORDER BY en la declaración de employees_jobs_cursor que se ha utilizado para declarar employees_jobs (consulte el ejemplo en Example 5-9).
El límite superior de la sentencia FOR LOOP, employees_jobs.COUNT, invoca un método a la recopilación que devuelve el número de elementos en la matriz. Para obtener más información sobre COUNT, consulte Referencia del lenguaje PL/SQL de Oracle Database.
Ejemplo 5-11 Recorrido de una Matriza Asociativa 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
Recorrido de Matrices Asociativas Dispersas
Una matriz asociativa dispersa (indexada por cadena) puede tener intervalos entre elementos.
Puede recorrerlo con una sentencia WHILE LOOP, como en el Example 5-12.
Para ejecutar el código en el Ejemplo 5-12, que imprime los elementos de la matriz job_titles, complete los pasos siguientes:
-
Al final de la parte declarativa del Ejemplo 5-9, inserte esta declaración de variable:
i jobs.job_id%TYPE; -
En la parte ejecutable del Ejemplo 5-10, después del código que rellena la matriz job_titles, inserte el código del Ejemplo 5-12.
Ejemplo 5-12 Recorrido de una Matriz Asociativo Dispersa
/* 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
El ejemplo 5-12 incluye dos invocaciones de método de recopilación, job_titles.FIRST y job_titles.NEXT(i). job_titles.FIRST devuelve el primer elemento de job_titles, mientras que job_titles.NEXT(i) devuelve el subíndice que sigue a i. Para obtener más información sobre FIRST, consulte Referencia de lenguaje PL/SQL de Oracle Database. Para obtener más información sobre NEXT, consulte Referencia de lenguaje PL/SQL de Oracle Database.