Está en la página 1de 13

PL/SQL 2 TIPOS DE DATOS ESTRUCTURADOS O COMPUESTOS

En PL/SQL podemos distinguir como tipos de Datos

Estructurados o Compuestos:
o o Los Registros Las Colecciones: Los Varrays Las Tablas: (indexadas, anidadas,multinivel)

Los Registros permiten tratar una serie de variables de tipos que pueden ser diferentes como una única unidad. Como los registros en otros lenguajes (C, Java,...) Las Colecciones combinan variables del mismo tipo, para ser tratadas también como una unidad. Como hacen los arrays o las matrices en otros lenguajes. RECORD

“Son agrupaciones de datos relacionados similares a las estructuras (struct) del lenguaje C o los registros de Modula2.”
Un registro proporciona un mecanismo para tratar con variables diferentes relacionadas entre sí, como si fueran una una única unidad. Declaración Sintaxis: TYPE tipo_registro IS RECORD ( campo1 tipo1 [NOT NOT NULL] NULL [:= expr1], ... campon tipon [NOT NOT NULL] NULL [:= exprn]);

tipo_registro es el nombre del nuevo tipo campoi son los nombres de los campos incluidos en el registro tipoi son los tipos correspondientes a los campos
Ejemplo: DECLARE TYPE t_registro_simple IS RECORD ( Codigo NUMBER(4), Nombre VARCHAR2(10):=’Pepe’, Fecha_alta DATE, Comentario VARCHAR2(45) NOT NULL:=’Desconocido’); NULL:= --Declaración de variables asociadas a los tipos definidos v_simple1 t_registro_simple; v_simple2 t_registro_simple; Para hacer referencia a uno de los campos del registro, se emplea la notación “de punto”:

nombre_registro.nombre_campo

25

