Oracle Colecciones PL/SQL: Varrays, anidadas e indexadas por tablas

โšก Resumen inteligente

Las colecciones PL/SQL son grupos ordenados de elementos del mismo tipo de datos, a los que se accede mediante un subรญndice. Existen tres tipos: Varray, tabla anidada y tabla indexada, que se diferencian en si el tamaรฑo es fijo, cรณmo funciona el subรญndice y si se pueden almacenar en la base de datos.

  • ๐Ÿงบ Definiciรณn: Una colecciรณn contiene muchos elementos de un mismo tipo, cada uno identificado por un subรญndice รบnico.
  • ๐Ÿ“ Varray: Tamaรฑo superior fijo, siempre denso, subรญndice numรฉrico, debe inicializarse antes de su uso.
  • ๐Ÿ“š Tabla anidada: Sin lรญmite de tamaรฑo, puede ser denso o disperso, se almacena en una tabla del sistema y se extiende con EXTEND.
  • ๐Ÿ”‘ รndice por tabla: Sin lรญmite de tamaรฑo, el subรญndice puede ser una cadena o un nรบmero entero negativo, no se almacena en la base de datos.
  • ???? ๏ธ Constructores: Los arrays variables y las tablas anidadas necesitan un constructor explรญcito para inicializarse antes de hacer referencia a ellos.
  • ๐Ÿ› ๏ธ Mรฉtodos: Las funciones COUNT, EXISTS, FIRST, LAST, EXTEND, TRIM y DELETE gestionan una colecciรณn.
  • โšก Abultar: BULK COLLECT completa una colecciรณn en un solo paso para un procesamiento rรกpido.

Oracle Colecciones PL/SQL

ยฟQuรฉ es una colecciรณn?

Una colecciรณn es un grupo ordenado de elementos de un tipo de dato especรญfico. Puede ser una colecciรณn de un tipo de dato simple o de un tipo de dato complejo, como los tipos definidos por el usuario o los tipos de registro.

En una colecciรณn, cada elemento se identifica mediante un tรฉrmino llamado "subรญndice." A cada elemento se le asigna un subรญndice รบnico, y los datos se pueden manipular u obtener haciendo referencia a ese subรญndice รบnico.

Las colecciones son mรกs รบtiles cuando se necesita procesar o manipular una gran cantidad de datos del mismo tipo. Las colecciones se pueden llenar y manipular en su conjunto utilizando la opciรณn 'BULK' en Oracle.

Las colecciones se clasifican segรบn su estructura, subรญndice y almacenamiento, como se muestra a continuaciรณn:

  • Tablas indexadas (tambiรฉn conocidas como matrices asociativas)
  • Tablas anidadas
  • Varrays

En cualquier momento, los datos de una colecciรณn pueden ser referenciados mediante tres tรฉrminos: nombre de la colecciรณn, subรญndice y nombre del campo o columna, como โ€œ ( ). Aprenderรกs sobre estas categorรญas de colecciรณn en las secciones siguientes.

Tipos de colecciones de un vistazo

Los tres tipos de colecciones presentan diferentes ventajas y desventajas. La siguiente tabla las compara antes de analizar cada una en detalle.

Aspecto Varray Tabla anidada Tabla de รญndices por
Tamaรฑo Lรญmite superior fijo No hay lรญmite No hay lรญmite
subรญndice Numรฉrico Numรฉrico Nรบmero entero o cadena de caracteres
Densidad Siempre denso Denso o disperso Siempre escaso
Almacenado en la base de datos Sรญ: Sรญ: No
Necesita inicializaciรณn Sรญ: Sรญ: No

Varrays

Un Varray es una colecciรณn cuyo tamaรฑo es fijo y no puede excederse. El subรญndice de un Varray es un valor numรฉrico. Los atributos de los Varrays son:

  • El tamaรฑo lรญmite superior es fijo.
  • Se rellenan secuencialmente comenzando con el subรญndice '1'.
  • Este tipo de colecciรณn siempre es densa; no podemos eliminar elementos individuales de la matriz. Un Varray se puede eliminar por completo o recortar desde el final.
  • Debido a su densidad constante, tiene muy poca flexibilidad.
  • Resulta mรกs apropiado cuando se conoce el tamaรฑo del array y se realizan actividades similares en todos los elementos.
  • El subรญndice y el nรบmero de elementos de la colecciรณn siempre permanecen estables.
  • Debe inicializarse antes de su uso. Cualquier operaciรณn que no sea EXISTS en una colecciรณn no inicializada generarรก un error.
  • Se puede crear como un objeto de base de datos visible en toda la base de datos, o dentro de un subprograma para su uso exclusivo en ese รกmbito.

