Programmierung von Datenbank Anwendungen

Slides:



Advertisements
Ähnliche Präsentationen
Object Relational Mapping
Advertisements

Vorlesung Datenbank-programmierung
1 Kapitel 9: Datenbankapplikationen. 2 Datenbankapplikationen MS Access Embedded SQL JDBC Application JDBC Applet Java Servlet Java Server Pages Cold.
1 Datenbankapplikationen 9.1MS Visio 9.2MS Access 9.3Embedded SQL 9.4JDBC 9.5Cold Fusion 9.6PHP.
Datenbank-Zugriffsschnittstellen. © Prof. T. Kudraß, HTWK Leipzig Überblick Datenbankzugriff mit PHP Datenbankzugriff mit JDBC Datenbankzugriff mit PSP.
Folien 2-5, 7-8 © Prof. Dr. Manfred Rössle (FH Aalen)
2. DB-API: Programmierschnittstellen zu Datenbanken
System J – Compiler – Praktikum: Datenbanksystementwicklung Knut Stolze
Allgemeine Technologien II
Systemüberblick Beispiele: Microsoft Access Oracle Ingres Informix
JDBC & ODMG Motivation - Beispielanwendung JDBC - DriverManager - Connection - Statement - ResultSet Anwendung ODMG - Objektmodell /ODL - OQL - Java-Binding.
Anbindung an Anwendungen
Java: Objektorientierte Programmierung
Java: Dynamische Datentypen
Indirekte Adressierung
FH-Hof SQLJ Richard Göbel. FH-Hof SQLJ - Idee Erweiterung von Java um SQL Die Verwendung von SQL-Anweisungen innerhalb einer Programmiersprache wird vereinfacht.
SQL als Abfragesprache
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],
Dynamische Webseiten mit PHP
Dynamische Webseiten Java servlets.
PL/SQL – Die prozedurale Erweiterungssprache Zu SQL
Oracle PL/SQL Server Pages (PSP). © Prof. T. Kudraß, HTWK Leipzig Grundidee: PSP – Internet-Seiten mit dynamischer Präsentation von Inhalten durch Einsatz.
Open Database Connectivity (ODBC). © Prof. T. Kudraß, HTWK Leipzig Open Database Connectivity (ODBC) Idee: – API für eine DBMS, das ein Call-Level-Interface.
Entwicklung von XML-Anwendungen mit ORACLE XSU Oberseminar Datenbanken Andreas Rebs, 01INM.
Datenbank-Zugriffsschnittstellen am Beispiel von Oracle und PL/SQL.
Text-Retrieval mit Oracle Vortrag von Andreas Mück & David Diestel.
JDBC Konzepte Realisierung von Zugriffen
Übung Datenbanksysteme WS 2003/ Übung Datenbanksysteme Hierarchische DBMS
Transaction Script Software Component Technology for Distributed Applications.
Die Skriptsprache Perl (2) Wolfgang Friebel DESY Zeuthen.
JDBC -Java Database Connectivity-. 15./22. April 2004JDBC2 JDBC.... verbindet Java-Programme mit SQL-basierten Datenbanken.. liefert eine generische SQL-API.
JDBC EDV JDBC.
Kapitel 8: Web-Anwendungen mit SQL und PHP
Datenbanken 10: Einfügen, Ändern, Löschen
Einführung in die Programmierung Datensammlung
Einführung MySQL mit PHP
Prof. K. Gremminger Folie 1 Vorlesung Datenbanksysteme SS 2002 Cursor-Konzept u Zugriff auf Mengen von Ergebnistupeln u In SQLJ Iteratoren u Vergleichbar.
Prof. K. Gremminger Folie 1 Vorlesung Datenbanksysteme SS 2002 Aufbau einer Verbindung zur Datenbank import java.net.URL; import java.sql.*; class JDBCExample.
JDBC: JAVA Database Connectivity
Datenmodelle, Datenbanksprachen und Datenbankmanagementsysteme
SQL PHP und MySQL Referat von Katharina Stracke und Carina Berning
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
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.
JDBC (Java DataBase Connectivity)
Objectives Verstehen was unterDelegate verstanden wird
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
Embedded SQL in Java Michael Stapf Berater Strategische Projekte
Programmiervorkurs WS 2014/15 Schleifen
Structured Query Language
8 Erzeugen und Verwalten von Tabellen Ziele Kennenlernen der wichtigsten Datenbankobjekte Anlegen von Tabellen Datentypen zur Definition von Spalten.
Alois Schütte Advanced System Programming 2 Interprozeßkommunikation  2.1 JVM Ablaufumgebung  2.2 Java Native Interface (JNI)  Verwendung von.
OQL-Anbindung an Java (1) Java als Beispiel für die Einbettung von OQL in eine Programmiersprache Die OQL-Einbettung in Java ist teilweise mit dynamischem.
11 Verwaltung von Abhängigkeiten. Ziele Am Ende dieser Lektion verfügen Sie über die folgenden Kenntnisse: Überwachen prozeduraler Abhängigkeiten Effekte.
WS 2013/14 Datenbanksysteme Do 17:00 – 18:30 R Vorlesung #8 SQL (Teil 5)
11 Zugriffskontrolle (Access Control) Ziele Privilegien Rollen GRANT und REVOKE Befehl Privilegien Rollen GRANT und REVOKE Befehl.
Trigger-abhängige Client Interaktionen (bezüglich Oracle8i)
JDBC1 Motivation(I) JDBC keine Abkürzung, sondern geschützter Name (inoffiziell: für Java Database Connectivity) unterschiedliche DBS haben unterschiedliche.
WS 2014/15 Datenbanksysteme Do 17:00 – 18:30 R Vorlesung #9 SQL Zusammenfassung.
By Thorsten Zisler 1 SQL Datenbank Anbindung an den Supervisor.
DB2 UDB im z/VSE Heinz Peter Maassen – Lattwein GmbH COURSE Tagung Bad Hersfeld 2008.
© Thales IS GmbH 2002 Oracle's Data Warehousing Features 1 Thales Information Systems GmbH Im Team für Ihren Erfolg DOAG - Regionaltreffen Hannover Donnerstag,
Übung Datenbanksysteme I Embedded SQL, Stored Procedures, JDBC
Vorlesung #8 SQL (Teil 5).
Create Table, Rechte und Rollen
 Präsentation transkript:

Programmierung von Datenbank Anwendungen ESQL, ODBC, JDBC und co

Methoden bisher interaktive Verwendung von SQL Terminal Skripte Ausführen von SQL aus Programmiersprache heraus proprietäre APIs standardisierte Schnittstellen statisch (embedded SQL) dynamisch (ODBC, JDBC)

Embedded SQL Einbettung von SQL-Statements in Wirts-Sprache C,COBOL, PL/1, FORTRAN, PASCAL,... Vor-Übesetzung des Programms in Wirts-Sprache (precompile) i.w. gleiche Syntax wie bei interaktivem SQL, zusätzlich Konstrukte für Einbettung der SQL-Befehle Fehlerbehandlung Übergabe von Variableninhalten Übergabe von Query-Ergebnissen Einfache, sprachunabhängige Syntax für Precompiler EXEC SQL Präfixc für SQL-Kommandos ":" als Kennzeichner für Variablen

Vorgehen example.pc C Source mit eingebettetem SQL Precompiler für C example.c C Source, SQl durch DBMS-spezifische Funktionsaufrufe ersetzt C Compiler example.o Object Code DBMS- Library Linker example[.exe] ausführbares Programm

Tupelvariablen SQL liefert Tupelmenge, Darstellung in C, PASCAL,... "Impedence mismatch" Typkonzept des RDBMS und der Wirtssprache passen nicht zusammen Lösung: Cursor Iterator, Tupel-Zeiger für satzweise Verarbeitung EXEC SQL DECLARE name CURSOR FOR select statm. Operationen: OPEN führt Abfrage aus CLOSE FETCH name INTO :var1, :var2,... überträgt Werte der Attribute des aktuellen Datensatzes in Variablen und setzt Zeiger eins weiter

