View
234
Download
0
Category
Preview:
Citation preview
Objektorientierte PL/SQL-Programmierung
für RDBMS
Andriy Terletskyy
Berenberg Bank
Neuer Jungfernstieg 20
20354 Hamburg
Willkommen
MDV/EDV- Erfahrung
Zeitraum Hardware Datenbank Pr. Sprache
• 1590 – ~ 1950 Rechenbrett Karteikarten
• ~ 1960 Buchungsautomaten Karteikarten
• ~ 1970 NCR Century 201 MIDAS Neat
• ~ 1980 NCR 8000/9800 TOTAL Cobol
• ~ 1990 NCR 3600 Supra PDM Cobol
• ~ 1995 NCR S-50 Oracle 8.0 Cobol
• ~ 2001 Sun 3800 Cluster Oracle 8.1 - 9.2 PL/SQL, Java
Modellierung
OBJECT TYPES
ODBMS
RDBMS
OO-ROWTYPES
BO-TYPES
Traditionelle ODBMS Virtuelle ODBMS auf
Basis RDBMS
OBJECT TYPES
Aufbau
• Definition Basis Typen
• Abbildung Real-Welt Objekten in BO-
Typen
• Aufbau OO-Tabellen
ODBMS
Aufbau traditionelle ODBMS
Verwendung
• übliche DML- Anweisungen
• Datennormalisierung über OID
• DEREF - zieht referenzierte Object
Größter Nachteil
• Änderungsunfähig, bzw. schwerfällig
( … IS DANGLING)
Aufbau virtuelle ODBMS für RDBMS
RDBMS
OO-ROWTYPES
BO-TYPES
Aufbau
• RDBMS (neue oder bestehende)
• Aufbau OO-ROWTYPE (ROWTYPE + DML,
DEFAULT, TO_STRING, DBMS_OUTPUT-
Methoden, PK/UK- Konstruktoren ) • Aufbau BO- Typen (Vererbung, Aggregation,
Assoziation)
Verwendung
• Methoden statt übliche DML- Anweisungen
• Datennormalisierung über RDBMS
• PK/UK- Konstruktoren - ziehen referenzierte
Object über relationale ID (DEREF- Analogon)
Größter Nachteil
• Aufwandbedürftig für OO-ROWTYPE Aufbau
(Lösung : automatische Generierung oder
Herstellerimplementierung)
Implementierung 1/8
1. Einführung TYPE_OBJECT – Basisklasse für alle abgeleiteten Object Types (optional)
CREATE OR REPLACE TYPE SCOTT.TYPE_OBJECT AS OBJECT(
-- attributes
object_type_name VARCHAR2(100)
-- member functions and procedures
, MEMBER FUNCTION TO_STRING RETURN VARCHAR2
, MEMBER PROCEDURE DBMS_OUTPUT
, MEMBER FUNCTION COMPARE(in_type1 TYPE_OBJECT, in_type2 TYPE_OBJECT) RETURN INTEGER
, ORDER MEMBER FUNCTION COMPARE2(in_other TYPE_OBJECT) RETURN INTEGER
) NOT FINAL NOT INSTANTIABLE
Vorteile: • Standardisiertes Interface für alle abgeleiteten Objekte (TO_STRING, DBMS_OUTPUT)
• Einfache Übergabe abgeleiteter Typen als Parameter (Ursprungshierarchie)
• ORDER Funktion - vergleicht Instanzen wegen überschriebener COMPARE- Methode
Implementierung 2/8
2.1. Einführung OO-ROWTYPE
CREATE OR REPLACE TYPE SCOTT.ROW_DEPT UNDER SCOTT.TYPE_OBJECT(
-- attributes
deptno NUMBER(2)
, dname VARCHAR2(14)
, loc VARCHAR2(13)
-- constructors
, CONSTRUCTOR FUNCTION ROW_DEPT RETURN SELF AS RESULT
, CONSTRUCTOR FUNCTION ROW_DEPT( in_deptno NUMBER, in_dname VARCHAR2
, in_loc VARCHAR2) RETURN SELF AS RESULT
, CONSTRUCTOR FUNCTION ROW_DEPT(in_deptno NUMBER) RETURN SELF AS RESULT
-- member functions
, MEMBER FUNCTION ROW_EXISTS(in_deptno NUMBER) RETURN BOOLEAN
, OVERRIDING MEMBER FUNCTION COMPARE( in_type1 GLOBAL.TYPE_OBJECT
, in_type2 GLOBAL.TYPE_OBJECT) RETURN INTEGER
-- member procedures
, MEMBER PROCEDURE ROW_INSERT
, MEMBER PROCEDURE ROW_UPDATE
, MEMBER PROCEDURE ROW_MERGE
, MEMBER PROCEDURE ROW_SAVE
, MEMBER PROCEDURE ROW_DELETE
, MEMBER PROCEDURE ROW_SELECT(in_deptno NUMBER)
, MEMBER PROCEDURE ROW_DEFAULT
) NOT FINAL
Implementierung 3/8
2.1. Einführung OO-ROWTYPE
CREATE OR REPLACE TYPE SCOTT.ROW_EMP UNDER SCOTT.TYPE_OBJECT(
-- attributes
empno NUMBER(4)
, ename VARCHAR2(10)
, job VARCHAR2(9)
, mgr NUMBER(4)
, hiredate DATE
, sal NUMBER(7,2)
, comm NUMBER(7,2)
, deptno NUMBER(2)
-- constructors
, CONSTRUCTOR FUNCTION ROW_EMP RETURN SELF AS RESULT
, CONSTRUCTOR FUNCTION ROW_EMP( in_empno NUMBER, in_ename VARCHAR2, in_job VARCHAR2, in_mgr NUMBER
, in_hiredate DATE, in_sal NUMBER, in_comm NUMBER, in_deptno NUMBER
) RETURN SELF AS RESULT
, CONSTRUCTOR FUNCTION ROW_EMP(in_empno NUMBER) RETURN SELF AS RESULT
-- member functions
, MEMBER FUNCTION ROW_EXISTS(in_empno NUMBER) RETURN BOOLEAN
, OVERRIDING MEMBER FUNCTION compare( in_type1 GLOBAL.TYPE_OBJECT, in_type2 GLOBAL.TYPE_OBJECT
) RETURN INTEGER
-- member procedures
, MEMBER PROCEDURE ROW_INSERT
, MEMBER PROCEDURE ROW_UPDATE
, MEMBER PROCEDURE ROW_MERGE
, MEMBER PROCEDURE ROW_SAVE
, MEMBER PROCEDURE ROW_DELETE
, MEMBER PROCEDURE ROW_SELECT(in_empno NUMBER)
, MEMBER PROCEDURE ROW_DEFAULT
) NOT FINAL
Implementierung 4/8
2.2. Einführung OO-ROWTYPE Container Types und Data-Cartridges
• Container Types
CREATE OR REPLACE TYPE TABLE_EMP AS TABLE OF SCOTT.ROW_EMP;
CREATE OR REPLACE TYPE TABLE_DEPT AS TABLE OF SCOTT.ROW_DEPT;
• Data-Cartridge für DEPT-Tabelle
CREATE OR REPLACE PACKAGE PA_DEPT IS
FUNCTION FU_SELECT RETURN TABLE_DEPT;
END;
• Data-Cartridge für EMP-Tabelle
CREATE OR REPLACE PACKAGE PA_EMP IS
FUNCTION FU_SELECT RETURN TABLE_EMP;
FUNCTION FS_DEPTNO(IN_DEPTNO IN EMP.DEPTNO%TYPE) RETURN TABLE_EMP;
FUNCTION FS_MGR(IN_MGR IN EMP.MGR%TYPE) RETURN TABLE_EMP;
END;
Implementierung 5/8
2.3. Automatische Generierung OO-ROWTYPEs, Container Types und Data-Cartridges
• Generator (generiert, kompiliert und bewährt Sourcen)
– Java-Klasse (liest TABLE Definition und generiert PL/SQL-Source)
– PL/SQL Wrapper – Prozedur (ruft Java-Klasse auf)
• DDL-Trigger (empfängt CREATE / ALTER TABLE Ereignis und schickt AQ-Message)
• Oracle-Job (empfängt AQ-Message und anstoßt Generator )
Implementierung 6/8
3.1. Einführung BO-Types (TYPE_ MANAGER)
CREATE OR REPLACE TYPE TYPE_MANAGER UNDER ROW_EMP(
-- attributes
EMPLOYEES TABLE_EMP
-- constructors
, CONSTRUCTOR FUNCTION TYPE_MANAGER RETURN SELF AS RESULT
, CONSTRUCTOR FUNCTION TYPE_MANAGER(IN_EMPNO NUMBER) RETURN SELF AS RESULT
) NOT FINAL
Implementierung 7/8
3.2. Einführung BO-Types (TYPE_DEPARTMENT)
CREATE OR REPLACE TYPE TYPE_DEPARTMENT UNDER ROW_DEPT(
-- attributes
EMPLOYEES TABLE_EMP
-- constructors
, CONSTRUCTOR FUNCTION TYPE_DEPARTMENT RETURN SELF AS RESULT
, CONSTRUCTOR FUNCTION TYPE_DEPARTMENT(in_deptno NUMBER) RETURN SELF AS
RESULT
-- member functions
, MEMBER FUNCTION GET_MANAGER RETURN TYPE_MANAGER
) NOT FINAL
Implementierung 8/8
3.3. Einführung BO-Types (TYPE_ENTERPRISE)
CREATE OR REPLACE TYPE TYPE_ENTERPRISE UNDER TYPE_OBJECT(
-- attributes
NAME VARCHAR2(100)
, PRESIDENT TYPE_MANAGER
, DEPARTMENTS TABLE_DEPT
, EMPLOYEES TABLE_EMP
-- constructors
, CONSTRUCTOR FUNCTION TYPE_ENTERPRISE RETURN SELF AS RESULT
) NOT FINAL
Programmierung 1/3
1. SQL
SQL> SELECT TYPE_DEPARTMENT(20) FROM DUAL;
TYPE_DEPARTMENT()(OBJECT_TYPE_NAME, DEPTNO, DNAME, LOC, NAME, TABLE_EMP(ROW_EMP())
--------------------------------------------------------------------------------
TYPE_DEPARTMENT('TYPE_DEPARTMENT', 20, 'RESEARCH', 'DALLAS',
TABLE_EMP(
ROW_EMP('ROW_EMP', 7369, 'SMITH', 'CLERK', 7902, '17.12.80', 800, NULL, 20),
ROW_EMP('ROW_EMP', 7566, 'JONES', 'MANAGER', 7839, '02.04.81', 2975, NULL, 20),
ROW_EMP('ROW_EMP', 7788, 'SCOTT', 'ANALYST', 7566, '19.04.87', 3000, NULL, 20),
ROW_EMP('ROW_EMP', 7876, 'ADAMS', 'CLERK', 7788, '23.05.87', 1100, NULL, 20),
ROW_EMP('ROW_EMP', 7902, 'FORD', 'ANALYST', 7566, '03.12.81', 3000, NULL, 20)
)
)
SQL> SELECT VALUE(e) FROM TABLE (TYPE_MANAGER(7698).EMPLOYEES) e;
VALUE(E)(OBJECT_TYPE_NAME, EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
--------------------------------------------------------------------------------
ROW_EMP('ROW_EMP', 7499, 'ALLEN', 'SALESMAN', 7698, '20.02.81', 1600, 300, 30)
ROW_EMP('ROW_EMP', 7521, 'WARD', 'SALESMAN', 7698, '22.02.81', 1250, 500, 30)
ROW_EMP('ROW_EMP', 7654, 'MARTIN', 'SALESMAN', 7698, '28.09.81', 1250, 1400, 30)
ROW_EMP('ROW_EMP', 7844, 'TURNER', 'SALESMAN', 7698, '08.09.81', 1500, 0, 30)
ROW_EMP('ROW_EMP', 7900, 'JAMES', 'CLERK', 7698, '03.12.81', 950, NULL, 30)
Programmierung 2/3
2.1. PL/SQL DECLARE
e TYPE_ENTERPRISE := TYPE_ENTERPRISE();
BEGIN
e.dbms_output;
END;
/
DBMS Output:
SCOTT.TYPE_ENTERPRISE
( OBJECT_TYPE_NAME = TYPE_ENTERPRISE
NAME = King Corporation
PRESIDENT = SCOTT.TYPE_MANAGER
( OBJECT_TYPE_NAME = TYPE_MANAGER
EMPNO = 7839
ENAME = KING
JOB = PRESIDENT
MGR =
HIREDATE = 17.11.1981 00:00:00
SAL = 5000
COMM =
DEPTNO = 10
EMPLOYEES = < SCOTT.TABLE_EMP >
)
DEPARTMENTS = < SCOTT.TABLE_DEPT >
EMPLOYEES = < SCOTT.TABLE_EMP >
)
Programmierung 3/6
2.2. PL/SQL
DECLARE
m TYPE_MANAGER;
BEGIN
m := TYPE_MANAGER(7839);
m.sal := m.sal * 2;
m.row_update;
m.dbms_output;
END;
/
DBMS Output:
SCOTT.TYPE_MANAGER
(
OBJECT_TYPE_NAME = TYPE_MANAGER
EMPNO = 7839
ENAME = KING
JOB = PRESIDENT
MGR =
HIREDATE = 17.11.1981 00:00:00
SAL = 10000
COMM =
DEPTNO = 10
EMPLOYEES = < SCOTT.TABLE_EMP >
)
Zusammenfassung (virtuelle ODBMS)
• keine Funktionalitätsverluste gegenüber der bestehenden ODBMS Lösung
• Das Objektmodel entspricht dem relationalen Datenmodel und kann ohne Änderung am relationalen Datenmodel erzeugt und verwendet werden
• Vereinfachung der DML-Anweisungen
• Zugriffe der Business Objekte (BO) sind unabhängig von der unterliegenden Datenquelle
• DB-Mapping für Java (JPublisher oder selbst geschriebene Generatoren)
Java DB-Mapping 1/2
1. Type-Mapping
PL/SQL-TYPE
Attribute 1
….
Attribute N
Constructor(p1,...)
Function F1(p1,..)
Procedure P2(p1,…)
Java-Class
Attribute 1
….
Attribute N
Constructor(con,p1,...)
Methode F1(con,p1,..)
Methode P2(con,p1,…)
JDBC, SQLData
Java DB-Mapping 2/2
2. Package-Mapping
PL/SQL-Package
Cursor 1 of Record 1
….
Cursor N of Record N
Function F1(p1,..)
Procedure P2(p1,…)
Java-Class
Constructor(con)
Methode F1(con,p1,..)
Methode P2(con,p1,…)
JDBC
Class Record 1
Attribute 1
….
Attribute N
Class Record N
Attribute 1
….
Attribute N
OUT_F1
Parameter 1
Parameter N
OUT_P2
Parameter 1
Parameter N
Gewünschte Nachbesserung von
Architekturnachteilen
• Object-Typen unterstützen nicht ROWID, %TYPE und INDEX BY TABLE
• ein Type kann nicht Container von eigenen Instanzen referenzieren
• ein SUPER –Attribut fehlt
• die entsprechendes Gegenstück der z.B. in Java existierenden Interfaces
fehlt (deswegen beinhaltet TYPE_OBJECT das überflüssige Attribute
OBJECT_TYPE_NAME)
• ein Type, der von einem anderen Type vererbt ist, oder von einem
Container referenziert wird, kann mittels REPLACE nicht mehr ersetzt
werden (DROP TYPE FORCE und anschließende Grants)
Q&A • Objektorientierte PL/SQL-Programmierung, Andriy Terletskyy,
Michael Meyer, DOAG News Q3/2004, s.31-35
• Objektorientierte PL/SQL-Programmierung, Andriy Terletskyy, 17.
Deutsche ORACLE- Anwenderkonferenz 10./11. November 2004, CCM
Congress Center Mannheim; s.207-215
• Alternative zu J2EE Enterprise- Applicationen mit wenig Ballast,
Manfred Emmelmnn, Stephan Koop, Jürgen Hoffmann, Tim Lechler,
Carsten Paschilke, Andriy Terletskyy, Javamagazin 01/2005, s.49-59
Recommended