La siguiente figura explica la asignaciรณn de memoria de un Varray (denso).

subรญndice 1 2 3 4 5 6 7
Valor Xyz dfv editores cxs vbc Nhu qwe

Sintaxis de VARRAY:

TYPE <type_name> IS VARRAY (<SIZE>) OF <DATA_TYPE>;
  • En la sintaxis anterior, type_name se declara como un VARRAY del tipo 'DATA_TYPE' para el lรญmite de tamaรฑo especificado. El tipo de dato puede ser simple o complejo.

Tablas anidadas

Una tabla anidada es una colecciรณn cuyo tamaรฑo no es fijo. Tiene un tipo de รญndice numรฉrico. Mรกs informaciรณn sobre el tipo de tabla anidada:

  • La tabla anidada no tiene lรญmite de tamaรฑo superior.
  • Dado que el lรญmite superior no es fijo, es necesario ampliar la memoria cada vez antes de su uso, utilizando la palabra clave 'EXTEND'.
  • Se rellenan secuencialmente comenzando con el subรญndice '1'.
  • Este tipo de colecciรณn puede ser ambos denso y escasoPodemos crearlo denso y tambiรฉn eliminar elementos individuales al azar, lo que lo hace disperso.
  • Ofrece mayor flexibilidad para eliminar elementos de la matriz.
  • Se almacena en una tabla de base de datos generada por el sistema y se puede utilizar en una consulta SELECT para obtener valores.
  • El subรญndice y el recuento pueden variar.
  • Debe inicializarse antes de su uso. Cualquier operaciรณn que no sea EXISTS en una colecciรณn no inicializada generarรก un error.
  • Se puede crear como un objeto de base de datos visible en toda la base de datos, o dentro de un subprograma para su uso exclusivo en ese รกmbito.

La siguiente figura explica la asignaciรณn de memoria de una tabla anidada (densa y dispersa). Un espacio vacรญo indica un elemento disperso.

subรญndice 1 2 3 4 5 6 7
Valor (denso) Xyz dfv editores cxs vbc Nhu qwe
Valor (disperso) qwe Asd afg Asd ยฟQuiรฉn

Sintaxis de tabla anidada:

TYPE <type_name> IS TABLE OF <DATA_TYPE>;
  • En la sintaxis anterior, type_name se declara como una colecciรณn de tablas anidadas del tipo 'DATA_TYPE'. El tipo de datos puede ser simple o complejo.

Tabla de รญndices por

Una tabla indexada es una colecciรณn cuyo tamaรฑo no es fijo. A diferencia de otros tipos de colecciones, el usuario puede definir el รญndice de una tabla indexada. Los atributos de una tabla indexada son:

  • El subรญndice puede ser un nรบmero entero o una cadena de texto. El tipo de subรญndice debe especificarse al crear la colecciรณn.
  • Estas colecciones no se almacenan secuencialmente.
  • Siempre son escasos en la naturaleza.
  • El tamaรฑo de la matriz no es fijo.
  • No se pueden almacenar en una columna de la base de datos. Se crean y utilizan dentro de una sesiรณn especรญfica.
  • Ofrecen mayor flexibilidad para mantener el subรญndice.
  • Los subรญndices pueden ser una secuencia negativa.
  • Son mรกs apropiadas para conjuntos de valores relativamente pequeรฑos utilizados dentro del mismo subprograma.
  • No es necesario inicializarlos antes de su uso.
  • No se pueden crear como un objeto de base de datos; solo se crean dentro de un subprograma.
  • La funciรณn BULK COLLECT no se puede utilizar con este tipo de recopilaciรณn, ya que el subรญndice debe especificarse explรญcitamente para cada registro.

La siguiente figura explica la asignaciรณn de memoria de una tabla indexada (dispersa). Un espacio vacรญo indica un elemento disperso.

Subรญndice (varchar) PRIMERO SEGUNDO TERCER CUARTO QUINTO SEXTO Sร‰PTIMO
Valor (disperso) qwe Asd afg Asd ยฟQuiรฉn