prinzipieller Aufbau EXEC SQL BEGIN DECLARE SECTION; Deklaration der Übergabevariablen EXEC SQL END DECLARE SECTION; EXEC SQL INCLUDE SQLCA; EXEC SQL CONNECT :userid IDENTIFIED BY :password EXEC SQL DECLARE c CURSOR FOR SELECT * FROM EMP; EXEC SQL OPEN c; for(;;) { EXEC SQL FETCH ... } EXEC SQL CLOSE c; EXEC SQL DISCONNECT;

Anmerkungen statisches SQL wird im Programm fest definiert und kann vom Precompiler ausgewertet werden SQL muß vorher bekannt sein ! Wie ist isql implementiert ? dynamisches SQL (in ESQL nicht möglich) tupelweise Verarbeitung u.U. nicht effizient ein Funktionsaufruf pro Tupel - > Array Fetch,... ESQL ist standardisiert wie SQL selbst passende Umgebung muß zum Programm gelinkt werden Geht nicht, wenn Auswahl des DB-Systems erst zur Laufzeit erfolgen soll ! -> ODBC

Native API, Beispiel OCI Oracle Call Interface (CLI) kompliziert, mächtig, Oracle spezifisch bestimmter Funktionen nur mit OCI mehrere Transaktionen BLOBs static char cmd[] = "INSERT INTO MESSAGE(SEVERITY,CODE) VALUES (:Severity,:Code)"; if (!olog(&lda, hda, (unsigned char *)pszUserid, -1, (unsigned char *)pszPassword, -1, (unsigned char *)pszNetAlias, -1, (ub4)OCI_LM_DEF)) if (!oopen(&cda, &lda, (text *) 0, -1, -1, (text *) 0, -1)) if (!oparse(&cda,(unsigned char *) cmd,-1,0,2)) ProcessMessage(&msg); /* normaler C-Code */ if ((!obndrv(&cda,(unsigned char *)":Severity",-1,(unsigned char *) Severity, strlen(Severity), VARCHAR2_TYPE,-1,0,0,-1,-1)) || (obndrv(&cda,(unsigned char *)":Code",-1,(unsigned char *)Code, strlen(Code),VARCHAR2_TYPE,-1,0,0,-1,-1))) if (!oexec(&cda))

Embedded SQL SQL wird in Standard C (COBOL,...) eingebettet Quellcode datenbankunabhängig Precompiler, der OCI erzeugt ausführbares Programm ist datenbankabhängig EXEC SQL BEGIN DECLARE SECTION; VARCHAR pszUserid[20]; VARCHAR pszPassword[20]; VARCHAR Severity[5]; VARCHAR Code[10]; EXEC SQL END DECLARE SECTION; EXEC SQL CONNECT :username IDENTIFIED BY :password; ProcessMessage(&msg); /* normaler C-Code */ EXEC SQL INSERT INTO MESSAGE(Severity, Code) VALUES (:Severity, :Code);

Warum ODBC ? Am Anfang waren die Daten, sie waren unformatiert, und Dunkelheit herrschte auf der Erde. Und Codd sagte: „Es werde ein relationales Datenmodell“. Und so geschah es. Und Codd sagte: „Die Daten sollen von den Datenstrukturen der Applikationsprogramme getrennt werden, so daß eine Datenunabhängigkeit entstehe“. Und es war gut. Und die DBMS-Hersteller sagten: „Wir wollen fruchtbar sein und uns mehren“. Und so geschah es. Und die Benutzer sagten: „Wir wollen Applikationen einsetzen, um auf die Daten von allen DBMS-Herstellern zuzugreifen“ Und die Applikationsentwickler senkten die Häupter und sagten: „Wir müssen durch das finstere Tal mit den Precompilern oder CLI‘s, Kommunikationsstacks und Protokollen aller Hersteller wandern“. Und es war nicht gut ... Und so entstand ODBC (Kyle Geiger, Inside ODBC)

ODBC-Architektur Anwendung ODBC Treibermanager Treiber Datenbank

