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.

ยฟ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.
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 ----------------------------------------------