Sintaxis para la indexaciรณn por tabla:

TYPE <type_name> IS TABLE OF <DATA_TYPE> INDEX BY VARCHAR2 (10);
  • En la sintaxis anterior, type_name se declara como una colecciรณn de tablas indexadas del tipo 'DATA_TYPE'. La variable de subรญndice se especifica como de tipo VARCHAR2 con un tamaรฑo mรกximo de 10.

Constructor y concepto de inicializaciรณn en colecciones.

Los constructores son funciones integradas proporcionadas por Oracle que tienen el mismo nombre que el objeto o la colecciรณn. Se ejecutan primero cuando se hace referencia a un objeto o colecciรณn por primera vez en una sesiรณn. Detalles importantes de un constructor en el contexto de la colecciรณn:

  • En el caso de las colecciones, estos constructores deben llamarse explรญcitamente para inicializar la colecciรณn.
  • Tanto los arrays de tipo Varray como las tablas anidadas deben inicializarse mediante estos constructores antes de poder ser utilizados en el programa.
  • Un constructor extiende implรญcitamente la asignaciรณn de memoria para una colecciรณn (excepto Varray), por lo que tambiรฉn puede asignar variables a la colecciรณn.
  • Asignar valores mediante constructores nunca hace que la colecciรณn sea dispersa.

Mรฉtodos de recolecciรณn

Oracle Ofrece numerosas funciones para manipular y trabajar con colecciones. Estas funciones determinan y modifican los diferentes atributos de una colecciรณn. La siguiente tabla muestra las distintas funciones y sus descripciones.

Mรฉtodo Mareas Ideales para Lecciones Sintaxis
EXISTE (n) Devuelve un resultado booleano. Devuelve VERDADERO si existe el enรฉsimo elemento, de lo contrario, FALSO. Solo EXISTS puede usarse en una colecciรณn no inicializada. .EXISTS(posiciรณn_elemento)
COUNT Indica el nรบmero total de elementos presentes en una colecciรณn. .COUNT
LIMITE LAS Devuelve el tamaรฑo mรกximo de la colecciรณn. Para Varray, devuelve el tamaรฑo fijo; para tablas anidadas e indexadas, devuelve NULL. .LIMIT
PRIMERO Devuelve el valor del primer subรญndice de la colecciรณn. .FIRST
รšLTIMO Devuelve el valor del รบltimo subรญndice de la colecciรณn. .LAST
ANTERIOR (n) Devuelve el subรญndice precedente del enรฉsimo elemento. Si no hay ninguno, devuelve NULL. .PRIOR(n)
SIGUIENTE (n) Devuelve el subรญndice siguiente al enรฉsimo elemento. Si no hay ninguno, devuelve NULL. .NEXT(n)
AMPLIAR Extiende un elemento al final de una colecciรณn. .EXTEND
EXTENDER (n) Extiende n elementos al final de una colecciรณn. .EXTEND(n)
EXTENDER (n,i) Extiende n copias del i-รฉsimo elemento al final de la colecciรณn. .EXTEND(n,i)
TRIM Elimina un elemento del final de la colecciรณn. .TRIM
RECORTAR (n) Elimina n elementos del final de la colecciรณn. .TRIM (n)
BORRAR Elimina todos los elementos de la colecciรณn, dejรกndola vacรญa. .BORRAR
BORRAR (n) Elimina el enรฉsimo elemento. Si el enรฉsimo elemento es NULL, no hace nada. .DELETE(n)
BORRAR (m,n) Elimina los elementos comprendidos entre el mth y el nth de la colecciรณn. .DELETE(m,n)

Ejemplo 1: Tipo de registro a nivel de subprograma

En este ejemplo, vemos cรณmo llenar la colecciรณn usando 'COLECCIร“N A GRANEL'y cรณmo hacer referencia a los datos de la colecciรณn.

Colecciรณn PL/SQL rellenada con un ejemplo de BULK COLLECT

