Objektorientierte PL/SQL-Programmierung für RDBMS · Objektorientierte PL/SQL-Programmierung für...

22
Objektorientierte PL/SQL-Programmierung für RDBMS Andriy Terletskyy Berenberg Bank Neuer Jungfernstieg 20 20354 Hamburg Willkommen

Transcript of Objektorientierte PL/SQL-Programmierung für RDBMS · Objektorientierte PL/SQL-Programmierung für...

Objektorientierte PL/SQL-Programmierung

für RDBMS

Andriy Terletskyy

Berenberg Bank

Neuer Jungfernstieg 20

20354 Hamburg

Willkommen

Berenberg stellt sich vor

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