M2 - Bases de dades / Apunts UF4 : BDOR2

De wikiserver
Dreceres ràpides: navegació, cerca
  • El lenguaje PL/SQL admite la herencia simple de tipos de objetos, mediante la cual, puedes definir subtipos de los tipos de objeto. Estos subtipos, o tipos heredados, contienen todos los atributos y métodos del tipo padre, pero además pueden contener atributos y métodos adicionales, o incluso sobreescribir métodos del tipo padre.
  • Se usan las reglas conocidas sobre la herencia de los atributos y métodos:
- Super-tipo tipo tiene que incluir la cláusula NOT FINAL (por defecto es FINAL).
CREATE TYPE person_typ AS OBJECT (
   idno NUMBER,
   name VARCHAR2(20),
   phone VARCHAR2(20),
   FINAL MAP MEMBER FUNCTION get_idno RETURN NUMBER,
   MEMBER FUNCTION show RETURN VARCHAR2) -- despliega idno y nombre --
   NOT FINAL;

CREATE TYPE BODY person_typ AS 
   FINAL MAP MEMBER FUNCTION get_idno RETURN NUMBER IS
   BEGIN
     RETURN self.idno;
   END;
   MEMBER FUNCTION show RETURN VARCHAR2 IS
    BEGIN
     RETURN ('--Idno: '  || self.Idno || ' -- Nombre: ' || self.name);
   END;
END;
- Los métodos pueden ser también FINAL o NOT FINAL (por defecto) independientemente de la correspondiente declaración para la estructura del tipo.
  • Los tipos y métodos pueden ser definidos como NOT INSTANTIABLE:
- El tipo no instantiable no permite crear instancias y puede ser usado para representar las sub-tipos instatiables con la participación total.
- Los métodos se definen como no instantiable cuando se espera que cada sub-tipo sobrescriba el método.
  • La herencia y overriding métodos se crean similar a SQL3 usando la cláusula UNDER y OVERRIDING, respectivamente.
CREATE TYPE student_typ UNDER person_typ (
   dept_id NUMBER,
   major VARCHAR2(30),
   OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2)
   NOT FINAL;

CREATE TYPE BODY student_typ AS
   OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2 IS
   BEGIN
     RETURN ((self AS person_typ).show || ' -- Major: ' || major);
   END;
END;
- La invocación del método del super-tipo se hace por medio de la sentencia (SELF AS [super-tipo]).[método del super-tipo].


  • Se crea la tabla que contiene las instancias de super y sub-tipos insertando valores por medio de la invocación de los constructores correspondientes:
CREATE TABLE person_obj_table OF person_typ;

INSERT INTO person_obj_table
VALUES (person_typ(12, 'Bob Jones', '111-555-1212'));

INSERT INTO person_obj_table
VALUES (student_typ(51, 'Joe Lane', '1-800-555-1312', 12, 'HISTORY'));
  • Se puede llamar al método show:
SELECT p.show() FROM person_obj_table p;
Resultado:
     
   12 Bob Jones        -----> Método show de super-tipo
   51 Joe Lane HISTORY -----> Método show de sub-tipo
  • Oracle maneja el concepto de substitutability que permite seleccionar los objetos de sub-tipos como parte del super-tipo.
  • La consulta sobre la tabla sin especificar el tipo de interés devuelve todos los objetos del super y sub-tipos:
SELECT VALUE(p) FROM person_obj_table p;
  • Se puede delimitar los objetos seleccionados usando el operador IS OF que examina si las instancias del objeto pertenecen a un nivel de especialización particular:
SELECT VALUE(p)
FROM person_obj_table p                 --Devuelve todos los objetos de tipo person_typ 
WHERE VALUE(p) IS OF (person_typ);      --y de los sub-tipos derivados de este tipo

SELECT VALUE(p)
FROM person_obj_table p                 --Devuelve todos los objetos de sub-tipo student_typ 
WHERE VALUE(p) IS OF (student_typ);     --y de los sub-tipos derivados de este sub-tipo
  • Para delimitar el despliegue a solo los objetos de un tipo específico se puede usar la cláusula ONLY:
SELECT VALUE(p) FROM person_obj_table p
WHERE VALUE(p) IS OF (ONLY person_typ);

SELECT VALUE(p) FROM person_obj_table p
WHERE VALUE(p) IS OF (ONLY student_typ);
  • Para poder acceder los atributos y métodos de sub-tipos se puede usar la función TREAT:
SELECT TREAT(VALUE(p) AS student_typ).major
FROM person_obj_table p;

SELECT  TREAT(VALUE(p)  AS person_typ).show() FROM person_obj_table p;

SELECT  TREAT(VALUE(p)  AS person_typ).show() FROM person_obj_table p
WHERE VALUE(p) IS OF (ONLY person_typ);

SELECT TREAT(VALUE(p) AS student_typ).show()
FROM person_obj_table p;

SELECT TREAT(VALUE(p) AS student_typ).show()
FROM person_obj_table p
WHERE VALUE(p) IS OF (ONLY student_typ);
- Resultado: devuelve todas las personas de la tabla. Las de tipo estudiante tendrán un valor de major guardado en la tabla. Las que no perteneces a este tipo tendrán valor NULL
  • Oracle permite modificar las estructuras jerárquicas, sin embargo, se requiere conocer los detalles de implementación para su manejo adecuado.
  • En el siguiente ejemplo puedes ver cómo se crea el tipo de objeto Persona, que se utilizará heredado en el tipo de objeto UsuarioPersona. De esta manera, este último tendrá los atributos de Persona más los atributos declarados en UsuarioPersona. En la creación del objeto puedes observar que se deben asignar los valores para todos los atributos, incluyendo los heredados.
CREATE TYPE Persona AS OBJECT (
   nombre VARCHAR2(20),
   apellidos VARCHAR2(30)
) NOT FINAL;
/
CREATE TYPE UsuarioPersona UNDER Persona (
   login VARCHAR(30),
   f_ingreso DATE,
   credito NUMBER
);
/
DECLARE
   u1 UsuarioPersona;
BEGIN
   u1 := NEW UsuarioPersona('nombre1', 'apellidos1', 'user1', '01/01/2001', 100);
   dbms_output.put_line(u1.nombre);
END;
/