Saltar la navegación

3.2.1.- Colecciones. Tablas anidadas.

Las tablas anidadas son colecciones de elementos, que no tienen límite superior fijo, y pueden aumentar dinámicamente su tamaño. Además podemos borrar elementos individuales.

Para declararlos utilizaremos la siguiente sintaxis:

TYPE nombre IS TABLE OF tipo_elementos [NOT NULL];

Donde tipo_elementos tendrá las mismas restricciones que para los VARRAY.

Al igual que pasaba con los VARRAY, al declarar una tabla anidada, ésta es automáticamente nula, por lo que deberemos inicializarla antes de usarla.

TYPE hijos IS TABLE OF agente;
hijos_fam hijos := hijos( agente(...) ...);

También podemos usar un constructor nulo.

Para referenciar elementos usamos la misma sintaxis que para los VARRAY.

Para extender una tabla usamos EXTEND exactamente igual que para los VARRAY. COUNT nos dirá el número de elementos, que no tiene por qué coincidir con LAST. LIMIT no tiene sentido y devuelve NULL. EXISTS(n) devuelve TRUE si el elemento existe, y FALSE en otro caso (el elemento ha sido borrado). FIRST devuelve el primer elemento que no siempre será 1, ya que hemos podido borrar elementos del principio. LAST devuelve el último elemento. PRIOR y NEXT nos dicen el antecesor y sucesor del elemento (ignorando elementos borrados). TRIM sin argumentos borra un elemento del final de la tabla. TRIM(n) borra n elementos del final de la tabla. TRIM opera en el tamaño interno, por lo que si encuentra un elemento borrado con DELETE, lo incluye para ser eliminado de la colección. DELETE(n) borra el n-ésimo elemento. DELETE(n, m) borra del elemento n al m. Si después de hacer DELETE, consultamos si el elemento existe nos devolverá FALSE.

Al trabajar con tablas anidadas podemos hacer que salte alguna de las siguientes excepciones, debidas a un mal uso de las mismas: COLECTION_IS_NULL, NO_DATA_FOUND, SUBSCRIPT_BEYOND_COUNT y VALUE_ERROR.

Ejemplos de uso de las tablas anidadas.

Diferentes operaciones sobre tablas anidadas.

DECLARE
TYPE numeros IS TABLE 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
tabla_numeros.DELETE(10);
num := tabla_numeros.LAST;     --num := 9
num := tabla_numeros.FIRST;     --num := 1
tabla_numeros.DELETE(1);
num := tabla_numeros.FIRST;     --num := 2
FOR i IN 1..4 LOOP
     tabla_numeros.DELETE(2*i);
END LOOP;
num := tabla_numeros.COUNT;     --num := 4
num := tabla_numeros.LAST;     --num := 9
...
END;

Posibles excepciones en su uso.

DECLARE
TYPE numeros IS TABLE OF NUMBER;
tabla_num numeros := numeros();
tabla1 numeros;
BEGIN
tabla1(5) := 0;     --lanzaría COLECTION_IS_NULL
tabla_num.EXTEND(5);
tabla_num.DELETE(4);
tabla_num(4) := 3;     --lanzaría NO_DATA_FOUND
tabla_num(6) := 10;     --lanzaría SUBSCRIPT_BEYOND_COUNT
tabla_num(-1) := 0;     --lanzaría SUBSCRIPT_OUTSIDE_LIMIT
tabla_num(‘y’) := 5;--lanzaría VALUE_ERROR
END;