Alias
En una base de datos con tipos y objetos, lo más recomendable es utilizar siempre alias para los nombres de las tablas. El alias de una tabla debe ser único en el contexto de la consulta. Los alias sirven para acceder al contenido de la tabla, pero hay que saber utilizarlos adecuadamente en las tablas que almacenan objetos.
El siguiente ejemplo ilustra cómo se deben utilizar.
CREATE TYPE persona AS OBJECT (nombre VARCHAR(20));
CREATE TABLE ptab1 OF persona;
CREATE TABLE ptab2 (c1 persona);
CREATE TABLE ptab3 (c1 REF persona);
La diferencia entre las dos primeras tablas está en que la primera almacena objetos del tipo persona, mientras que la segunda tabla tiene una columna donde se almacenan valores del tipo persona. Considerando ahora las siguientes consultas, se ve cómo se puede acceder a estas tablas.
1. SELECT nombre FROM ptab1; Correcto
2. SELECT c1.nombre FROM ptab2; Incorrecto
3. SELECT p.c1.nombre FROM ptab2 p; Correcto
4. SELECT p.c1.nombre FROM ptab3 p; Correcto
5. SELECT p.nombre FROM ptab3 p; Incorrecto
En la primera consulta nombre es considerado como una de las columnas de la tabla ptab1, ya que los atributos de los objetos se consideran columnas de la tabla de objetos. Sin embargo, en la segunda consulta se requiere la utilización de un alias para indicar que nombre es el nombre de un atributo del objeto de tipo persona que se almacena en la columna c1. Para resolver este problema no es posible utilizar los nombres de las tablas directamente: ptab2.c1.nombre es incorrecto. Las consultas 4 y 5 muestran cómo acceder a los atributos de los objetos referenciados desde un atributo de la tabla ptab3.
En conclusión, para facilitar la formulación de consultas y evitar errores se recomienda utilizar alias para acceder a todas las tablas que contengan objetos con o sin identidad, y para acceder a las columnas de las tablas en general.
Inserción de referencias
La inserción de objetos con referencias implica la utilización del operador REF para poder insertar la referencia en el atributo adecuado. La siguiente sentencia inserta una orden de pedido en la tabla definida en la sección 1.1.3.
INSERT INTO ordenes_tab
SELECT 3001, REF(C),'30-MAY-1999', NULL
--se seleccionan los valores de los 4 atributos de la tabla
FROM cliente_tab C WHERE C.clinum= 3;
CREATE TYPE persona_t AS OBJECT (
nombre VARCHAR2(30),
jefe REF persona_t ) ;
Si x es una variable que representa a un objeto de tipo persona_t, entonces las dos expresiones siguientes son equivalentes:
1. x.jefe.nombre
2. y.nombre, y=DEREF(x.jefe)
Para obtener una referencia a un objeto de una tabla de objetos, se puede aplicar el operador REF como muestra el siguiente ejemplo:
CREATE TABLE persona_tab OF persona_t;
DECLARE ref_persona REF persona_t;
SELECT REF(pe) INTO ref_persona
FROM persona_tab pe WHERE pe.nombre= ‘Juan Pérez Ruíz’;
Simétricamente, para recuperar un objeto desde una referencia es necesario usar DEREF, como muestra el siguiente ejemplo que visualiza los datos del jefe de la persona indicada:
SELECT DEREF(pe.jefe)
FROM persona_tab pe WHERE pe.nombre= ‘Juan Pérez Ruíz’;
Llamadas a métodos
Para invocar un método hay que utilizar su nombre y unos paréntesis que encierren sus argumentos de entrada. Si el método no tiene argumentos, se especifican los paréntesis aunque estén vacíos. Por ejemplo, si tb es una tabla con la columna c de tipo de objeto t, y t tiene un método m sin argumentos de entrada, la siguiente consulta es correcta:
SELECT p.c.m FROM tb p;
Inserción en tablas anidadas
Además del constructor del tipo de colección disponible por defecto, la inserción de elementos dentro de una tabla anidada puede hacerse siguiendo estas dos etapas:
1. Crear el objeto con la tabla anidada y dejar vacío el campo que contiene las tuplas anidadas.
2. Comenzar a insertar tuplas en la columna correspondiente de la tupla seleccionada por una subconsulta.
Para ello, se tiene que utilizar la palabra clave THE con la siguiente sintaxis:
INSERT INTO THE (subconsulta) (tuplas a insertar)
Esta técnica es especialmente útil si dentro de una tabla anidada se guardan referencias a otros objetos. El siguiente ejemplo ilustra la manera de realizar estas operaciones sobre la tabla de ordenes (ordenes_tab) definida anteriormente.
INSERT INTO ordenes_tab --inserta una orden
SELECT 3001, REF(C), SYSDATE,'30-MAY-1999', lineas_pedido_t(), NULL
FROM cliente_tab C
WHERE C.clinum= 3 ;
INSERT INTO THE ( --selecciona el atributo pedido de la orden
SELECT P.pedido
FROM ordenes_tab P
WHERE P.ordnum = 3001
)
VALUES (linea_t(30, NULL, 18, 30));
--inserta una linea de pedido anidada
Para poner condiciones a las tuplas de una tabla anidada, se pueden utilizar cursores dentro de un SELECT o desde un programa PL/SQL. Veamos aquí un ejemplo de acceso con cursores. Utilizando un ejemploanterior, vamos a recuperar el número de las ordenes, sus fechas de pedido y las líneas de pedido que se refieran al item ‘CH4P3’.
SELECT ord.ordnum, ord.fechpedido,
CURSOR (SELECT * FROM TABLE(ord.pedido) lp WHERE lp.item= ‘CH4P3’)
FROM ordenes_tab ord;
La cláusula THE también sirve para seleccionar las tuplas de una tabla anidada. La sintaxis es como sigue:
SELECT ... FROM THE (subconsulta) WHERE ...
Por ejemplo, para seleccionar las primeras dos líneas de pedido de la orden 8778 se hace:
SELECT lp FROM THE
(SELECT ord.pedido FROM ordenes_tab ord WHERE ord.ordnum= 8778) lp
WHERE lp.linum<3;