*/ v_reg1.campo2 := v_reg2. END. END Asignación de Registros Para poder asignar un registro a otro. que extraiga los datos y los almacene en un registro compatible. por tanto. Campo2 VARCHAR2(5)). v_simple1:= v_simple2 . se pueden asignar “campo a campo”.Comentario:=’Le falta la poliza’. SELECT columna1. los campos son del mismo tipo. TYPE t_ t_regtipo2 IS RECORD ( Campo1 NUMBER.campo1. Campo2 VARCHAR2(5)). ….Fecha_alta:=SYSDATE SYSDATE. Esta es una asignación ilegal que genera el error PLSPLS-382.PL/SQL 2 Con la declaración de tipos del ejemplo anterior Ejemplo: Ejemplo: BEGIN /* SYSDATE función predefinida que devuelve la fecha y hora del sistema asignamos a las variables definidas en el ejemplo los valores siguientes*/ v_simple1.…. columnan compatibles con los campos correspondientes del registro 26 .campo2. v_reg1 t_regtipo1. ambos tienen que ser del mismo tipo. /* Sin embargo. columnan INTO v_registro … Siendo columna1. v_reg1.campo1 := v_reg2. Asignación válida Las asignaciones de registros utilizan la semántica de copia: “los valores de un registro son asignados a los campos correspondientes del otro registro” Si dos registros son de tipos distintos no se pueden asignar. END / También se puede asignar un valor a un registro mediante una instrucción SELECT . aunque tengan definidos los mismos tipos de campos. En caso de asignación no válida obtendremos el error: PLSPLS-00382: 00382: el tipo de la expresión no es correcto Ejemplo: : Ejemplo DECLARE TYPE t_regtipo1 IS RECORD ( Campo1 NUMBER. 382 */ v_reg1 := v_reg2. los tipos de registros en sí mismos son diferentes. las siguientes asignaciones son legales. SYSDATE v_simple2. END. BEGIN /* Aunque v_ reg1 y v_reg2 tienen los mismos nombres y tipos de campo. v_reg2 t_regtipo2. En este caso.

PL/SQL 2 Utilización de %ROWTYPE Es habitual definir un registro con los mismos tipos que una fila de una tabla. si se modifica la tabla también se modifica automáticamente este tipo definido con %ROWTYPE. Además. Para facilitar esa labor PL/SQL incorpora el operador %ROWTYPE. No se heredan las posibles restricciones de NOT NULL que puedan estar definidas en la tabla. Sintaxis: DECLARE v_registroStudents Students%ROWTYPE. major VARCHAR2(30). first_name VARCHAR2(20). v_registroStudents tendría la estructura: ( id NUMBER(5). current_credits NUMBER(3)). %ROWTYPE De forma similar %TYPE. last_name VARCHAR2(20). %ROWTYPE devuelve un tipo basándose en la definición de la tabla que se le indique. 27 . Define un registro cuyos campos son idénticos a las columnas de Students.

cada uno de los cuales está restringido para no ser un elemento nulo. OF students%ROWTYPE. 28 . Declaración Sintaxis: TYPE nombre_tipo IS {VARRAY|VARYING VARRAY|VARYING ARRAY} (límite_superior) NOT NULL]. En particular hablaremos de los métodos delas colecciones VARRAY “Matriz de longitud variable. Es un tipo de dato similar a los arrays en otros lenguajes” Se limita la dimensión del varray fijando el límite superior. TYPE ObjectList is VARRAY(25) VARRAY OF MyObject. NCLOB NVARCHAR2 o REF CURSOR. NULL -. BOOLEAN NCHAR. El tamaño máximo de un varray es de 2 Gigabytes. NCHAR NCLOB. TYPE StudentList IS VARRAY(100) VARRAY -. -. CURSOR (Sólo desde la versión 9i puede ser TABLE o VARRAY) VARRAY Ejemplo: Ejemplo: DECLARE -.PL/SQL 2 COLECCIONES Como ya hemos comentado las colecciones son tipos de Datos Estructurados en PL/SQL que pueden ser VARRAYS y TABLAS El tratamiento de estos dos tipos tiene características similares por lo que se les engloban en el tipo colecciones. OF tipo_elemento [NOT NULL Nombre_tipo es el nombre del nuevo tipo límite_superior es un entero que especifica el número máximo de elementos tipo_elemento es un escalar.Una lista de números. %ROWTYPE.Una lista de objetos.Una lista de registros PL/SQL. TYPE NumberList IS VARRAY(10) OF NUMBER(3) VARRAY NUMBER NOT NULL. un registro o cualquier otro tipo de objeto El tipo_elemento no puede ser BOOLEAN.Tipos de varray válidos.

-.PUT_LINE('v_List2(1) is NULL'). toma un número variable de argumentos. VARRAY NUMBER -. De esta manera en el ejemplo anterior v_List2(1) accede a la primera posición de la variable varray v_List2. Numbers BEGIN IF v_NullList IS NULL THEN DBMS_OUTPUT. por la asignación: v_List2 Numbers := Numbers(NULL). que son compatibles con el tipo de los elementos del varray.Declara un varray NULL.Este varray tiene 2 elementos. v_NullList Numbers. END. IF IF v_List2(1) IS NULL THEN DBMS_OUTPUT.PUT_LINE('v_NullList is NULL').En negrita Numbers se refiere a los constructores -. END IF. Si se hacen asignaciones a los elementos que quedan fuera de este rango se producirá el error: “ORA-06533: Subíndice mayor que el recuento” 29 . es decir se utiliza un índice que comienza en el valor 1 y termina en el correspondiente al límite superior definido en la declaración. / Manipulación de los elementos de un varray Para acceder a los elementos del varray se hace lo mismo que en lo arrays en otros lenguajes. Ejemplo: Ejemplo: DECLARE -. que es NULL. nombre_var_varray(índice) Donde índice>=1 y índice<=límite_superior. v_List2 Numbers := Numbers(NULL). Numbers 2). constructor Un constructor toma el mismo nombre que la variable varray. (que efectivamente tiene el valor NULL. -. TYPE Numbers IS VARRAY(20) OF NUMBER(3).Define un tipo VARRAY.) Numbers El tamaño inicial de un varray se establece mediante el número de elementos usados en el constructor utilizado para declararlo.PL/SQL 2 Inicialización de un varray Para inicializar un varray es necesario utilizar un constructor. v_List1 Numbers := Numbers(1.Declaración de variables del tipo definido Number -. END IF.Este varray tiene un elemento.

v_Lista1 Numbers := Numbers(1. DBMS_OUTPUT.PUT_LINE('v_Lista1(1)= '|| v_Lista1(1)). BEGIN DBMS_OUTPUT. END. EXTEND que tiene la siguiente sintaxis: variable_varray.PUT_LINE('v_Lista1(3)= '|| v_Lista1(3)). v_Lista1.EXTEND.PL/SQL 2 Ejemplo: DECLARE TYPE Numbers IS VARRAY(3) VARRAY OF NUMBER(3). END. / La salida de este bloque sera: v_Lista1(1)= 1 v_Lista1(2)= 2 v_Lista1(3)= 3 En cualquier caso al el límite superior en la declaración del tipo varray este no puede superarse. Ejemplo DECLARE TYPE Numbers IS VARRAY(3) VARRAY OF NUMBER(3). DBMS_OUTPUT.PUT_LINE('v_Lista1(2)= '|| v_Lista1(2)). BEGIN DBMS_OUTPUT.PUT_LINE('v_Lista1(2)= '|| v_Lista1(2)). v_Lista1(3):=3. DBMS_OUTPUT. DBMS_OUTPUT. / La salida de este bloque sería: v_Lista1(1)= 1 v_Lista1(2)= 2 DECLARE * ERROR en línea 1: ORAORA-06533: Subíndice mayor que el recuento ORA-06512: en línea 7 Para ampliar el varray se utiliza el método EXTEND.PUT_LINE('v_Lista1(1)= '|| v_Lista1(1)). v_Lista1 Numbers := Numbers(1.EXTEND EXTEND que permite ampliar en 1 la dimensión del vector definida en el constructor(sin superar el límite máximo).PUT_LINE('v_Lista1(3)= '|| v_Lista1(3)). si se intenta superar se obtiene el error: “ORA-06532: Subíndice fuera del límite” 30 . 2). 2).

v_Lista1(3):=3. END.PL/SQL 2 Ejemplo: DECLARE TYPE Numbers IS VARRAY(3) VARRAY OF NUMBER(3). BEGIN DBMS_OUTPUT.PUT_LINE('v_Lista1(1)= '|| v_Lista1(1)). DBMS_OUTPUT. END. / Tiene como salida: v_Lista1(1)= 1 v_Lista1(2)= 2 v_Lista1(3)= 3 DECLARE * ERROR en línea 1: ORA-06532: Subíndice fuera del límite ORA-06512: en línea 10 31 .EXTEND.EXTEND.PUT_LINE('v_Lista1(2)= '|| v_Lista1(2)). v_Lista1 Numbers := Numbers(1. DBMS_OUTPUT. v_Lista1(4):=4. v_Lista1. 2).PUT_LINE('v_Lista1(3)= '|| v_Lista1(3)). v_Lista1. DBMS_OUTPUT.PUT_LINE('v_Lista1(4)= '|| v_Lista1(4)).

Una vez declarado el tipo y la variable se accede a los elementos individuales de la tabla a través del índice como en el caso del varray: varray nombre_var_tabla(índice) donde nombre_var_tabla es el nombre de la tabla índice es una variable de tipo BINARY_INTEGER o bien una variable o expresión que pueda convertirse en BINARY_INTEGER Ejemplo: Ejemplo Con la declaración de tipos y variables del ejemplo anterior podríamos hacer las siguientes asignaciones: BEGIN v_Names(1) := 'Scott'. Sintaxis: TYPE tipo_tabla IS TABLE OF tipo INDEX BY BINARY_INTEGER. v_Dates DateTab. --Se declara un tipo tabla_indexada del tipo predefinido fecha TYPE DateTab IS TABLE OF DATE INDEX BY BINARY_INTEGER. +2147483647) Ejemplo DECLARE --Se declara un tipo tabla_indexada del mismo tipo que el atributo first_name de la tabla -. --Declaración de dos variables de los tipos anteriores v_Names NameTab. Tablas Indexadas Son similares sintácticamente a las matrices de C o Java. v_Dates(-4) := SYSDATE .students TYPE NameTab IS TABLE OF students.first_name%TYPE TYPE INDEX BY BINARY_INTEGER. tipo_tabla es el nombre del nuevo tipo tipo es un tipo predefinido o bien una referencia a un tipo (%TYPE. La cláusula INDEX BY BINARY_INTEGER es obligatoria como parte de la definición de tabla indexada. END 32 .1.. tabla anidada y tabla multinivel. END.%ROWTYPE) BINARY_INTEGER (-2147483647 .PL/SQL 2 TABLE En este apartado hablaremos de los tipos tabla indexada.

Asigna valores a tres de los elementos de la tabla -. / La Estructura de Datos de v_caracteres sería similar a : KEY 0 -7 3 Destaquemos algunos aspectos: Las tablas indexadas no están restringidas. Una tabla indexada tiene una estructura similar a la de una tabla de base de datos con dos columnas: KEY y VALUE. v_caracteres tabla_caracteres. Así mismo la referencia al elemento i es similar a un SELECT (WHERE KEY= i) Así en muchos sentidos el comportamiento de una tabla indexada es similar al de una tabla abla de BD. END. la implementación de las tablas en PL/SQL es diferente. Los elementos que se encuentran almacenados en una tabla indexada no guardan ningún orden particular.Observad que los valores de la KEY no son secuenciales v_caracteres(0) := 'Harold'. crea dicho elemento si todavía no existe (similar a un INSERT en una tabla de BD). Si ejecutamos el siguiente bloque: DECLARE TYPE tabla_caracteres IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER. v_caracteres(-7) := 'Susan'. Que es similar al error que se produce al hacer un SELECT en una tabla vacía Tablas indexadas de tipos no escalares: De registros: Su declaración es similar: TYPE tipo_tabla IS TABLE OF tipo_registro. restringidas la única restricción es que la KEY debe ser un BINARY_INTEGER. v_caracteres(3) := 'Steve'. 33 . La asignación de un valor al elemento i de una tabla indexada. VALUE El tipo KEY es BINARY_INTEGER y VALUE es del tipo especificado.PL/SQL 2 A pesar del parecido entre el tipo tabla indexada y matrices en C o Java. BD Si por ejemplo hacemos referencia al elemento i antes de ser creado obtendremos el error : VALUE Harold Susan Steve “ORA-01403: no se han encontrado datos “. particular no se almacenan de manera contigua en memoria Las KEYS utilizadas en una tabla indexada no tiene por que ser secuenciales El único valor permitido para la KEY es BINARY_INTEGER. BEGIN -.

Además las tablas anidadas pueden almacenarse en la Base de Datos. v_major(2).NVARCHAR2 ni REF CURSOR CURSOR La única diferencia sintáctica entre una tabla indexada y una anidada es la presencia de la cláusula INDEX BY BINARY_INTEGER. se puede pensar en una tabla anidada como en una tabla de BD con dos campos KEY y VALUE.PL/SQL 2 Dado que cada elemento de una tabla de este tipo es un registro el acceso a los valores de la misma hay que hacerlo a través del índice y del campo correspondiente: nombre_var_tabla(índice). nombre_tabla es el nombre del nuevo tipo tipo_tabla es el tipo de cada elemento de la tabla anidada El tipo_tabla puede ser un tipo de objeto definido por el usuario o una expresión que utilice %TYPE.campo Ejemplo: DECLARE TYPE tabla_major IS TABLE OF major_stats%ROWTYPE INDEX BY BINARY_INTEGER.total_students := 0. v_major tabla_major.Define un tipo de tabla anidada basado en un tipo de registro TYPE t_registro IS RECORD ( 34 . SELECT * INTO v_major(1) FROM major_stats WHERE major= 'Music'. VALUE Sin embargo las tablas anidadas deben crearse con índices secuenciales consecutivos consecutivos y no negativos. BINARY_INTEGER Si esta cláusula no existe se trata de una tabla anidada.NCLOB. El número máximo de filas de una tabla anidada es de 2 Gigabytes. Sintaxis: TYPE nombre_tabla TABLE OF tipo_tabla [NOT NULL]. / También se pueden utilizar tipos Objeto (se verá más adelante) Tablas Anidadas Como en el caso de tablas indexadas.total_credits := 10. --Asigna directamente valores a v_major(2) v_major(2). NCHAR. no así las tablas indexadas. Ejemplo: -. END. v_major(2).major := 'BBDD'. %TYPE pero no puede ser BOOLEAN. BEGIN --Recupera el registro con major='Music' y lo almacena en v_major(1).

es decir vacía v_tabla_num tabla_num:=tabla_num tabla_num(). v_nombre_tabla nombre_tabla:=nombre_tabla(valor o valores de :=nombre_tabla inicialización). tabla_num Ahora existen v_tabla_num(1). con valores –3. --Variables asociadas a ambos tipos v_tabla_registro tabla_registro. TYPE tabla_registro IS TABLE OF t_registro. -.2. NUMBER --Inicializamos la variable tabla con tres valores v_tabla_num tabla_num:=tabla_num tabla_num(-3.2.1). v_tabla_estudiante tabla_estudiante.Un tipo de tabla anidada basada en %ROWTYPE TYPE tabla_estudiante IS TABLE OF students%ROWTYPE. v_tabla_num(2) y v_tabla_num(3). Inicialización de Tablas anidadas Las tablas anidadas se inicializan de la misma manera que los varrays: utilizando constructores. 35 . Ejemplo: TYPE tabla_num IS TABLE TABLE OF NUMBER.1). DECLARE TYPE nombre_tabla TABLE OF tipo_tabla.PL/SQL 2 campo1 NUMBER. constructores El constructor tiene el mismo nombre que el tipo nombre_tabla al que se refiere y se inicializa en la sección declarativa. tabla_num Si no se inicializa se entiende que es una tabla anidada NULL v_tabla_num tabla_num. Al contrario que los varrays las tablas anidadas no tienen dimensión restringida. 2 y 1 respectivamente Se puede inicializar una tabla anidada con un único elemento que sea NULL: NULL v_tabla_num tabla_num:=tabla_num tabla_num(NULL). campo3 DATE). campo2 VARCHAR2(20). --Inicializamos la variable tabla con tres valores v_tabla_num tabla_num:=tabla_num(-3. tabla_num Se puede inicializar una tabla anidada sin valores. restringida sin embargo no se puede asignar un valor a un elemento que no exista y que supondría un aumento del tamaño de la tabla anidada: Ejemplo: Ejemplo: DECLARE TYPE tabla_num IS TABLE OF NUMBER.

Ahora se declara un tipo que es una tabla indexada de t_num. END LOOP. . tabla indexada y tabla anidada. -. / Obtenemos el error ORA-06533: Subíndice mayor que el recuento Al igual que en el caso de los varrays se puede ampliar el tamaño de una tabla anidada con el método EXTEND con la sintaxis: variable_tabla. / Ya no tendremos el error anterior.PL/SQL 2 BEGIN --Asignamos a los tres valores de la tabla anidada el valor 8 FOR v_contador IN 1.EXTEND.Esto es una colección multinivel.EXTEND FOR v_contador IN 1. --Inicializamos la variable tabla con tres valores v_tabla_num tabla_num:=tabla_num(-3.También podemos tener un varray de la tabla indexada 36 . Oracle 9i permite utilizar también colecciones de más de una dimensión o colecciones multinivel. Tablas Multinivel Las colecciones tratadas hasta ahora: varray. TYPE t_Multinum IS TABLE OF t_num INDEX BY BINARY_INTEGER. -. --Intentamos aumentar la tabla anidada en un elemento v_tabla_num(4):=8. multinivel es decir colecciones de colecciones..Primero declara una tabla de números indexada TYPE TYPE t_num IS TABLE OF NUMBER INDEX BY BINARY_INTEGER. La declaración es similar excepto porque el tipo de la colección es a su vez una colección Ejemplo: DECLARE -.. BEGIN v_tabla_num.EXTEND EXTEND Ejemplo DECLARE TYPE tabla_num IS TABLE OF NUMBER. END. -.EXTEND .4 LOOP v_tabla_num(v_contador):=8. END. y v_tabla_num tiene 4 elementos.2.3 LOOP v_tabla_num(v_contador):=8.1). anidada son unidimensionales. END LOOP.

PL/SQL 2 TYPE t_MultiVarray IS VARRAY(10) OF t_num. v_Multinum t_Multinum.O una tabla anidada TYPE t_Multianidada IS TABLE OF t_num.Y las variables correspondientes v_tnum t_num. para acceder a un elemento de la colección se utilizan dos pares de paréntesis Ejemplo: BEGIN v_Multinum(1)(1) := 12345. v_Multianidada t_Multianidada. / COMPARACIÓN ENTRE TIPOS DE COLECCIONES Oracle 9i Programación PL/SQL páginas 285-287 37 . END. Como un elemento de una colección multinivel es a su vez una colección . -. v_Multivarray t_Multivarray. -.