Andriy Terletskyy Lead Database Architect Hamburg,

Slides:



Advertisements
Ähnliche Präsentationen
Object Relational Mapping
Advertisements

Vorlesung Datenbank-programmierung
PL/SQL - Einführung. © Prof. T. Kudraß, HTWK Leipzig Vorteile Application Other DBMSs Application Oracle with PL/SQL SQL SQL SQL SQL SQLIF...THENSQLELSESQL.
PL/SQL - Programmierung von Programmeinheiten. © Prof. T. Kudraß, HTWK Leipzig Gespeicherte Prozeduren – Eine Prozedur ist ein benannter PL/SQL Block,
Folien 2-5, 7-8 © Prof. Dr. Manfred Rössle (FH Aalen)
PL/SQL - Kurze Einführung -.
JPQL Java Persistence Query Language
System J – Compiler – Praktikum: Datenbanksystementwicklung Knut Stolze
MySQL.
Systemüberblick Beispiele: Microsoft Access Oracle Ingres Informix
Praktikum Entwicklung und Einsatz von Geosoftware I - Sitzung 3 Klassen, Objekte, Arrays und Kontrollstrukturen Sommersemester 2003 Lars Bernard.
Datensicherheit in DBMS
IS: Datenbanken, © Till Hänisch 2000 CREATE TABLE Syntax: CREATE TABLE name ( coldef [, coldef] [, tableconstraints] ) coldef := name type [länge], [[NOT]NULL],
PL/SQL – Die prozedurale Erweiterungssprache Zu SQL
Spezielle Aspekte der Anbindung von Datenbanken im Web.
Publikation von XML-Daten mit XSQL Pages. © Prof. T. Kudraß, HTWK Leipzig Vorteile von XSQL Pages einfache Generierung von XML-Dokumenten auf der Basis.
PL/SQL - Programmierung von Programmeinheiten. © Prof. T. Kudraß, HTWK Leipzig Gespeicherte Prozeduren – Eine Prozedur ist ein benannter PL/SQL Block,
Prof. Dr. T. Kudraß1 Integrität in Datenbanken. Prof. Dr. T. Kudraß2 Unterschied Konsistenz - Integrität Konsistenz beschreibt die Korrektheit der DB-internen.
PL/SQL - Programmierung von Programmeinheiten. © Prof. T. Kudraß, HTWK Leipzig Gespeicherte Prozeduren – Eine Prozedur ist ein benannter PL/SQL Block,
Übung Datenbanksysteme WS 2003/ Übung Datenbanksysteme Hierarchische DBMS
Transaction Script Software Component Technology for Distributed Applications.
Datenintegrität Referentielle Integrität create table
Oracle interMedia Audio Vortrag für das Seminar Oracle Zusatzoptionen Chris Haußmann.
Oracle interMedia Image
JDBC -Java Database Connectivity-. 15./22. April 2004JDBC2 JDBC.... verbindet Java-Programme mit SQL-basierten Datenbanken.. liefert eine generische SQL-API.
Modulare Programmierung
1 Datenintegrität Statische Bedingung (jeder Zustand) Dynamische Bedingung (bei Zustandsänderung) Bisher: Definition eines Schlüssels 1:N - Beziehung Angabe.
1 Kapitel 8: Datenintegrität. 2 Datenintegrität Statische Bedingung (jeder Zustand) Dynamische Bedingung (bei Zustandsänderung) Bisher: Definition eines.
Datenbanken 10: Einfügen, Ändern, Löschen
objekt-relationale Datenbanken
Datenbankentwicklung IV-LK
SQL PHP und MySQL Referat von Katharina Stracke und Carina Berning
Information Systems & Semantic Web University of Koblenz Landau, Germany Vorlesung Multimedia-Datenbanken Objekt-relationale Datenbanksysteme (Folien nach.
PHP und MYSQL am Organisatorisches Der komplette Kurs im Schnelldurchgang Bewertung von wichtig und unwichtig Historisch Kulturwissenschaftliche.
WS 2012/13 Datenbanksysteme Fr 15:15 – 16:45 R Vorlesung #8 SQL (Teil 5)
WS 2013/14 Datenbanksysteme Do 17:00 – 18:30 R Vorlesung #7 SQL (Teil 4)
SS 2004 Datenbanken 4W Mi 13:30 – 15:00 G 2.30 Vorlesung #9 SQL (Teil 4)
WS 2009/10 Datenbanksysteme Fr 15:15 – 16:45 R Vorlesung #7 SQL (Teil 4)
WS 2007/08 Datenbanksysteme Mi 17:00 – 18:30 R Vorlesung #8 Wiederholung: Referentielle Integrität/ Embedded SQL.
Einführung in Datenbankmodellierung und SQL
PL/SQL - Kurze Einführung April 2003Übung Data Warehousing: PL/SQL 2 PL/SQL.. ist eine Oracle-eigene, prozedurale Programmiersprache Sämtliche.
Datenbankanbindung mit
procedural language / structured query language
Structured Query Language
Oberseminar Moderne Datenbanken WS03/04
WS 2013/14 Datenbanksysteme Do 17:00 – 18:30 R Vorlesung #8 SQL (Teil 5)
SQL-Prozeduren Charakteristika: Kapselung von SQL-Anweisungen in Prozeduren, die wiederholt aufgerufen werden können. Dazu Verbergen parametrisierter SQL-
Trigger-abhängige Client Interaktionen (bezüglich Oracle8i)
Datenbank für Skriptenverkauf
WS 2014/15 Datenbanksysteme Do 17:00 – 18:30 R Vorlesung #9 SQL Zusammenfassung.
Datenbanken erstellen mit PostgreSQL
Datenbanken abfragen mit SQL
1 Objektorientierte Datenbanken zBeim vorigen Mal: zODMG-OQL und FastObjects-OQL zIntegritätsbedingungen und Schema-Evolution zHeute: Objektrelationale.
© 2003, Rudolf Jansen Einsatz der XML-Features der Oracle 9i DB zur Systemintegration Rudolf Jansen Freiberuflicher Entwickler und Autor
Oracle IFS Die Brücke zwischen Content Management System und einer Produktpräsentation im Internet.
© Thales IS GmbH 2002 Oracle's Data Warehousing Features 1 Thales Information Systems GmbH Im Team für Ihren Erfolg DOAG - Regionaltreffen Hannover Donnerstag,
Thomas Tretter, 10. Februar 2004Oracle Label Security1 Oracle Label Security (fine grained access control) 10. Februar 2004.
SQL Structured Query Language Enzio Thiem. INHALT CREATE TABLE Anweisung Gängige Datentypen Beispiel CREATE TABLE Beispiel CREATE TABLE - erweitert Beispiel.
Sprachumfang von SQL Vier Kategorien DDL (Data Definition Language)
Vorlesung #4 Relationales Kalkül und SQL (Teil 1)
„Was du ererbt von Deinen Vätern hast, erwirb es, um es zu besitzen.“
Frank Schneede Senior Berater ORACLE Deutschland GmbH.
Abfragesprache SQL in ORACLE
Sichten.
Beispiele zur Datenänderung
Vorlesung #8 SQL (Teil 5).
Create Table, Rechte und Rollen
Geschäftslogik in der Datenbank Best Practice
Die erste Form der INSERT-Anweisung dient der Neueingabe von Daten:
GRUNDLAGEN WISSENSCHAFTLICHEN ARBEITENS MODULA-2 SONAY SUBAYAZ
 Präsentation transkript:

Andriy Terletskyy Lead Database Architect Hamburg, 17.06.2010 Geschäftslogik in der Datenbank Architektur und Objektorientierte PL/SQL-Programmierung Andriy Terletskyy Lead Database Architect Hamburg, 17.06.2010

Geschäftslogik Geschäftslogik (engl. Business Logic, auch Anwendungslogik) ist ein abstrakter Begriff in der Softwaretechnik, der eine Abgrenzung der durch die Aufgabenstellung selbst motivierten Logik eines Softwaresystems von der technischen Implementierung zum Ziel hat. Allerdings ist der Begriff unscharf, da eine klare Trennung oft nicht möglich ist. Mehrfache BL-Umsetzung Datenbank Abhängigkeit Datenverarbeitungs- und Datenerfassungslogik Oracle EE ist mehr als eine Datenbank (Speicherort) SQL und PL/SQL Engine DBMS-Packages Object Types Type Mapping (Java&.NET) JPublisher, SQLData, STRUCT, ODP.NET

Datenbanken Architektur

Virtuelle ODBMS auf Basis RDBMS (DOAG Konferenz 2004) Aufbau OO-ROWTYPE (ROWTYPE + DML, DEFAULT, TO_STRING, DBMS_OUTPUT- Methoden, PK/UK- Konstruktoren, ROW_LOCK) BO-Typen (Vererbung, Aggregation, Assoziation) Verwendung Methoden statt üblicher DML- Anweisungen Datennormalisierung über RDBMS PK/UK- Konstruktoren - ziehen referenziertes Objekt über relationale ID (DEREF- Analogon) Generator Java-Class PL/SQL-Wrapper DDL-Trigger mit asynchroner Queue

Tabelle und OO-Rowtype (Beispiel) CREATE OR REPLACE TYPE ROW_STATUS UNDER GLOBAL.TYPE_OBJECT (  -- attributes     STATUS_ID          NUMBER(12)   , KURZBEZEICHNUNG    VARCHAR2(50)   , ERSTELLT_ZST       DATE   , ERSTELLT_ID        VARCHAR2(30)   , GEAENDERT_ZST      DATE   , GEAENDERT_ID       NUMBER(12)   , GEAENDERT_ZAEHLER  NUMBER(10)   , BEZEICHNUNG        VARCHAR2(200)   -- constructors   , CONSTRUCTOR FUNCTION ROW_STATUS RETURN SELF AS RESULT   , CONSTRUCTOR FUNCTION ROW_STATUS(IN_STATUS_ID NUMBER) RETURN SELF AS RESULT   -- member functions   , MEMBER FUNCTION ROW_EXISTS(IN_STATUS_ID 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_STATUS_ID NUMBER)   , MEMBER PROCEDURE ROW_DEFAULT   , MEMBER PROCEDURE ROW_LOCK   , MEMBER PROCEDURE ROW_LOCK(IN_STATUS_ID NUMBER) ) NOT FINAL CREATE OR REPLACE TRIGGER TBI$STATUS BEFORE INSERT ON WPH.STATUS FOR EACH ROW WHEN ( NEW.STATUS_ID IS NULL) DECLARE BEGIN SELECT STATUS_SEQ.NEXTVAL INTO :NEW.STATUS_ID FROM DUAL; END; -------------------------------------------------------------------------------------------- CREATE OR REPLACE TRIGGER TBU$STATUS BEFORE UPDATE ON WPH.STATUS FOR EACH ROW :new.Geaendert_ID := SYS_CONTEXT('VPD', 'USERID'); :new.Geaendert_ZST := sysdate; :new.Geaendert_Zaehler := :old.Geaendert_Zaehler + 1; end;

RETURNING clause (INSERT und UPDATE)   MEMBER PROCEDURE ROW_INSERT   IS     methodenname  CONSTANT VARCHAR2(100) := 'WPH.ROW_STATUS.ROW_INSERT';   BEGIN     IF SYS_CONTEXT('TRACE','TRACE_LEVEL') >= GLOBAL.PA_TRACE.TRACE_TRACE THEN       GLOBAL.PA_TRACE.TRACE( GLOBAL.PA_TRACE.TRACE_TRACE, methodenname, 'Parameters: ');     END IF;     INSERT INTO WPH.STATUS ( STATUS_ID                             ,KURZBEZEICHNUNG                             ,BEZEICHNUNG                   ) VALUES ( SELF.STATUS_ID                             ,SELF.KURZBEZEICHNUNG                             ,SELF.BEZEICHNUNG                  ) RETURNING                              STATUS_ID                             ,KURZBEZEICHNUNG                             ,ERSTELLT_ZST                             ,ERSTELLT_ID                             ,GEAENDERT_ZST                             ,GEAENDERT_ID                             ,GEAENDERT_ZAEHLER                             ,BEZEICHNUNG                   INTO                              SELF.STATUS_ID                             ,SELF.KURZBEZEICHNUNG                             ,SELF.ERSTELLT_ZST                             ,SELF.ERSTELLT_ID                             ,SELF.GEAENDERT_ZST                             ,SELF.GEAENDERT_ID                             ,SELF.GEAENDERT_ZAEHLER                             ,SELF.BEZEICHNUNG                            ;   EXCEPTION     WHEN OTHERS THEN       GLOBAL.PA_TRACE.TRACE( GLOBAL.PA_TRACE.TRACE_ERROR, methodenname, ' - Exception raised. '                             ||SELF.TO_STRING()                             ||', SQLcode=' || to_char(SQLCODE) || ', ' || SQLERRM);     RAISE;   END;

SAVE und MERGE   MEMBER PROCEDURE ROW_SAVE   IS     methodenname  CONSTANT VARCHAR2(100) := 'WPH.ROW_STATUS.ROW_SAVE';   BEGIN     IF SYS_CONTEXT('TRACE','TRACE_LEVEL') >= GLOBAL.PA_TRACE.TRACE_TRACE THEN       GLOBAL.PA_TRACE.TRACE( GLOBAL.PA_TRACE.TRACE_TRACE, methodenname, 'Parameters: ');     END IF;     IF ROW_EXISTS(IN_STATUS_ID => SELF.STATUS_ID) THEN       SELF.ROW_UPDATE;     ELSE       SELF.ROW_INSERT;     END IF;   EXCEPTION     WHEN OTHERS THEN       GLOBAL.PA_TRACE.TRACE( GLOBAL.PA_TRACE.TRACE_ERROR, methodenname, ' - Exception raised. '                             ||SELF.TO_STRING()                             ||', SQLcode=' || to_char(SQLCODE) || ', ' || SQLERRM);     RAISE;   END;   ---------------------------------------------------------------   MEMBER PROCEDURE ROW_MERGE   IS     methodenname  CONSTANT VARCHAR2(100) := 'WPH.ROW_STATUS.ROW_MERGE';   BEGIN     MERGE INTO WPH.STATUS A     USING ( SELECT SELF.STATUS_ID     AS STATUS_ID                   ,SELF.KURZBEZEICHNUNG   AS KURZBEZEICHNUNG                   ,SELF.BEZEICHNUNG       AS BEZEICHNUNG             FROM DUAL ) B     ON (A.STATUS_ID         = B.STATUS_ID)     WHEN MATCHED THEN UPDATE SET   KURZBEZEICHNUNG   = B.KURZBEZEICHNUNG                                    ,BEZEICHNUNG       = B.BEZEICHNUNG     WHEN NOT MATCHED THEN INSERT ( STATUS_ID                                   ,KURZBEZEICHNUNG                                   ,BEZEICHNUNG                         ) VALUES ( B.STATUS_ID                                   ,B.KURZBEZEICHNUNG                                   ,B.BEZEICHNUNG                                 );   EXCEPTION     WHEN OTHERS THEN       GLOBAL.PA_TRACE.TRACE( GLOBAL.PA_TRACE.TRACE_ERROR, methodenname, ' - Exception raised. '                             ||SELF.TO_STRING()                             ||', SQLcode=' || to_char(SQLCODE) || ', ' || SQLERRM);     RAISE;   END;

Pessimistisches Locking - Default   MEMBER PROCEDURE ROW_LOCK   IS     methodenname  CONSTANT VARCHAR2(100) := 'WPH.ROW_STATUS.ROW_LOCK';     v_lock                 NUMBER;   BEGIN     IF SYS_CONTEXT('TRACE','TRACE_LEVEL') >= GLOBAL.PA_TRACE.TRACE_TRACE THEN       GLOBAL.PA_TRACE.TRACE( GLOBAL.PA_TRACE.TRACE_TRACE, methodenname, 'Parameters: ');     END IF;     SELECT GEAENDERT_ZAEHLER       INTO v_lock     FROM WPH.STATUS     WHERE STATUS_ID         = SELF.STATUS_ID     FOR UPDATE     ;     IF SELF.GEAENDERT_ZAEHLER <> v_lock THEN       SELF.ROW_SELECT(    IN_STATUS_ID         => SELF.STATUS_ID);     END IF;   EXCEPTION     WHEN OTHERS THEN       GLOBAL.PA_TRACE.TRACE( GLOBAL.PA_TRACE.TRACE_ERROR, methodenname, ' - Exception raised. '                             ||SELF.TO_STRING()                             ||', SQLcode=' || to_char(SQLCODE) || ', ' || SQLERRM);     RAISE;   END; declare i ROW_STATUS; begin i := ROW_STATUS(IN_STATUS_ID => 200); ... i.ROW_LOCK(); end;

Pessimistisches Locking mit PK oder UK   MEMBER PROCEDURE ROW_LOCK(IN_STATUS_ID NUMBER)   IS     methodenname  CONSTANT VARCHAR2(300) := 'WPH.ROW_STATUS.ROW_LOCK(IN_STATUS_ID NUMBER)';   BEGIN     IF SYS_CONTEXT('TRACE','TRACE_LEVEL') >= GLOBAL.PA_TRACE.TRACE_TRACE THEN       GLOBAL.PA_TRACE.TRACE( GLOBAL.PA_TRACE.TRACE_TRACE, methodenname, 'Parameters: '                             ||'IN_STATUS_ID = '||IN_STATUS_ID||';'                           );     END IF;     SELECT STATUS_ID           ,KURZBEZEICHNUNG           ,ERSTELLT_ZST           ,ERSTELLT_ID           ,GEAENDERT_ZST           ,GEAENDERT_ID           ,GEAENDERT_ZAEHLER           ,BEZEICHNUNG       INTO SELF.STATUS_ID           ,SELF.KURZBEZEICHNUNG           ,SELF.ERSTELLT_ZST           ,SELF.ERSTELLT_ID           ,SELF.GEAENDERT_ZST           ,SELF.GEAENDERT_ID           ,SELF.GEAENDERT_ZAEHLER           ,SELF.BEZEICHNUNG     FROM WPH.STATUS     WHERE STATUS_ID = IN_STATUS_ID     FOR UPDATE     ;   EXCEPTION     WHEN OTHERS THEN       GLOBAL.PA_TRACE.TRACE( GLOBAL.PA_TRACE.TRACE_ERROR, methodenname, ' - Exception raised. '                             ||'IN_STATUS_ID = '||IN_STATUS_ID||';'                             ||', SQLcode=' || to_char(SQLCODE) || ', ' || SQLERRM);     RAISE;   END; declare i ROW_STATUS; begin i := ROW_STATUS(); i.ROW_LOCK(IN_STATUS_ID => 200); end;

Optimistisches Locking - UPDATE   MEMBER PROCEDURE ROW_UPDATE   IS     methodenname  CONSTANT VARCHAR2(100) := 'WPH.ROW_STATUS.ROW_UPDATE';   BEGIN     IF SYS_CONTEXT('TRACE','TRACE_LEVEL') >= GLOBAL.PA_TRACE.TRACE_TRACE THEN       GLOBAL.PA_TRACE.TRACE( GLOBAL.PA_TRACE.TRACE_TRACE, methodenname, 'Parameters: ');     END IF;     UPDATE WPH.STATUS     SET KURZBEZEICHNUNG   = SELF.KURZBEZEICHNUNG        ,BEZEICHNUNG       = SELF.BEZEICHNUNG     WHERE STATUS_ID         = SELF.STATUS_ID       AND GEAENDERT_ZAEHLER = SELF.GEAENDERT_ZAEHLER     RETURNING STATUS_ID              ,KURZBEZEICHNUNG              ,ERSTELLT_ZST              ,ERSTELLT_ID              ,GEAENDERT_ZST              ,GEAENDERT_ID              ,GEAENDERT_ZAEHLER              ,BEZEICHNUNG          INTO SELF.STATUS_ID              ,SELF.KURZBEZEICHNUNG              ,SELF.ERSTELLT_ZST              ,SELF.ERSTELLT_ID              ,SELF.GEAENDERT_ZST              ,SELF.GEAENDERT_ID              ,SELF.GEAENDERT_ZAEHLER              ,SELF.BEZEICHNUNG     ;     IF SQL%ROWCOUNT <> 1 THEN       GLOBAL.RAISE(-20999); -- Der Datensatz hat sich zwischenzeitlich geändert     END IF;   EXCEPTION     WHEN OTHERS THEN       GLOBAL.PA_TRACE.TRACE( GLOBAL.PA_TRACE.TRACE_ERROR, methodenname, ' - Exception raised. '                             ||SELF.TO_STRING()                             ||', SQLcode=' || to_char(SQLCODE) || ', ' || SQLERRM);     RAISE;   END;

Optimistisches Locking - DELETE   MEMBER PROCEDURE ROW_DELETE   IS     methodenname  CONSTANT VARCHAR2(100) := 'WPH.ROW_STATUS.ROW_DELELE';   BEGIN     IF SYS_CONTEXT('TRACE','TRACE_LEVEL') >= GLOBAL.PA_TRACE.TRACE_TRACE THEN       GLOBAL.PA_TRACE.TRACE( GLOBAL.PA_TRACE.TRACE_TRACE, methodenname, 'Parameters: ');     END IF;     DELETE FROM WPH.STATUS     WHERE STATUS_ID         = SELF.STATUS_ID       AND GEAENDERT_ZAEHLER = SELF.GEAENDERT_ZAEHLER;     IF SQL%ROWCOUNT <> 1 THEN       GLOBAL.RAISE(-20999); -- Der Datensatz hat sich zwischenzeitlich geändert     END IF;   EXCEPTION     WHEN OTHERS THEN       GLOBAL.PA_TRACE.TRACE( GLOBAL.PA_TRACE.TRACE_ERROR, methodenname, ' - Exception raised. '                             ||SELF.TO_STRING()                             ||', SQLcode=' || to_char(SQLCODE) || ', ' || SQLERRM);     RAISE;   END;

Variablen und OO-ROWTYPE declare s VARCHAR2(50); begin SELECT s.kurzbezeichnung INTO s FROM WPH.STATUS s WHERE s.sTATUS_ID=200; end; declare s WPH.STATUS.KURZBEZEICHNUNG%TYPE; begin SELECT s.kurzbezeichnung INTO s FROM WPH.STATUS s WHERE s.STATUS_ID=200; end; declare   s WPH.STATUS%ROWTYPE; begin   SELECT *   INTO s   FROM WPH.STATUS s   WHERE s.sTATUS_ID=200; end; declare s WPH.ROW_STATUS; begin s := WPH.ROW_STATUS(IN_STATUS_ID => 200); end;

Arbeiten mit OO-ROWTYPE declare i ROW_STATUS; begin i := ROW_STATUS(IN_STATUS_ID => 200); i.DBMS_OUTPUT; i.KURZBEZEICHNUNG := 'Eingestellt'; i.ROW_UPDATE; end; <ROW_STATUS> <OBJECT_TYPE_NAME>WPH.ROW_STATUS</OBJECT_TYPE_NAME> <STATUS_ID>200</STATUS_ID> <KURZBEZEICHNUNG>Einstellung</KURZBEZEICHNUNG> <ERSTELLT_ZST>12.07.02</ERSTELLT_ZST> <ERSTELLT_ID>-2</ERSTELLT_ID> <GEAENDERT_ZST>14.08.04</GEAENDERT_ZST> <GEAENDERT_ID>1469</GEAENDERT_ID> <GEAENDERT_ZAEHLER>2</GEAENDERT_ZAEHLER> <BEZEICHNUNG>ORDERAUSFUEHRUNG-STATUS</BEZEICHNUNG> </ROW_STATUS> <KURZBEZEICHNUNG>Eingestellt</KURZBEZEICHNUNG> <GEAENDERT_ZST>15.06.10</GEAENDERT_ZST> <GEAENDERT_ID>907</GEAENDERT_ID> <GEAENDERT_ZAEHLER>3</GEAENDERT_ZAEHLER>

Gattungsstamm – Input Daten G       DE000AAR0082AAR0081900000640329 00"GD090  09062010"GD100  01"GD100A 1"GD160  004"GD161  DE"GD170  EO "GD171  EUR"GD172  EUR"GD190  PD"GD195  227"GD196  1"GD198A SEC"GD198B 2000"GD198C 2003"GD198D ZZZZ"GD198E ZZZZ"GD198F E302"GD198G M401"GD200  00025"GD201  DE03472          "GD205B KA05"GD211  1"GD212  703"GD213  25"GD214  22"GD215A J"GD217  AAC"GD218  J"GD218A J"GD218B J"GD218C J"GD220  142"GD220A 004"GD220C 183"GD225  A"GD226  60"GD227  1"GD228  0413"GD230  MTH"GD234  1"GD240  804110"GD260  AAREAL BANK MTN.HPF.S.67 "GD270A Aareal Bank AG                "GD270B MTN-HPF.S.67 v.2010(2013)     "GD280A Serie 67 v. 2010 (2013)       "GD290  16092010"GD290A 16092010"GD300  16092013"GD312  6"GD321  10"GD322  16062010"GD323  15092013"GD388A 686665"GD388PIDE0006866650"GD400  03"GD410  9"GD420  7"GD423  J"GD424  B"GD430  099"GD440  2"GD455A 000001000000000000"GD455E 1"GD473  ²NOM=1000,W=EUR;                         "GD481A 05"GD483  1"GD500  84"GD504A J"GD505B 25000000000"GD505E 2"GD507  0550000"GD545  1"GD545A 2"GD546  09062010"GD571  J"GD572  J"GD621  099"GD622  DE000AAR0082"GD622PWAAR008"GD630A 000000500000000000"GD630B EUR"GD650A 000000500000000000"GD660  16062010"GD663A N"GD663D N"GD669  0000997590000"GD670A EUR"GD670B %"GD672  1"GD685  DTFSFB"GD697  2B"GD776  3"GD801A 0001750000000"GD805  F"GD810  093"GD811  1"GD812  16"GD812A 16"GD813  SEPT"GD813A SEPT"GD815  0092"GD815A 0044109589"GD819  2"GD821B 09"GD822  01"GD841  2"GD861A 000000100000000000"GD862  16092013"GD910  16092013"GD924  N"GD970G 01"GD986  ²deutsches Recht G       DE000AAR0082AAR0081909920640329 00"GV992  ²0660/J/ / / / / / / / / / / / /         ²0348/J/ / / / / / / / / / / / /         ²2597/J/ / / / / / / / / / / / / G       DE000AAR0082AAR0081909950640329 00"GV995  ²0660/ / / / / / / / / /J/ / / /         ²0348/ / / / / / / / / / /J/ / /         ²2597/ / / / / / / / / / /J/ / / E       NO00030753019065612010060932000 00"ED001  2"ED002A 1"ED004A DD"ED023  1"ED024A 01012009"ED025A 31122009"ED190  02 G       NO00030753019065611910000603643 00"GD090  29062010"GD260  PETROLIA DRILLING    NK 5"GD270A Petrolia Drilling ASA         "GD270B Navne-Aksjer NK 5             "GD460A 000000005000000000 H       NO00030753019065612010032905600200"HD008  28062010"HD015  1300 U       NO00030753019065612010060940500 00"UD001  1"UD002A 1"UD005  1"UD006  1"UD007  4"UD008A AZ"UD010A ST "UD010C 0000010000000"UD010D 0000000100000000"UD011A ST "UD011C 0000100000000"UD011D 0000000010000000"UD021  906561"UD021PINO0003075301"UD025  29062010²ca.                                     "UD034  28062010"UD078  20"UD087  049"UD190  02"UD460A 000000000500000000"UD460B 000000005000000000

Gattungsstamm – Datenbank Model

Schwergewichtiger TYPE CREATE OR REPLACE TYPE TYPE_GATTUNG AUTHID CURRENT_USER UNDER GLOBAL.TYPE_OBJECT (  -- Attributes   id               NUMBER(12) , isin             CHAR(12) , wkn              CHAR(6) , sh               NUMBER(2) , geloescht        DATE , name             VARCHAR2(80) , instrument       VARCHAR2(80) , fids             WP.TABLE_WMFID , ertraege         WP.TABLE_ERTRAG , kapitals         WP.TABLE_KAPITAL , ohc              WP.TABLE_GATTUNG_OHC , hauptversammlung WP.TABLE_HAUPTVERSAMMLUNG , bogenerneuerung  WP.TABLE_BOGENERNEUERUNG , umtausch         WP.TABLE_UMTAUSCH , verlosung        WP.TABLE_VERLOSUNG , termin           WP.TABLE_GATTUNG_TERMIN , opposition       WP.TABLE_OPPOSITION , ifp              WP.TABLE_WMFID , NWKN             VARCHAR2(4000) -- Nationale WKN   -- Methods , CONSTRUCTOR FUNCTION TYPE_GATTUNG RETURN SELF AS RESULT , CONSTRUCTOR FUNCTION TYPE_GATTUNG(in_id NUMBER) RETURN SELF AS RESULT , CONSTRUCTOR FUNCTION TYPE_GATTUNG(IN_ID NUMBER, IN_DATUM DATE) RETURN SELF AS RESULT , CONSTRUCTOR FUNCTION TYPE_GATTUNG(in_isin VARCHAR2, in_sh NUMBER DEFAULT 0) RETURN SELF AS RESULT , CONSTRUCTOR FUNCTION TYPE_GATTUNG(in_wkn VARCHAR2, in_sh NUMBER DEFAULT 0) RETURN SELF AS RESULT , CONSTRUCTOR FUNCTION TYPE_GATTUNG(in_wkn VARCHAR2, in_sh NUMBER, in_datum DATE) RETURN SELF AS RESULT , CONSTRUCTOR FUNCTION TYPE_GATTUNG(in_isin VARCHAR2, in_wkn VARCHAR2, in_sh NUMBER DEFAULT 0, in_geloescht DATE DEFAULT NULL) RETURN SELF AS RESULT , CONSTRUCTOR FUNCTION TYPE_GATTUNG(in_isin VARCHAR2, in_wkn VARCHAR2, in_instrument VARCHAR2) RETURN SELF AS RESULT , MEMBER PROCEDURE add_ertrag(in_ertrag WP.TYPE_ERTRAG) , MEMBER PROCEDURE add_hauptversammlung(in_hauptversammlung WP.TYPE_HAUPTVERSAMMLUNG) , MEMBER PROCEDURE add_bogenerneuerung(in_bogenerneuerung WP.TYPE_BOGENERNEUERUNG) , MEMBER PROCEDURE add_kapital(in_kapital WP.TYPE_KAPITAL) , MEMBER PROCEDURE add_umtausch(in_umtausch WP.TYPE_UMTAUSCH) , MEMBER PROCEDURE add_verlosung(in_verlosung WP.TYPE_VERLOSUNG) , MEMBER PROCEDURE add_ohc(in_ohc WP.TYPE_GATTUNG_OHC) , MEMBER PROCEDURE add_termin(in_termin WP.TYPE_GATTUNG_TERMIN) , MEMBER PROCEDURE add_opposition(in_opposition WP.TYPE_OPPOSITION) , MEMBER PROCEDURE INIT_KAPITAL_DETAIL(SELF IN OUT TYPE_GATTUNG) , MEMBER FUNCTION  GET_KAPITAL_DETAIL(SELF IN OUT TYPE_GATTUNG) RETURN WP.TABLE_KAPITAL , MEMBER PROCEDURE INIT_FID_DETAIL(SELF IN OUT TYPE_GATTUNG) , MEMBER FUNCTION  GET_FID_DETAIL(SELF IN OUT TYPE_GATTUNG) RETURN WP.TABLE_WMFID , MEMBER PROCEDURE INIT_SCD_FIDS(IN_DATUM DATE DEFAULT NULL) , MEMBER PROCEDURE INIT_OHC(IN_BOERSENPLATZ_ID VARCHAR2) ,… ) NOT FINAL

Schwergewichtiger TYPE (Fortsetzung) CREATE OR REPLACE TYPE TABLE_ERTRAG AS TABLE OF WP.TYPE_ERTRAG; ------------------------------------------------------------------------------------------------------------------------ CREATE OR REPLACE TYPE TYPE_ERTRAG UNDER WP.ROW_ERTRAG_BASE (   -- Attributes   id               NUMBER(12) , fids             WP.TABLE_WMFID   -- Methods , CONSTRUCTOR       FUNCTION  TYPE_ERTRAG RETURN SELF AS RESULT , CONSTRUCTOR       FUNCTION  TYPE_ERTRAG(in_wmdaten WP.TYPE_WMDATEN) RETURN SELF AS RESULT , CONSTRUCTOR       FUNCTION  TYPE_ERTRAG(OBJECT_TYPE_NAME VARCHAR2, ID NUMBER, BID_NR VARCHAR2, DATUM DATE, FIDS WP.TABLE_WMFID) RETURN SELF AS RESULT , CONSTRUCTOR       FUNCTION  TYPE_ERTRAG(BID_NR VARCHAR2, DATUM DATE, FIDs WP.TABLE_WMFID) RETURN SELF AS RESULT , CONSTRUCTOR       FUNCTION  TYPE_ERTRAG(in_BID_NR VARCHAR2, in_DATUM VARCHAR2, in_FIDs WP.TABLE_WMFID) RETURN SELF AS RESULT , CONSTRUCTOR       FUNCTION  TYPE_ERTRAG(IN_ERTRAG_BASE_ID NUMBER, IN_DATUM DATE DEFAULT NULL) RETURN SELF AS RESULT , MEMBER            PROCEDURE INIT_SCD_FIDS(IN_DATUM DATE DEFAULT NULL) , OVERRIDING MEMBER FUNCTION  compare(in_type1 GLOBAL.TYPE_OBJECT, in_type2 GLOBAL.TYPE_OBJECT) RETURN INTEGER , MEMBER            PROCEDURE getDBid(in_gattung_id NUMBER) , MEMBER            PROCEDURE save(in_gattung_id NUMBER,IN_DATUM DATE DEFAULT SYSDATE) , MEMBER            FUNCTION  TO_VF1 RETURN GLOBAL.TABLE_VARCHAR2 ) NOT FINAL --------------------------------------------------------------------------------------------------------------------------- CREATE OR REPLACE TYPE ROW_ERTRAG_BASE UNDER GLOBAL.TYPE_OBJECT (-- attributes     ERTRAG_BASE_ID     NUMBER(12)   , GATTUNG_BASE_ID    NUMBER(12)   , BID_NR             VARCHAR2(5)   , DATUM              DATE   , ERSTELLT_ZST       DATE   , GEAENDERT_ZST      DATE   , ERSTELLT_ID        NUMBER(12)   , GEAENDERT_ID       NUMBER(12)   , ERSTELLT_IP        VARCHAR2(30)   , GEAENDERT_IP       VARCHAR2(30)   , GEAENDERT_ZAEHLER  NUMBER(10)   -- define constructors   , CONSTRUCTOR FUNCTION ROW_ERTRAG_BASE RETURN SELF AS RESULT   , CONSTRUCTOR FUNCTION ROW_ERTRAG_BASE(ERTRAG_BASE_ID NUMBER, GATTUNG_BASE_ID NUMBER, BID_NR , … ) NOT FINAL

Schwergewichtiger TYPE & Load Balancing MEMBER PROCEDURE INIT_KAPITAL_DETAIL(SELF IN OUT TYPE_GATTUNG)   IS     methodenname  CONSTANT VARCHAR2(300) := 'WP.'||$$PLSQL_UNIT||'.INIT_KAPITAL_DETAIL';     FUNCTION parm RETURN VARCHAR2 IS BEGIN       RETURN substr( 'Parameter: ' || CHR(10) || 'SELF:' || SELF.TO_STRING(),1,32760);     END;   BEGIN     IF SYS_CONTEXT('TRACE','TRACE_LEVEL') >= GLOBAL.PA_TRACE.TRACE_TRACE THEN       GLOBAL.PA_TRACE.TRACE( GLOBAL.PA_TRACE.TRACE_TRACE, methodenname, parm());     END IF;     SELF.kapitals := WP.TABLE_KAPITAL();     FOR rec IN (SELECT d.kapital_base_id                   FROM WP.Kapital_Base d                  WHERE d.gattung_base_id = SELF.id                  ORDER BY datum                )     LOOP       SELF.kapitals.EXTEND;       SELF.kapitals(SELF.kapitals.LAST) :=         WP.TYPE_KAPITAL(in_kapital_base_id => rec.kapital_base_id);     END LOOP;   EXCEPTION     WHEN OTHERS THEN       GLOBAL.pa_trace.TRACE( GLOBAL.pa_trace.TRACE_ERROR, methodenname, parm()||CHR(10)||         ', SQLcode=' || to_char(SQLCODE) || ', ' || SQLERRM);     RAISE;   END;   ---------------------------------------------------------------   MEMBER FUNCTION  GET_KAPITAL_DETAIL(SELF IN OUT TYPE_GATTUNG) RETURN WP.TABLE_KAPITAL   IS     methodenname  CONSTANT VARCHAR2(300) := 'WP.'||$$PLSQL_UNIT||'.GET_KAPITAL_DETAIL';     FUNCTION parm RETURN VARCHAR2 IS BEGIN       RETURN substr('Parameter: ' || CHR(10) || 'SELF:' || SELF.TO_STRING(),1,32760);     END;   BEGIN     IF SYS_CONTEXT('TRACE','TRACE_LEVEL') >= GLOBAL.PA_TRACE.TRACE_TRACE THEN       GLOBAL.PA_TRACE.TRACE( GLOBAL.PA_TRACE.TRACE_TRACE, methodenname, parm());     END IF; IF SELF.kapitals IS NULL THEN     SELF.INIT_KAPITAL_DETAIL(); END IF;     RETURN SELF.kapitals;   EXCEPTION     WHEN OTHERS THEN       GLOBAL.pa_trace.TRACE( GLOBAL.pa_trace.TRACE_ERROR, methodenname, parm()||CHR(10)||         ', SQLcode=' || to_char(SQLCODE) || ', ' || SQLERRM);     RAISE;   END;

Fliegengewichtiger COMP CREATE OR REPLACE TYPE COMP_GATTUNG UNDER GLOBAL.TYPE_OBJECT (   -- Attributes   GATTUNG_BASE_ID      NUMBER , WKN                  CHAR(6) , ISIN                 CHAR(12) , SH                   NUMBER(2) , NAME                VARCHAR2(80) , INSTRUMENT   VARCHAR2(80) , GELOESCHT    DATE   -- Methods , CONSTRUCTOR FUNCTION  COMP_GATTUNG RETURN SELF AS RESULT , CONSTRUCTOR FUNCTION  COMP_GATTUNG(IN_GATTUNG_BASE_ID NUMBER) RETURN SELF AS RESULT , CONSTRUCTOR FUNCTION  COMP_GATTUNG(IN_ISIN VARCHAR2, IN_SH NUMBER DEFAULT 0) RETURN SELF AS RESULT , CONSTRUCTOR FUNCTION  COMP_GATTUNG(IN_WKN VARCHAR2,  IN_SH NUMBER DEFAULT 0) RETURN SELF AS RESULT , CONSTRUCTOR FUNCTION  COMP_GATTUNG(IN_ISIN VARCHAR2, IN_WKN VARCHAR2, IN_SH NUMBER) RETURN SELF AS RESULT , CONSTRUCTOR FUNCTION  COMP_GATTUNG(IN_SECURITY_ID VARCHAR2, IN_ID_SOURCE VARCHAR2) RETURN SELF AS RESULT , MEMBER FUNCTION GET_ABRECHNUNGS_WAEHRUNG_ISO(IN_BOERSENPLATZ_ID VARCHAR2) RETURN VARCHAR2 , MEMBER FUNCTION GET_ABRECHNUNGS_WAEHRUNG_ID(IN_BOERSENPLATZ_ID VARCHAR2) RETURN NUMBER , MEMBER FUNCTION GET_ABRECHNUNGS_WAEHRUNG_ISO RETURN VARCHAR2 , MEMBER FUNCTION GET_HANDELS_WAEHRUNG_ISO(IN_BOERSENPLATZ_ID VARCHAR2) RETURN VARCHAR2 , MEMBER FUNCTION GET_HANDELS_WAEHRUNGEN_ISO(IN_BOERSENPLATZ_ID VARCHAR2) RETURN BBS.TAB_ROW_WAEHRUNG , MEMBER FUNCTION GET_RIC RETURN VARCHAR2 , MEMBER FUNCTION GET_RIC(IN_BOERSENPLATZ_ID VARCHAR2) RETURN VARCHAR2 , MEMBER FUNCTION GET_SEDOL RETURN VARCHAR2 , MEMBER FUNCTION GET_CUSIP RETURN VARCHAR2 , MEMBER FUNCTION GET_EMITTENT_NR RETURN VARCHAR2 , MEMBER FUNCTION GET_HEIMATLAND_ISO RETURN VARCHAR2 , MEMBER FUNCTION GET_HEIMATBOERSE_ID RETURN VARCHAR2 , MEMBER FUNCTION GET_LETZTER_HANDELSTAG(IN_BOERSENPLATZ_ID VARCHAR2) RETURN DATE , MEMBER FUNCTION IS_MIFID_RELEVANT RETURN BOOLEAN , MEMBER FUNCTION IS_DAX RETURN BOOLEAN , MEMBER FUNCTION IS_MDAX RETURN BOOLEAN , MEMBER FUNCTION IS_SDAX RETURN BOOLEAN , MEMBER FUNCTION IS_TECDAX RETURN BOOLEAN , MEMBER FUNCTION IS_STOXX RETURN BOOLEAN , MEMBER FUNCTION IS_HANDELBAR(IN_LAND_ISO VARCHAR2) RETURN BOOLEAN , MEMBER FUNCTION IS_HANDELBAR(IN_BOERSENPLATZ_ID VARCHAR2) RETURN BOOLEAN , MEMBER FUNCTION IS_HANDELBAR_FH(IN_BOERSENPLATZ_ID VARCHAR2) RETURN BOOLEAN , MEMBER FUNCTION IS_INVESTRO RETURN BOOLEAN , MEMBER FUNCTION IS_ZERTIFIKAT RETURN BOOLEAN , MEMBER FUNCTION IS_WARRANT RETURN BOOLEAN , MEMBER FUNCTION IS_FOND RETURN BOOLEAN , MEMBER FUNCTION IS_BEGO_FOND RETURN BOOLEAN , MEMBER FUNCTION IS_EHF RETURN BOOLEAN , MEMBER FUNCTION IS_DEF RETURN BOOLEAN , … ) NOT FINAL

Schwergewichtiger TYPE CREATE OR REPLACE TYPE TYPE_KUNDE UNDER BBS.ROW_KUNDE (  -- attributes   DEPOT               BBS.TABLE_DEPOT,   KONTEN             BBS.TABLE_KONTO,   KONTEN_BBS     BBS.TABLE_KONTO_BBS,   land                VARCHAR2(35),   nationalitaet       VARCHAR2(35),   rechtsform          VARCHAR2(105),   branche             VARCHAR2(105),   betreuer1           VARCHAR2(35),   betreuer2           VARCHAR2(35),   betreuer3           VARCHAR2(35),   betreuer4           VARCHAR2(35),   stammkreis          VARCHAR2(35)   -- define constructors   , CONSTRUCTOR FUNCTION TYPE_KUNDE       RETURN SELF AS RESULT   , CONSTRUCTOR FUNCTION TYPE_KUNDE(IN_STAMMNR VARCHAR2)       RETURN SELF AS RESULT   , CONSTRUCTOR FUNCTION TYPE_KUNDE(IN_UNTERDEPOTID NUMBER)       RETURN SELF AS RESULT   , CONSTRUCTOR FUNCTION TYPE_KUNDE(IN_KUNDENID NUMBER, IN_KONTOID NUMBER)       RETURN SELF AS RESULT   , CONSTRUCTOR FUNCTION TYPE_KUNDE(IN_DEPOTNUMMER CHAR, IN_REFERENZNUMMER NUMBER)       RETURN SELF AS RESULT   ---------------------------------------------------------------   -- static functions instead of constructors   -- duplicate signature problem in Java   , STATIC FUNCTION CONSTRUCTOR_TYPE_KUNDE(IN_KUNDENID NUMBER)       RETURN BBS.TYPE_KUNDE   , STATIC FUNCTION CONSTRUCTOR_KONTONUMMER(IN_KONTONUMMER VARCHAR2)       RETURN BBS.TYPE_KUNDE   , STATIC FUNCTION CONSTRUCTOR_KONTO_BBS_ID(IN_KONTO_BBS_ID NUMBER)       RETURN BBS.TYPE_KUNDE   -- define member functions   , MEMBER PROCEDURE ROW_SELECT(IN_STAMMNR VARCHAR2)   , MEMBER PROCEDURE ROW_SELECT(IN_KUNDENID NUMBER, IN_VERSION NUMBER)   , MEMBER PROCEDURE init_text_fields   , MEMBER PROCEDURE INIT_DEPOT(SELF IN OUT TYPE_KUNDE,                           IN_REFERENZNUMMER NUMBER DEFAULT NULL)   , MEMBER PROCEDURE INIT_DEPOT(SELF IN OUT TYPE_KUNDE, IN_DISPLAY_ID     NUMBER, IN_REFERENZNUMMER NUMBER DEFAULT NULL)   , MEMBER PROCEDURE INIT_KONTEN(SELF IN OUT TYPE_KUNDE) , … ) NOT FINAL

Fliegengewichtiger COMP CREATE OR REPLACE TYPE COMP_KUNDE UNDER GLOBAL.TYPE_OBJECT (   -- Attributes   KUNDE_ID             NUMBER(12) , STAMMNUMMER          CHAR(10) , INHABER              VARCHAR2(35) , SPRACHE_ID           NUMBER(12)   -- Methods , CONSTRUCTOR FUNCTION COMP_KUNDE RETURN SELF AS RESULT , CONSTRUCTOR FUNCTION COMP_KUNDE(in_kunde_id NUMBER) RETURN SELF AS RESULT , CONSTRUCTOR FUNCTION COMP_KUNDE(in_stammnummer CHAR) RETURN SELF AS RESULT , CONSTRUCTOR FUNCTION COMP_KUNDE(in_unterdepot_id NUMBER) RETURN SELF AS RESULT ) NOT FINAL

Mischung OO-Type und relationale FK ID Analogon zur DEREF in ODBMS kann man mit dem FK eines Type den anderen Type instanzieren declare b wph.ROW_BOERSE; h wph.ROW_HANDELSSYSTEM; begin b := wph.ROW_BOERSE('194'); h := wph.ROW_HANDELSSYSTEM(b.HANDELSSYSTEM_ID); end;

Wie programmieren wir in PL/SQL -- Allocation ermitteln FOR rec_alloc IN (SELECT g.COLUMN_VALUE AS xml FROM TABLE (XMLSEQUENCE(rec_order.XML.EXTRACT('Order/Allocations/Allocation'))) g) LOOP -- Neue Allocation anlegen t_allocation := NEW WPH.TYPE_ALLOCATION ( IN_KUNDE_ID => t_ob.KUNDE_ID , IN_ANNAHMEART_ID => t_ob.ANNAHMEART_ID , IN_ALLOC_IDENT => t_ob.ORDER_NR_EXTERN , ...); -- Order hinzufuegen t_allocation.ADD_ORDER(IN_ORDER_BUCH_ID => t_ob.ORDER_BUCH_ID); -- Client Account ermitteln v_client_account := GLOBAL.PA_XML.EXTRACT_STRING(rec_alloc.XML, 'Allocation/ClientAccount'); -- Stueckzahl ermitteln v_stueckzahl := GLOBAL.PA_XML.EXTRACT_NUMBER(rec_alloc.XML, 'Allocation/Stueckzahl'); IF v_stueckzahl IS NOT NULL THEN -- Allocation hinzufuegen t_allocation.ADD_ALLOCATION(IN_CLIENT_ACCOUNT => v_client_account , IN_STUECKZAHL => GLOBAL.PA_XML.EXTRACT_NUMBER(rec_alloc.XML, 'Allocation/Stueckzahl') , IN_KURS => NULL); ELSE -- Prozentsatz ermitteln v_prozentsatz := GLOBAL.PA_XML.EXTRACT_NUMBER(rec_alloc.XML, 'Allocation/Prozentsatz'); , IN_PROZENTSATZ => v_prozentsatz); END IF; END LOOP; -- Allocation einstellen t_allocation.EINSTELLEN();

Wie programmieren wir in PL/SQL -- zentrale Schnittstelle zum Steuermodul PROCEDURE STEUER_BERECHNUNG(...) IS t_steuer BBS.TYPE_STEUER; BEGIN -- geschäftsbedingt Instanzierung IF ....GESCHAEFTSART = 'KKZ' THEN t_steuer := NEW BBS.TYPE_STEUER_KKZ(...) ELSIF ....GESCHAEFTSART = 'WPK' THEN t_steuer := NEW BBS.TYPE_STEUER_WPK(...) ELSIF <weitere Geschäftsbereiche> THEN t_steuer := NEW BBS.TYPE_STEUER_XXX(...) END IF; -- Aufruf der Steuerverrechnung t_steuer.BERECHNE_STEUERN; END;

Unsere Leitsätze Man sollte alles so einfach wie möglich machen, aber nicht einfacher Albert Einstein "Der einfache und klare Zweck sowie Prinzipien bedingen komplexes und intelligentes Verhalten". "Komplexe Regeln und Vorschriften bedingen einfaches und dummes Verhalten". Dee Hock, Designer VISA-Systems 1960-1970 Ein System erreicht Perfektion nicht, wenn nichts weiter hinzugefügt werden kann, sondern wenn nichts weiter entfernt werden kann. ???

E-Mail : andriy.terletskyy@berenberg.de Q&A Vielen Dank ! E-Mail : andriy.terletskyy@berenberg.de