DECLARE
TYPE emp_det IS RECORD
(
EMP_NO NUMBER,
EMP_NAME VARCHAR2(150),
MANAGER NUMBER,
SALARY NUMBER
);
TYPE emp_det_tbl IS TABLE OF emp_det;
guru99_emp_rec emp_det_tbl:= emp_det_tbl();
BEGIN
INSERT INTO emp (emp_no,emp_name, salary, manager) VALUES (1000,'AAA',25000,1000);
INSERT INTO emp (emp_no,emp_name, salary, manager) VALUES (1001,'XXX',10000,1000);
INSERT INTO emp (emp_no, emp_name, salary, manager) VALUES (1002,'YYY',15000,1000);
INSERT INTO emp (emp_no,emp_name,salary, manager) VALUES (1003,'ZZZ',7500,1000);
COMMIT;
SELECT emp_no,emp_name,manager,salary BULK COLLECT INTO guru99_emp_rec
FROM emp;
dbms_output.put_line ('Employee Detail');
FOR i IN guru99_emp_rec.FIRST..guru99_emp_rec.LAST
LOOP
dbms_output.put_line ('Employee Number: '||guru99_emp_rec(i).emp_no);
dbms_output.put_line ('Employee Name: '||guru99_emp_rec(i).emp_name);
dbms_output.put_line ('Employee Salary:'|| guru99_emp_rec(i).salary);
dbms_output.put_line('Employee Manager Number:'||guru99_emp_rec(i).manager);
dbms_output.put_line('--------------------------------');
END LOOP;
END;
/

Code Explicaciรณn

  • Code lรญneas 2-8: Tipo de registro 'emp_det' se declara con las columnas emp_no, emp_name, manager y salary de tipo de datos NUMBER, VARCHAR2, NUMBER y NUMBER.
  • Code lรญnea 9: Creando la colecciรณn 'emp_det_tbl' del elemento de tipo registro 'emp_det'.
  • Code lรญnea 10: Declarar la variable 'guru99_emp_rec' como de tipo 'emp_det_tbl' e inicializarla con un constructor nulo.
  • Code lรญneas 12-15: Insertar los datos de muestra en la tabla 'emp'.
  • Code lรญnea 16: Confirmando la transacciรณn de inserciรณn.
  • Code lรญnea 17: Se recuperan los registros de la tabla 'emp' y se rellena la variable de colecciรณn de forma masiva mediante "BULK COLLECT". La variable 'guru99_emp_rec' ahora contiene todos los registros presentes en la tabla 'emp'.
  • Code lรญneas 19-26: Configurar el bucle 'FOR' para imprimir todos los registros de la colecciรณn uno por uno. Los mรฉtodos de colecciรณn FIRST y LAST se utilizan como lรญmites inferior y superior de la colecciรณn. loops.

Salida: Cuando se ejecuta el cรณdigo anterior, se obtiene la siguiente salida.

Employee Detail
Employee Number: 1000
Employee Name: AAA
Employee Salary: 25000
Employee Manager Number: 1000
----------------------------------------------
Employee Number: 1001
Employee Name: XXX
Employee Salary: 10000
Employee Manager Number: 1000
----------------------------------------------
Employee Number: 1002
Employee Name: YYY
Employee Salary: 15000
Employee Manager Number: 1000
----------------------------------------------
Employee Number: 1003
Employee Name: ZZZ
Employee Salary: 7500
Employee Manager Number: 1000
----------------------------------------------

Preguntas Frecuentes

Un Varray tiene un tamaรฑo mรกximo fijo y siempre es denso. Una tabla anidada no tiene lรญmite de tamaรฑo, puede ser dispersa y se puede extender, lo que la hace mรกs flexible para datos en crecimiento o con huecos.

Dado que se trata de una matriz asociativa en memoria, no de una tabla almacenada, el subรญndice actรบa como clave de bรบsqueda, por lo que funciona con cadenas de texto o nรบmeros enteros negativos, lo cual resulta รบtil para bรบsquedas por clave dentro de una sesiรณn.

Un Varray o tabla anidada no inicializada es atรณmicamente nula, por lo que hacer referencia a un elemento genera un error. Llamar al constructor lo asigna, tras lo cual se pueden aรฑadir datos mediante EXTEND y otras asignaciones.

Sรญ. En funciรณn de si el tamaรฑo es fijo, si los datos se almacenan y si se necesita una clave de cadena, la IA puede seรฑalar un Varray, una tabla anidada o una tabla indexada y explicar las ventajas y desventajas.

BULK COLLECT carga todas las filas en una colecciรณn en un รบnico cambio de contexto entre los motores SQL y PL/SQL, en lugar de un cambio por fila, lo que reduce considerablemente la sobrecarga en conjuntos de resultados grandes.

Resumir este post con: