Saltar la navegación

3.2.- Colecciones. Arrays de longitud variable.

Una colección es un grupo ordenado de elementos, todos del mismo tipo. Cada elemento tiene un subíndice único que determina su posición en la colección.

Una colección es un grupo ordenado de elementos, todos del mismo tipo. Cada elemento tiene un subíndice único que determina su posición en la colección.

En PL/SQL las colecciones sólo pueden tener una dimensión. PL/SQL ofrece 2 clases de colecciones: arrays de longitud variable y tablas anidadas.

Arrays de longitud variable.

Los elementos del tipo VARRAY son los llamados arrays de longitud variable. Son como los arrays de cualquier otro lenguaje de programación, pero con la salvedad de que a la hora de declararlos, nosotros indicamos su tamaño máximo y el array podrá ir creciendo dinámicamente hasta alcanzar ese tamaño. Un VARRAY siempre tiene un límite inferior igual a 1 y un límite superior igual al tamaño máximo.

Para declarar un VARRAY usaremos la sintaxis:

TYPE nombre IS {VARRAY | VARYING} (tamaño_máximo) OF tipo_elementos [NOT NULL];

Donde tamaño_máximo será un entero positivo y tipo_elementos será cualquier tipo de dato válido en PL/SQL, excepto BINARY_INTEGER, BOOLEAN , LONG, LONG RAW , NATURAL, NATURALN , NCHAR, NCLOB , NVARCHAR2, objetos que tengan como atributos TABLE o VARRAY, PLS_INTEGER , POSITIVE, POSITIVEN , SIGNTYPE, STRING , TABLE, VARRAY . Si tipo_elementos es un registro, todos los campos deberían ser de un tipo escalar.

Cuando definimos un VARRAY, éste es automáticamente nulo, por lo que para empezar a utilizarlo deberemos inicializarlo. Para ello podemos usar un constructor:

TYPE familias_hijas IS VARRAY(100) OF familia;
                familias_hijas1 familias_hijas := familias_hijas( familia(100, ’Fam100’, 10, null), ..., familia(105, ’Fam105’, 10, null));
         
    

También podemos usar constructores vacíos.

familias_hijas2 familias_hijas := familias_hijas();
    

Para referenciar elementos en un VARRAY utilizaremos la sintaxis nombre_colección(subíndice). Si una función devuelve un VARRAY, podemos usar la sintaxis: nombre_funcion(lista_parametros)(subindice).

IF familias_hijas1(i).identificador = 100 THEN ...
                IF dame_familias_hijas(10)(i).identificador = 100 THEN ...
    

Un VARRAY puede ser asignado a otro si ambos son del mismo tipo.

DECLARE
                TYPE tabla1 IS VARRAY(10) OF NUMBER;
                TYPE tabla2 IS VARRAY(10) OF NUMBER;
                mi_tabla1 tabla1 := tabla1();
                mi_tabla2 tabla2 := tabla2();
                mi_tabla tabla1 := tabla1();
                BEGIN
                ...
                mi_tabla := mi_tabla1;          --legal
                mi_tabla1 := mi_tabla2;     --ilegal
                ...
                END;
    

Para extender un VARRAY usaremos el método EXTEND. Sin parámetros, extendemos en 1 elemento nulo el VARRAY. EXTEND(n) añade n elementos nulos al VARRAY y EXTEND(n,i) añade n copias del i-ésimo elemento.

COUNT nos dirá el número de elementos del VARRAY. LIMIT nos dice el tamaño máximo del VARRAY. FIRST siempre será 1. LAST siempre será igual a COUNT. PRIOR y NEXT devolverá el antecesor y el sucesor del elemento.

Al trabajar con VARRAY podemos hacer que salte alguna de las siguientes excepciones, debidas a un mal uso de los mismos: COLECTION_IS_NULL, SUBSCRIPT_BEYOND_COUNT, SUBSCRIPT_OUTSIDE_LIMIT y VALUE_ERROR.

Ejemplos de uso de los VARRAY.

  • Extender un VARRAY.
DECLARE
           TYPE tab_num IS VARRAY(10) OF NUMBER;
           mi_tab tab_num;
BEGIN
            mi_tab := tab_num();
            FOR i IN 1..10 LOOP
                    mi_tab.EXTEND;
                     mi_tab(i) := calcular_elemento(i);
            END LOOP;
                      ...
END;
  • Consultar propiedades VARRAY.
DECLARE 
   TYPE numeros IS VARRAY(20) OF NUMBER;
   tabla_numeros numeros := numeros(); 
   num NUMBER;
BEGIN
    num := tabla_numeros.COUNT; --num := 0 
    FOR i IN 1..10 LOOP 
             tabla_numeros.EXTEND; 
             tabla_numeros(i) := i;
    END LOOP;
    num := tabla_numeros.COUNT; --num := 10 
    num := tabla_numeros.LIMIT; --num := 20
    num := tabla_numeros.FIRST; --num := 1;
    num := tabla_numeros.LAST; --num := 10; 
...
END;
  • Posibles excepciones.
DECLARE
  TYPE numeros IS VARRAY(20) OF INTEGER; 
  v_numeros numeros := numeros( 10, 20, 30, 40 ); 
  v_enteros numeros;
BEGIN
   v_enteros(1) := 15; --lanzaría COLECTION_IS_NULL
   v_numeros(5) := 20; --lanzaría SUBSCRIPT_BEYOND_COUNT
   v_numeros(-1) := 5; --lanzaría SUBSCRIPT_OUTSIDE_LIMIT v_numeros(‘A’) := 25; -- 
 lanzaría VALUE_ERROR 
....
END;

Los constructores son funciones o métodos cuyo nombre es igual al nombre de su objeto. Se utilizan para inicializar un objeto. En la mayoría de los casos, esta inicialización asigna valores a los miembros del objeto.

Autoevaluación

Pregunta

Indica, de entre las siguientes, cuál es la afirmación correcta referida a VARRAY.

Respuestas

Un VARRAY no hace falta inicializarlo.

COUNT y LIMIT siempre nos devolverán el mismo valor.

LAST y COUNT siempre nos devolverán el mismo valor.

Retroalimentación