ODBC Open Database Connectivity Industriestandard (Microsoft, IBM,...) datenbankunabhängig static char cmd[] = "INSERT INTO MESSAGE(SEVERITY,CODE) VALUES (?,?)"; rc=SQLAllocEnv(&henv); rc=SQLAllocConnect(henv,&hdbc); rc=SQLConnect(hdbc,“Kurs",SQL_NTS,ODBC_USERNAME,SQL_NTS,ODBC_PASSWORD,SQL_NTS); rc=SQLAllocStmt(hdbc,&hstmt); rc = SQLPrepare(hstmt,cmd,SQL_NTS); rc = SQLBindParameter(hstmt,1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_VARCHAR, strlen(Severity),0,Severity,0,NULL); rc = SQLBindParameter(hstmt,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_VARCHAR, strlen(Code),0,Code,0,NULL); rc = SQLExecute(hstmt);

JDBC Java Database Connectivity import java.sql.*; class Employee { public static void main (String args []) throws SQLException DriverManager.registerDriver(new com.sybase.jdbc.SybDriver()); Connection conn = DriverManager.getConnection ("jdbc:sybase:Tds:vaio:9898", "ba", "isdb00"); Statement stmt = conn.createStatement (); ResultSet rset = stmt.executeQuery ("select empno,ename from emp"); // Iterate through the result and print the employee names while (rset.next ()) System.out.println (rset.getInt(1) + " " + rset.getString (2)); }

JDBC - Statement Kann SQL-Anweisungen ausführen Statement stmt = conn.createStatement (); Stmt.executeQuery(“SELECT * FROM EMP“); PreparedStatement ps = conn.prepareStatement( „SELECT * FROM EMP WHERE EMPNO = ?“); Kann SQL-Anweisungen ausführen Spezialfall: PreparedStatement: Bei mehrfacher Ausführung bleibt SQL-Text gleich, muß nicht bei jeder Ausführung analysiert werden Bietet u.U. bessere Performance

JDBC - ResultSet executeQuery liefert ResultSet-Objekt zurück ResultSet rset = stmt.executeQuery ("select empno,ename from emp"); while (rset.next ()) System.out.println (rset.getInt(1) + " " + rset.getString (2)); } executeQuery liefert ResultSet-Objekt zurück Kapselt Cursor, kann Ergebnis zeilenweise durchgehen Steht nach executeQuery vor dem ersten Datensatz next() geht einen Datensatz weiter, liefert true zurück, solange aktueller Datensatz gültig Zugriff auf Spalten mit getXXX (getInt, getString,...)

JDBC - PreparedStatement PreparedStatement ps = conn.prepareStatement( „SELECT * FROM EMP WHERE EMPNO = ?“); for(...) { ps.setInt(1,4711); ResultSet rset = ps.execute(); ... } Platzhalter werden mit setXXX mit Werten belegt Erster Parameter ist Index des Platzhalters

JDBC - Transaktionskontrolle conn.setAutoCommit(false); Conn.commit(); Conn.rollback(); Conn.setTransactionIsolation( Connection.TRANSACTION_SERIALIZABLE); AutoCommit führt nach jedem execute ein commit durch (oft Standard, sinnvoll ?) Manuelle Commit-Steuerung oft sinnvoller Nicht alle Isolationlevel werden von allen Datenbanken unterstützt (siehe Datenbanken II)

Performance SQL> describe lagerbewegung Name Null? Type ----------------------------------------- -------- ----------------- NUMMER NOT NULL NUMBER ART NOT NULL NUMBER(2) VORGANGSNUMMER VARCHAR2(10) BESTELLNUMMER NUMBER TEILENUMMER NOT NULL VARCHAR2(15) MENGE NOT NULL NUMBER(10,3) LAGERORT NOT NULL VARCHAR2(12) DATUM NOT NULL DATE SQL> select count(*) from lagerbewegung; COUNT(*) ---------- 159804

Szenario Lesen aller Records aus einer Tabelle und schreiben in andere, zunächst intern durch DB Dann verschiedene Programmiertechniken Idee: Bearbeitung der Records nötig, z.B. ergänzen von Werten ... SQL> create table fastest as select * from lagerbewegung; Table created. Elapsed: 00:00:03.91

Einschub PL/SQL „select finance.AuftragTotal('01-1691/01') from dual;“ 3G Sprache von Oracle Andere etwa: Transact SQL (Microsoft/ Sybase) SQL PL (IBM) An ADA angelehnt Direkte Einbettung von SQL-Statements in Programm Normalerweise statisches SQL Wozu ? Definierte Schnittstelle zum Zugriff auf Daten Wird (nach compile) in der DB gespeichert und dort ausgeführt (Performance) Konsistenz, z.B. direkter Zugriff auf Datentypen in DB User defined functions, z.B. „select finance.AuftragTotal('01-1691/01') from dual;“ Usw. Erstellung von stored procedures usw.

Stored procedure SQL> execute perf_proc create or replace procedure perf_proc as cursor c is select * from lagerbewegung; c_rec c%rowtype; i integer; begin open c; i := 0; fetch c into c_rec; while c%found loop insert into perf(nummer,art,vorgangsnummer,...) values (c_rec.nummer,c_rec.art...); i := i + 1; if ((i mod 1000) = 0) then commit; end if; end loop; close c; end; / SQL> execute perf_proc PL/SQL procedure successfully completed. Elapsed: 00:01:56.90

Java, dynamisches SQL oracle$ java Perftest ResultSet rset = stmt.executeQuery ("select nummer, ... where rownum < 10000"); // Zunächst nur 10.000 records .... while (rset.next ()) { sql = "insert into perf(nummer,art...)" + “values (" + rset.getInt(1) + "," + ...)"; ins.execute(sql); NumberOfRecords++; if ((NumberOfRecords % CommitInterval) == 0) conn.commit(); } oracle$ java Perftest elapsed time: 38.146 seconds für 10.000 records, Entspricht insgesamt (extrapoliert) ca. 11 Minuten

Prepared statement oracle$ java PerftestPrepared PreparedStatement ps = conn.prepareStatement("insert into perf(..., values (?,?,?,?,?,?,?,to_date(?,'yyyy-mm-dd hh24:mi:ss'))"); ResultSet rset = stmt.executeQuery ("select nummer ... "); while (rset.next ()) { ps.setInt(1,rset.getInt(1)); ... ps.execute(); NumberOfRecords++; if ((NumberOfRecords % CommitInterval) == 0) conn.commit(); } oracle$ java PerftestPrepared elapsed time: 17.573 seconds für 10.000 records, Entspricht insgesamt (extrapoliert) ca. 5 Minuten !

Vergleich Technik Dauer Table Copy ohne Transaktion 4 Sekunden Stored procedure 2 Minuten Java mit dynamischem Statement 11 Minuten Java mit prepared statement 5 Minuten

Besser ... (DB-spezifisch) create or replace procedure perf_bulk as type recs is table of lagerbewegung%rowtype; data recs; cursor c is select * from lagerbewegung; i integer; begin open c; loop fetch c bulk collect into data limit 10000; forall i in 1..data.count insert into perf values data(i); commit; exit when c%notfound; end loop; close c; end; SQL> execute perf_bulk PL/SQL procedure successfully completed. Elapsed: 00:00:13.36

NB: Commit-Frequenz Commit alle n records Dauer (sec) 1 1132 (*) 10 384 100 285 1000 280 10000 275 Eine Transaktion 259 (*): möglicherweise phys. Speicher zu klein

Aktive Datenbanken „normale“ Datenbanken speichern Daten Aktive Datenbanken führen Aktionen aus (ECA-Modell) Event Z.B. Änderung von Daten, Zeitpunkt,... Condition Bedingung, unter der Action ausgeführt wird Action

Wozu ? Denormalisierte Relationen Protokollierung Replikation Materialized views Einfache Integritätsbedingungen durch constraints, komplexere ? Business rules Z.B. „Fakturierte Aufträge dürfen nicht geändert werden“

Beispiel (Oracle Trigger) CREATE OR REPLACE TRIGGER TUpdAuftrag BEFORE UPDATE ON Auftrag FOR EACH ROW BEGIN IF ((:old.Status = Globvar.Stat_Auftrag_abgerechnet) AND (USER <> '&1')) THEN Error.raise_error(Error.en_Abgerechnet); END IF; END; CREATE OR REPLACE TRIGGER TDelAuftrag BEFORE DELETE ON Auftrag FOR EACH ROW IF (:old.Status = Globvar.Stat_Auftrag_abgerechnet) THEN