Datenbanken 1. Kapitel 5: Datenbank-Anwendungsprogrammierung

Ähnliche Dokumente
Kapitel 10. JDBC und SQLJ. Prof. Dr. Wolfgang Weber Vorlesung Datenbanken 1

Einbettung in SQL. Zwei Prinzipien: (1) Statische Einbettung

11 Anwendungsprogrammierung

vs. Fehler zur Übersetzungszeit

Grundlagen von Datenbanken SS 2010 Kapitel 8: Datenbank-Einbettung in Programmiersprachen Prof. Dr. Stefan Böttcher Universität Paderborn

Datenbanksysteme I Übung: JDBC. Jana Bauckmann

Prozedurale Datenbank- Anwendungsprogrammierung

Datenbanken. Anwendungsentwicklung in Datenbanken: Prozedurale Spracherweiterung von SQL (z.b. PL/SQL bei Oracle)

Webbasierte Informationssysteme

10 Anwendungsprogrammierung

Kapitel 11: Anwendungsentwicklung

Kapitel 11: Anwendungsentwicklung

Datenbanksysteme I Datenbankprogrammierung Felix Naumann

SQLJ. Standardisierte Java-DB. DB-Schnittstelle. Spezifikationen. Oracle, IBM, Informix, Sybase,, Tandem, Sun, Microsoft stehen dahinter

Kapitel DB:VI (Fortsetzung)

Kapitel 9. Embedded SQL. Prof. Dr. Wolfgang Weber Vorlesung Datenbanken 1

Client/Server-Programmierung

Java: MySQL-Anbindung mit JDBC.

Kapitel 11: Anwendungsentwicklung

JDBC. Java DataBase Connectivity

Kapitel 4 Dynamisches SQL

seit Java 1.1 Bestandteil der API: packages java.sql, javax.sql

Willkommen. Datenbanken und Anbindung

Kapitel 4 Dynamisches SQL

Client/Server-Programmierung

2. Datenbank-Programmierung

Java und Datenbanksysteme Datenbankanbindung mit JDBC

Datenbanksysteme. Programmieren von Datenbankzugriffen mit JDBC. Burkhardt Renz. Fachbereich MNI Technische Hochschule Mittelhessen

DB-Programmierung. Lehr- und Forschungseinheit Datenbanken und Informationssysteme 1. Ziele. DB2 Zugriff mit Java selbst programmieren

Wie kommen die Befehle zum DBMS

Java Database Connectivity-API (JDBC)

Übung Datenbanksysteme I JDBC. Thorsten Papenbrock

Übung Datenbanksysteme I Embedded SQL, Stored Procedures, JDBC

Übung Datenbanksysteme I JDBC. Thorsten Papenbrock

Datenbank und Informationssysteme

Java Database Connectivity-API (JDBC)

SQL. SQL: Structured Query Language. Früherer Name: SEQUEL. Standardisierte Anfragesprache für relationale DBMS: SQL-89, SQL-92, SQL-99

Kapitel DB:VI (Fortsetzung)

1a) SQL Stored Procedure via IDs

JDBC. Es kann z.b. eine ODBC-Treiberverbindung eingerichtet werden, damit das JAVA-Programm auf eine ACCESS-DB zugreifen kann.

Wie kommen die Befehle zum DBMS

Prozedurale SQL-Erweiterungen

Datenbanken SQL JDBC. Programmieren II. Dr. Klaus Höppner. Hochschule Darmstadt Sommersemester / 21

Programmieren II. Beispiele für RDBMS. Relationale Datenbanken. Datenbanken SQL. Dr. Klaus Höppner JDBC. Hochschule Darmstadt SS 2008

Funktionen. Überblick über Stored Functions. Syntax zum Schreiben einer Funktion. Schreiben einer Funktion

Schnellübersichten. SQL Grundlagen und Datenbankdesign

Universität Augsburg, Institut für Informatik WS 2006/2007 Dr. W.-T. Balke 11. Dez M. Endres, A. Huhn, T. Preisinger Lösungsblatt 7

Webbasierte Informationssysteme

Dynamisches SQL. Folien zum Datenbankpraktikum Wintersemester 2009/10 LMU München

Datenbanken 1 für Mediennformatiker WS ODBC, JDBC und SQLJ: Datenbank-Anbindung an Anwendungsprogramme

Datenbanken SQL-Grundlagen JDBC SQL-Constraints. Programmieren II. Martin Schultheiß. Hochschule Darmstadt Sommersemester 2011

Ho Ngoc Duc IFIS - Universität zu Lübeck

Datenbankentwurf & Datenbankzugriff mit JDBC. Georg Köster Sven Wagner-Boysen

Java Database Connectivity-API (JDBC)

Übung Datenbanksysteme I Embedded SQL, Stored Procedures, JDBC

Zugriff auf die Datenbank. Ulf Leser Wissensmanagement in der Bioinformatik

Wiederholung VU Datenmodellierung

Einführung in JDBC. IFIS Universität zu Lübeck

Softwareentwicklung mit JAVA EE

Java Database Connectivity (JDBC) Walther Rathenau Gewerbeschule 1

Teil XI Anwendungsprogrammierung

Datenbankanwendungen (JDBC)

Praktikum Datenbanksysteme

Wiederholung VU Datenmodellierung

Oracle: Abstrakte Datentypen:

JDBC Datenzugriff aus Java ETIS SS04

Übung: Data Warehousing und Data Mining

Datenbanksysteme. Programmieren von Datenbankzugriffen mit JDBC. Burkhardt Renz. Fachbereich MNI Technische Hochschule Mittelhessen

Funktion definieren Gibt Summe der Gehälter zurück. Aufruf in einem SQL-Statement

Datenbankschnittstellen erlauben Zugriff auf Datenbank aus einer externen Anwendung

Das diesem Dokument zugrundeliegende Vorhaben wurde mit Mitteln des Bundesministeriums für Bildung und Forschung unter dem Förderkennzeichen

Die Anweisung create table

WS 2010/11 Datenbanksysteme Fr 15:15 16:45 R Vorlesung #6. SQL (Teil 4)

Universität Stuttgart Abteilung Anwendersoftware Steht für Embedded SQL in Java. - Java-Methoden als SQL Stored-Procedures

12. Programmierung in der Datenbank

Oracle & Java HOW TO

Klausur Datenbanken II

Übung: Data Warehousing und Data Mining

Programmieren II. Relationale Datenbanken. Vorlesung 07. Handout S. 1. Martin Schultheiß. Hochschule Darmstadt Sommersemester 2011.

DBS: Anwendungsprogrammierung

Universität Augsburg, Institut für Informatik WS 2011/2012 Prof. Dr. W. Kießling 09. Dez Dr. M. Endres, Dr. S. Mandl, F. Wenzel Lösungsblatt 6

Datenintegrität. Integitätsbedingungen Schlüssel Beziehungskardinalitäten Attributdomänen Inklusion bei Generalisierung

10. Programmieren in SQL

Praktische SQL-Befehle 2

Musterlösung Übungsblatt 11

Mehr Performance mit JDBC JAVA-Anwendungen und die Oracle-Datenbank. Carsten Czarski Business Unit Database Oracle Deutschland GmbH

Datenbanksysteme 2013

Entwicklungsumgebung für die Laborübung

MySQL mit MyLinux. 2/2003 Java unter Linux

Gruppe A Bitte tragen Sie sofort und leserlich Namen, Studienkennzahl und Matrikelnummer ein und legen Sie Ihren Studentenausweis

Datenintegrität. Kapitel 5 1

Transkript:

Datenbanken 1 Kapitel 5: Datenbank-Anwendungsprogrammierung create or replace trigger keinepreissenkung before update of ProdPreis on Produkt for each row when (:old.prodpreis is not null) begin if :new.prodpreis < :old.prodpreis then :new.prodpreis := :old.prodpreis; dbms_output.put_line ('Preissenkung nicht erlaubt!'); end if; end;

Vorlesung Datenbanken 1 Ausschnitt aus der realen Welt Konzeptuelles Modell (z.b. ER-Modell) Anwendungsprogramm 5 Logisches Modell (z.b. Relationenmodell) DBMS 6 DB Uta Störl Datenbanken 1 WS 2015/16 5-2

Datenbank-Anwendungsprogrammierung Motivation Bisher: DDL- und DML-Befehle, welche ad hoc ausgeführt werden können. Aber: In der Realität werden insbesondere DML-Zugriffe meistens aus Anwendungsprogrammen heraus benötigt. Uta Störl Datenbanken 1 WS 2015/16 5-3

Datenbank-Anwendungsprogrammierung Inhalt des Kapitels Grundprinzipien SQL-Zugriff über APIs (u.a. JDBC) Einbettung von SQL Prozedurale SQL-Erweiterungen Integrität und Trigger Lernziele Kennen und Bewerten verschiedener Varianten der Anwendungsprogrammierung für Datenbanken Anwenden der prozeduralen SQL-Erweiterungen Umsetzung von Integritätsbedingungen mit Triggern Uta Störl Datenbanken 1 WS 2015/16 5-4

Grundprinzipien Wichtige Unterscheidung: Fall 1: Ergebnis der Anfrage höchstens 1 Tupel Fall 2: Ergebnis der Anfrage mehrere Tupel Fall 1: Ergebnis der Anfrage höchstens 1 Tupel Beispiel: Ausgabe von Preis und Namen des Produkts mit der Produktnummer 203. Anwendungsprogramm (C, C++, Java,.NET, C#, PHP ) Datenbank SQL- Anfrage 203 Einlesen in Variablen im Programm (sog. Host-Variablen) Datenbanksystem Uta Störl Datenbanken 1 WS 2015/16 5-5

Grundprinzipien Fall 2: Ergebnis der Anfrage mehrere Tupel Beispiel: Gib für alle Produkte, die teurer als 100 Euro sind, die Produktnummer und den Preis aus. Problem: Unterschiedliche Datenstrukturkonzepte: (imperative) Programmiersprachen: Tupel SQL: Relation, also Menge von Tupeln Impedance mismatch Datenbank SQL- Anfrage Datenbanksystem Uta Störl Datenbanken 1 WS 2015/16 5-6

Grundprinzipien: Cursor-Konzept Cursor-Konzept = Abstrakte Sicht auf eine Relation, realisiert als Liste Anwendungsprogramm (C, C++, Java,.NET, C#, PHP ) Datenbank SQL- Anfrage Datenbanksystem Anfrageergebnisse werden sequentiell abgearbeitet! Uta Störl Datenbanken 1 WS 2015/16 5-7

Cursor-Konzept SQL92 SQL92 bietet neben dem einfachen Weitersetzen des Cursors (fetch) wesentlich erweiterte Möglichkeiten: current position of cursor C prior next relative r from C -2 1-1 2.. 1 2 n-1.. n r absolute n from C Uta Störl Datenbanken 1 WS 2015/16 5-8

Datenbank-Anwendungsprogrammierung Grundprinzipien SQL-Zugriff über APIs Einbettung von SQL Prozedurale SQL-Erweiterungen Integrität und Trigger Uta Störl Datenbanken 1 WS 2015/16 5-9

SQL-Zugriff über APIs SQL/CLI (Call Level Interface) Prozedurale Datenbankschnittstelle für C, C++, Ada, Fortran, Pascal X/Open bzw. ISO-Standard Datenbankhersteller implementieren diesen Standard und bieten spezifische CLIs an (Oracle CI, DB2 CLI etc.) Alternative: Datenbanksystemunabhängige Application Programming Interfaces (APIs) Open Database Connectivity (ODBC) Für Java: Java Database Connectivity (JDBC) Wichtige Eigenschaften von ODBC/JDBC Sehr weite Verbreitung/Unterstützung Dynamischer Zugriff auf (beliebige) Datenquellen Bei Einhaltung des SQL-Standards ist datenbanksystem-unabhängige Programmierung und sogar Zugriff aus einem Programm auf mehrere (unterschiedliche) DBMS möglich Uta Störl Datenbanken 1 WS 2015/16 5-10

JDBC Architektur (grob) DriverManager getconnection Connection createstatement Statement Statement executequery ResultSet ResultSet Java Klassen und Interfaces im Paket java.sql java.sql.drivermanager Laden der Treiber und Aufbau der Verbindung zur Datenbank java.sql.connection ein Connection-Objekt repräsentiert eine Datenbankverbindung java.sql.statement Objekt für die Ausführung von SQL-Anweisungen java.sql.resultset Objekt für die Repräsentation der Ergebnis-Relation der Abfrage Uta Störl Datenbanken 1 WS 2015/16 5-11

JDBC Ablauf 1. Aufbau einer Verbindung zur Datenbank Angabe der Verbindungsinformationen Auswahl und Laden des Treibers 2. Senden einer SQL-Anweisung Definition der Anweisung Belegung von Parametern 3. Verarbeiten der Anfrageergebnisse Navigation über Ergebnisrelation Zugriff auf Spalten Uta Störl Datenbanken 1 WS 2015/16 5-12

JDBC Aufbau einer Verbindung Treiber laden // Treiber laden Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Verbindung herstellen // Aufbau der Verbindung Connection con; String url = "jdbc:odbc:myoracledb"; con = DriverManager.getConnection(url, "user", "passwort"); JDBC-URL spezifiziert Datenquelle/Datenbank Verbindungsmechanismus (Protokoll, Server und Port) Uta Störl Datenbanken 1 WS 2015/16 5-13

JDBC Anfrageausführung Anweisungsobjekt (Statement) erzeugen // Anweisungsobjekt (Statement) erzeugen Statement stmt = con.createstatement (); Anweisung ausführen // Aufbau und Ausführung der Anfrage String retquery = "select ProdNr, ProdName from Produkt"; ResultSet rs = stmt.executequery ( retquery ); Für Retrieval-Operationen (select): executequery Für Einfüge- (insert), Update- (update), Lösch- (delete) und DDL-Operationen (create table, drop table): executeupdate String insquery = "insert into Produkt values (50071, 2Hi4U, 129)"; Statement stmt = con.createstatement (); int numberrows = stmt.executeupdate ( insquery ); Uta Störl Datenbanken 1 WS 2015/16 5-14

JDBC Auswertung des Anfrageergebnis Auswertung des ResultSet: Navigation auf der Ergebnismenge mit einem Cursor Zugriff auf Spalten des ResultSet mit get<type> Methoden Statement stmt = con.createstatement (); String retquery = "select ProdNr, ProdName from Produkt"; ResultSet rs = stmt.executequery ( retquery ); String name; int number; System.out.println( Produkt-Nr Produkt-Name ); try { while (rs.next ()) { number = rs.getint(1); name = rs.getstring("prodname"); System.out.println (number + " " + name); } rs.close(); } catch (SQLException exc) { // Fehlerbehandlung System.out.println("SQL-Fehler: " + exc); } Cursor steht am Anfang VOR dem ersten Tupel Spalten sind von 1 bis n nummeriert; Anfrage über Spaltenindex oder Spaltenname Uta Störl Datenbanken 1 WS 2015/16 5-15

JDBC Nachteile bei der Verwendung der Klasse Statement Bei mehrfacher Ausführung wird das Statement immer wieder neu übersetzt und kompiliert schlecht für Performance Gefahr von SQL-Injection Beispiel für SQL-Injection: String sql = "select * from account where username='" + username + "' and password='" + password + "'"; Statement stmt = con.createstatement(); ResultSet rs = stmt.executequery(sql); if (rs.next()) { Boolean loggedin = true; System.out.println("Successfully logged in"); } else { System.out.println("Username and/or password not recognized"); } Eingabe von username und passwort: abc' OR '1' = '1 führt zu: select * from account where username='abc' OR '1' = '1' and password='abc' OR '1' = '1' Uta Störl Datenbanken 1 WS 2015/16 5-16

JDBC Vorübersetzung von Anfragen: Klasse PreparedStatement Statt Statement sollte PreparedStatement verwendet werden, wenn Anfragen wiederholt ausgeführt werden oder dynamische Benutzereingabe enthalten. String insquery = "insert into Produkt values (?,?,?)"; PreparedStatement stmt = con.preparestatement ( insquery ); int numberrows; while (...) { // Wiederholtes Setzen der Werte nach Eingabe durch Nutzer stmt.setint ( 1, 50071) stmt.setstring ( 2, "2Hi4U"); stmt.setint ( 3, 129); numberrows = stmt.executeupdate ( ); } Uta Störl Datenbanken 1 WS 2015/16 5-17

JDBC PreparedStatement Die Verwendung von PreparedStatement schützt außerdem vor SQL-Injection String sql = "select * from account where username =? and password =?"; PreparedStatement pstmt = con.preparestatement(sql); pstmt.setstring(1, username); pstmt.setstring(2, password); ResultSet rs = pstmt.executequery(); if (rs.next()) { Boolean loggedin = true; System.out.println("Successfully logged in"); } else { System.out.println("Username and/or password not recognized"); } Eingabe von username und passwort: abc' OR '1' = '1 führt zu: select * from account where username = " abc' OR '1' = '1' " and password = " abc' OR '1' = '1' " Uta Störl Datenbanken 1 WS 2015/16 5-18

JDBC Klassen DriverManager getconnection(jdbcparam) Connection createstatement() preparestatement(sql) preparecall(procedurecall) Statement PreparedStatement CallableStatement setxxx(param) setxxx(param) execute Update(SQL) execute Query(SQL) execute Update() execute Query() execute Update() execute Query() registerout Parameter(Param) execute () getxxx(param) ResultSet ResultSet ResultSet Uta Störl Datenbanken 1 WS 2015/16 5-19

JDBC Metadaten Häufig sehr hilfreich: Abfrage der Metadaten des ResultSets (d.h. der Struktur des Anfrageergebnisses) Mehr als 20 verschiedene Methoden u.a. Abfrage der Spaltennamen (getcolumnname) der DBMS-spezifischen Datentypen der Spalten (getcolumntypename) der SQL-Datentypen der Spalten (getcolumntype)... String stmtstring = "select * from " + tabname"; String cname; String dtype; rs = stmt.executequery(stmtstring); ResultSetMetaData rsmdt = rs.getmetadata(); int numbercolumns = rsmdt.getcolumncount(); int i; for (i = 1; i <= numbercolumns; i++) { String cname = rsmdt.getcolumnname(i); String dtype = rsmdt.getcolumntypename(i); System.out.println(" Name: " + cname + " Datentyp: " + dtype); }; Uta Störl Datenbanken 1 WS 2015/16 5-20

JDBC Treibertypen Java Applikation JDBC API JDBC Driver Manager JDBC- ODBC- Bridge Native API- Treiber JDBC- Net- Treiber Native Protokoll -Treiber ODBC Client- Bibliothek DB-Middleware Client- Bibliothek Typ 1: JDBC-ODBC-Bridge - nutzt ODBC-Treiber Typ 2: Native-API-Treiber - nutzt DBMS-spezifische APIs Typ 3: JDBC-Net-Treiber - nutzt DBMS-unabhängige Middleware Typ 4: Native Protokoll-Treiber - nutzt DBMS-spezifisches Protokoll Uta Störl Datenbanken 1 WS 2015/16 5-21

Verwendung von JDBC-Treibern Beispiele für Oracle: JDBC-ODBC-Treiber vorab ODBC-Datenquelle mit Namen MyOracleDB für Datenbank DBPrak definiert // JDBC-ODBC-Treiber Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection con; String url = "jdbc:odbc:myoracledb"; con = DriverManager.getConnection(url, "user", "passwort"); JDBC-Treiber Type 4 Oracle-JDBC-Treiber ojdbc14.jar in Build-Path einbinden (als Library o.ä.) // JDBC Type 4 Treiber (JDBC 3.0) Class.forName("oracle.jdbc.OracleDriver"); Connection con; String url = "jdbc:oracle:thin:@//localhost:1521/dbprak"; con = DriverManager.getConnection(url, "user", "passwort"); Uta Störl Datenbanken 1 WS 2015/16 5-22

Eigenschaften SQL über API (z.b. JDBC) Vorteile Ermöglicht (weitgehend) datenbanksystemunabhängige Programmierung Flexibel (SQL-Statements können dynamisch zur Laufzeit festgelegt werden) Nachteile Keine Syntax- und Typüberprüfung zur Übersetzungszeit Keine Vorübersetzung im Programm möglich (schlecht für Performance) Alternative: Einbettung von SQL in Programmiersprache (Embedded SQL) Uta Störl Datenbanken 1 WS 2015/16 5-23

Datenbank-Anwendungsprogrammierung Grundprinzipien SQL-Zugriff über APIs Einbettung von SQL Prozedurale SQL-Erweiterungen Integrität und Trigger Uta Störl Datenbanken 1 WS 2015/16 5-24

Einbettung von SQL / Embedded SQL Prinzip Vorübersetzer-Prinzip (Pre-Compiler/Translator) In Programmcode (z.b. C, C++, Java, ) integrierte SQL- Anweisungen werden durch den Pre-Compiler übersetzt, d.h. in Prozeduraufrufe der Wirtssprache übersetzt Anschließend Übersetzung durch Compiler Quelle: Oracle Database Online Documentation 11g: 2015 Uta Störl Datenbanken 1 WS 2015/16 5-25

Embedded SQL für Java SQL/OLB (früher: SQLJ) = Embedded SQL für Java 1997 vorgeschlagen von IBM, Oracle, Sybase, Informix und Sun; Bestandteil von SQL:1999 nochmals überarbeiten in SQL:2000 und SQL:2002 Direkte Einbettung von SQL-Anweisungen in Java Code (= Embedded SQL für Java) SQLJ-Anweisungen werden mittels Pre-Compiler (Translator) in Java- Code übersetzt Spezifikation besteht aus ISO/IEC 9075-10:2000, Information technology Database languages SQL Part 10: Object Language Bindings (SQL/OLB) ISO/IEC 9075-13:2002, Information technology Database languages SQL Part 13: SQL Routines and Types Using the Java Programming Language (SQL/JRT). Uta Störl Datenbanken 1 WS 2015/16 5-26

Embedded SQL für Java SQL/OLB (SQLJ) Eingebettete SQL-Anweisungen werden durch #sql gekennzeichnet: Ergebnis-Tupel können mit einem Iterator durchlaufen werden (vgl. Cursor)... Deklaration des Iterators (Cursors) try { #sql iterator PrdItr (int nummer, int preis); #sql PrdItr = { select ProdNr, ProdPreis from Produkt }; while (PrdItr.next ()) Instanziierung des Iterators (Cursors) { System.out.println (PrdItr.nummer() + " " + PrdItr.preis()); } PrdItr.close(); } catch (SQLException exc) { // Fehlerbehandlung System.out.println("SQL-Fehler: " + exc); } Bereits beim Kompilieren kann die SQL-Syntax überprüft werden! Bereits beim Kompilieren kann ein Anfrageplan in der Datenbank berechnet und abgelegt! Uta Störl Datenbanken 1 WS 2015/16 5-27

JDBC vs. SQLJ Statement stmt = con.createstatement (); String retquery = "select ProdNr, ProdName from Produkt";... ResultSet rs = stmt.executequery(retquery); while (rs.next ()) { i = rs.getint("prodname"); s = rs.getstring("prodname"); System.out.println(i + " " + s); } rs.close();... stmt.close(); #sql iterator PrdItr (int nummer, int preis); #sql PrdItr = {select ProdNr, ProdPreis from Produkt};... while (PrdItr.next ()) { i = PrdItr.nummer(); p = PrdItr.preis(); System.out.println(i + " " + s); } PrdItr.close(); Uta Störl Datenbanken 1 WS 2015/16 5-28

SQL über API vs. Eingebettetes SQL SQL über API (z.b. JDBC) Eingebettetes SQL (z.b. SQL/OLB = SQLJ) Vorteile Flexibel (SQL-Statements können dynamisch zur Laufzeit festgelegt werden) Vorteile Syntax- und Typüberprüfung zur Übersetzungszeit Vorübersetzung möglich (gut für Performance) Nachteile Keine Syntax- und Typüberprüfung zur Übersetzungszeit Keine Vorübersetzung möglich (schlecht für Performance) Nachteile Geringe Flexibilität (Operationen müssen zur Übersetzungszeit feststehen) Uta Störl Datenbanken 1 WS 2015/16 5-29

Datenbank-Anwendungsprogrammierung Grundprinzipien SQL-Zugriff über APIs Einbettung von SQL Prozedurale SQL-Erweiterungen Integrität und Trigger Uta Störl Datenbanken 1 WS 2015/16 5-30

Eingebettetes SQL: Limitationen Abarbeitungskontrolle zwischen Anwendungsprogramm (Wirtssprache) und DBMS wird auf sehr kleinen Granularitäten hin- und hergeschaltet Anfrageoptimierung durch das DBSM nur für einzelne Anweisung möglich (kritisch für die Performance der Programme!) Lösungsansatz Erweiterung von SQL um Ablaufkonstrukte wie Sequenz, bedingte Ausführung und Schleifen: Prozedurale SQL-Erweiterungen Proprietär schon früh von DBMS-Herstellern angeboten (z.b. Oracle: PL/SQL) Standardisierung erst in SQL-99 eingeführt Uta Störl Datenbanken 1 WS 2015/16 5-31

Prozedurales SQL Aufbau Oracle declare <Datendeklaration> begin <PL/SQL-Code> exception <PL/SQL-Code> end; / declare cursor CurProd is select ProdNr, ProdPreis from Produkt; ProdRecord CurProd%rowtype; Uta Störl Datenbanken 1 WS 2015/16 5-32

Oracle Prozedurales SQL Operationale Konstrukte if <Bedingung> then <PL/SQL-Anweisungen>; [ else <PL/SQL-Anweisungen>; ] end if; for <IndexVariable> in <EndlicherBereich> loop <PL/SQL-Anweisungen>; end loop; while <Bedingungsvariable> loop <PL/SQL-Anweisungen>; end loop; Uta Störl Datenbanken 1 WS 2015/16 5-33

Prozedurales SQL Cursor-Iteration Oracle declare cursor CurProd is select ProdNr, ProdPreis from Produkt; ProdRecord CurProd%rowtype; begin open CurProd; fetch CurProd into ProdRecord; while CurProd%found loop dbms_output.put_line (ProdRecord.ProdNr ProdRecord.ProdPreis); fetch CurProd into ProdRecord; end loop; close CurProd; end; Für die sequentielle Abarbeitung eines Cursors existiert eine verkürzte Schreibweise, ohne explizites Öffnen, zeilenweise Lesen und Schließen des Cursor (open, fetch, close):... begin for ProdRecord in CurProd loop dbms_output.put_line (ProdRecord.ProdNr ProdRecord.ProdPreis); end loop; end; Uta Störl Datenbanken 1 WS 2015/16 5-34

Oracle Prozedurales SQL Beispiel mit Update declare cursor CurProd is select ProdNr, ProdPreis from Produkt for update of ProdPreis; ProdRecord CurProd%rowtype; begin for ProdRecord in CurProd loop dbms_output.put_line (ProdRecord.ProdNr ProdRecord.ProdPreis); if ProdRecord.ProdPreis < 100 then update Produkt set ProdPreis = ProdPreis*1.1 where current of CurProd; else update Produkt set ProdPreis = ProdPreis*1.2 where current of CurProd; end if; end loop; end; / Uta Störl Datenbanken 1 WS 2015/16 5-35

Prozedurales SQL ohne Cursor Oracle Spezialfall: Ergebnis der Anfrage höchstens 1 Tupel Kein Cursor notwendig (und dann auch nicht sinnvoll!) Einlesen der Ergebnisse in Host-Variablen mit into Beispiel: Ausgabe des Preises für das Produkt mit der Produktnummer 203. declare preis Produkt.ProdPreis%type; begin select ProdPreis into preis from Produkt where ProdNr = 203; dbms_output.put_line('preis: ' preis); end; / Uta Störl Datenbanken 1 WS 2015/16 5-36

Funktionen und Prozeduren Oracle Nahe liegende Erweiterung zur Strukturierung und Modularisierung: Definition von Funktionen und Prozeduren function FunktionsName ( Param1 ParamTyp1,..., ParamN ParamTypN ) return ErgebnisTyp is < Deklarationsteil o h n e Schlüsselwort declare > begin <PL/SQL-Anweisungen mit return-anweisung>; end; / procedure ProzedurName ( Param1 [ in out in out ] ParamTyp1,... ) is < Deklarationsteil o h n e Schlüsselwort declare > begin <PL/SQL-Anweisungen>; end; / Uta Störl Datenbanken 1 WS 2015/16 5-37

Stored Procedures Oracle Funktionen und Prozeduren können auch dauerhaft auf dem DB-Server gespeichert werden: create [ or replace ] function FunktionsName ( Param1 ParamTyp1,..., ParamN ParamTypN ) return ErgebnisTyp is < Deklarationsteil o h n e Schlüsselwort declare > begin <PL/SQL-Anweisungen mit return-anweisung>; end; / create [ or replace ] procedure ProzedurName ( Param1 [ in out in out ] ParamTyp1,... ) is < Deklarationsteil o h n e Schlüsselwort declare > begin <PL/SQL-Anweisungen>; end; / Uta Störl Datenbanken 1 WS 2015/16 5-38

Stored Procedures Beispiel Oracle create or replace procedure PreisUpdate (preis1 in decimal, preis2 in decimal) is cursor CurProd is select ProdNr, ProdPreis from Produkt for update of ProdPreis; ProdRecord CurProd%rowtype; begin for ProdRecord in CurProd loop dbms_output.put_line (ProdRecord.ProdNr ProdRecord.ProdPreis); if ProdRecord.ProdPreis < 100 then update Produkt set ProdPreis = ProdPreis*preis1 where current of CurProd; else update Produkt set ProdPreis = ProdPreis*preis2 where current of CurProd; end; / end if; end loop; Aufruf im Programm: PreisUpdate (1.1, 1.2); bzw. interaktiv: execute PreisUpdate (1.1, 1.2); Uta Störl Datenbanken 1 WS 2015/16 5-39

Stored Procedures können auch aus Programmen heraus aufgerufen werden DriverManager JDBC-Klassen getconnection(jdbcparam) Connection createstatement() preparestatement(sql) preparecall(procedurecall) Statement PreparedStatement CallableStatement setxxx(param) setxxx(param) execute Update(SQL) execute Query(SQL) execute Update() execute Query() execute Update() execute Query() registerout Parameter(Param) execute () getxxx(param) ResultSet ResultSet ResultSet Uta Störl Datenbanken 1 WS 2015/16 5-40

Übung zu Stored Procedures Vorbemerkung: In Stored Procedures können nicht nur DML- sondern auch DDL-Befehle ausgeführt werden; diese müssen mit dem Schlüsselwort execute immediate eingeleitet werden:... execute immediate 'drop table verlag' ;... Übung: Schreiben Sie eine Stored Procedure, die alle Tabellen einer Datenbank löscht. Uta Störl Datenbanken 1 WS 2015/16 5-41

Stored Procedures Bewertung Funktionen und Prozeduren sind ein wichtiges und bewährtes Strukturierungsmittel für Anwendungen (darüber hinaus können mehrere Funktionen und Prozeduren in Pakete gruppiert werden). Vermeidung von Redundanz relevante Funktionalität kann für verschiedene Anwendungen durch das DBMS bereitgestellt werden. Funktionen und Prozeduren sind in der Sprache des DBMS geschrieben sind und können deshalb durch dieses (unabhängig von der Wirtssprache) optimiert werden! Ausführung von Stored Procedures vollständig unter Kontrolle des DBMS geringere Netzwerkbelastung in Client-/Server-Architekturen. Stored Procedures können zur Integritätssicherung eingesetzt werden (Stichwort: Trigger - siehe nächster Abschnitt). Uta Störl Datenbanken 1 WS 2015/16 5-42

Datenbank-Anwendungsprogrammierung Grundprinzipien SQL-Zugriff über APIs Einbettung von SQL Prozedurale SQL-Erweiterungen Integrität und Trigger Uta Störl Datenbanken 1 WS 2015/16 5-43

Semantische Integritätsbedingungen Semantische Integritätsbedingungen = Integritätsbedingungen, die aus der Modellierung der Miniwelt abgeleitet werden Beispiele Für jedes Produkt muss es eine eindeutige Produktnummer geben. Nur existierende Produkte dürfen in einer Rechnungsposition auftauchen. Für jede Rechnung muss ein Datum eingetragen sein. Der Produktpreis beträgt mindestens 10 Euro. Bei einer Veränderung des Preises ist eine Preissenkung nicht zulässig. PRODNR PRODNAME PRODPREIS PRODUKT INTEGER VARCHAR2(15) INTEGER <pk> PRODNR = PRODNR RNR POSITIONSNR PRODNR ANZAHL POSITION INTEGER INTEGER INTEGER INTEGER <pk,fk1> <pk> <fk2> RNR = RNR RNR DATUM GESPREIS RECHNUNG INTEGER DATE INTEGER <pk> Uta Störl Datenbanken 1 WS 2015/16 5-44

Umsetzung in SQL Für jedes Produkt muss es eine eindeutige Produktnummer geben. create table Produkt ( ProdNr integer constraint PK_Produkt primary key,... ) Eindeutigkeit für Nicht-Primärschlüsselattribute: ProdName varchar(15) constraint U_Produkt unique, Nur existierende Produkte dürfen in einer Rechnungsposition auftauchen. create table Position ( RNr integer PositionsNr integer, ProdNr integer,... constraint PK_Pos primary key ( RNr, PositionsNr ), constraint FK_Pos_Prod foreign key ( ProdNr ) references Produkt (ProdNr),... ) Uta Störl Datenbanken 1 WS 2015/16 5-45

Umsetzung in SQL Für jede Rechnung muss ein Datum eingetragen sein. create table Rechnung ( RNr integer constraint PK_Rechnung primary key, Datum date not null,... ) Der Produktpreis beträgt mindestens 10 Euro. create table Produkt ( ProdNr integer constraint PK_Produkt primary key, ProdPreis integer constraint Min_Preis check (ProdPreis >= 10);... ) Bei einer Veränderung des Preises ist eine Preissenkung nicht zulässig. Uta Störl Datenbanken 1 WS 2015/16 5-46

Umsetzung in SQL Bei einer Veränderung des Preises ist eine Preissenkung nicht zulässig. Dynamische Integritätsbedingung können durch Trigger realisiert werden Ein Trigger ist eine Folge benutzerdefinierter Anweisungen, die automatisch beim Vorliegen bestimmter Bedingungen (u.a. Einfügen, Update, Löschen) vom DBMS gestartet werden. Trigger wurden leider noch nicht in SQL-92 sondern erst in SQL-99 standardisiert Teilweise unterschiedliche Syntax in verschiedenen DBMS Uta Störl Datenbanken 1 WS 2015/16 5-47

Trigger Beispiel Oracle Bei einer Veränderung des Preises ist eine Preissenkung nicht zulässig. -- Definition eines Trigger-Namens create or replace trigger keinepreissenkung -- Ausführungszeitpunkt before update of ProdPreis on Produkt -- einmal für jede betroffene Zeile ausführen for each row -- einschränkende Bedingung when (:old.prodpreis is not null) begin -- Zugriff auf alten bzw. neuen Wert mit :new bzw. :old if :new.prodpreis < :old.prodpreis then :new.prodpreis := :old.prodpreis; dbms_output.put_line ('Preissenkung nicht erlaubt!'); end if; end; / Uta Störl Datenbanken 1 WS 2015/16 5-48

Aufbau eines Triggers Oracle create trigger <Triggername> before after Name des Triggers Ausführungszeitpunkt [ insert delete Spezifikation update [ of <spalte1,...> ]] der auslösenden [ or insert ] Ereignisse on <Tabellenname> [ for each row ] Ausführung für alle betroffenen Zeilen (sonst nur einmal für ganze Tabelle) [ when <Bedingung> ] einschränkende Bedingung [ declare <Deklarationen> ] ggf. Variablendeklarationen begin <Proz. SQL-Anweisungen> Anweisungen end; / :old.<spalte> :new.<spalte> alter Zustand des Tupel (bei delete und update) neuer Zustand des Tupel (bei insert und update) Uta Störl Datenbanken 1 WS 2015/16 5-49

Trigger-Beispiel mit Fehlerbehandlung Eingabe oder Änderung eines Verkaufsdatensatzes soll nur in einem bestimmten Zeitfenster möglich sein: create or replace trigger verkauf_aktualisierung before insert or update on verkauf -- Deklaration der Exception declare Eingabe_nicht_zulaessig exception; Oracle begin if to_char(sysdate, 'HH:MM') not between '08:00' and '17:00' then raise Eingabe_nicht_zulaessig; end if; -- Behandlung der Exception exception when Eingabe_nicht_zulaessig then raise_application_error (-20001, 'Nur zwischen 8:00 und 17:00 Uhr Daten eingeben! '); end; Uta Störl Datenbanken 1 WS 2015/16 5-50

Trigger-Beispiel 1(3) PRODUKT POSITION RECHNUNG PRODNR PRODNAME PRODPREIS INTEGER VARCHAR2(15) INTEGER <pk> PRODNR = PRODNR RNR POSITIONSNR PRODNR ANZAHL INTEGER INTEGER INTEGER INTEGER <pk,fk1> <pk> <fk2> RNR = RNR RNR DATUM GESPREIS INTEGER DATE INTEGER <pk> Beim Hinzufügen einer Rechnungsposition soll der Gesamtpreis der Rechnung aktualisiert werden. Uta Störl Datenbanken 1 WS 2015/16 5-51

Trigger-Beispiel 2(3) Oracle PRODUKT POSITION RECHNUNG PRODNR PRODNAME PRODPREIS INTEGER VARCHAR2(15) INTEGER <pk> PRODNR = PRODNR RNR POSITIONSNR PRODNR ANZAHL INTEGER INTEGER INTEGER INTEGER <pk,fk1> <pk> <fk2> RNR = RNR RNR DATUM GESPREIS INTEGER DATE INTEGER <pk> 1. Lösungsvariante: Berechnung innerhalb des Triggers create or replace trigger PositionInsertTrigger after insert on Position for each row declare aktpreis Produkt.ProdPreis%type; begin select ProdPreis into aktpreis from Produkt where ProdNr = :new.prodnr; update Rechnung set GesPreis = GesPreis + aktpreis * :new.anzahl where RNr = :new.rnr; dbms_output.put_line('aktualisierung ausgeführt'); end; / Uta Störl Datenbanken 1 WS 2015/16 5-52

Trigger-Beispiel 3(3) Oracle 2. Lösungsvariante: Berechnung in separater Stored Procedure: create or replace procedure setgespreis (aktrnr in integer, aktpnr in integer, aktanzahl in integer) is aktpreis Produkt.ProdPreis%type; begin select ProdPreis into aktpreis from Produkt where ProdNr = aktpnr; update Rechnung set GesPreis = GesPreis + aktpreis*aktanzahl where RNr = aktrnr; end; / Wiederverwendung: Wie sieht der entsprechende delete-trigger bzw. update-trigger aus? create or replace trigger PositionInsertTrigger after insert on Position for each row begin setgespreis (:new.rnr, :new.prodnr, :new.anzahl); end; / Uta Störl Datenbanken 1 WS 2015/16 5-53

Übung zu Triggern Beim Einfügen einer Rechnung soll automatisch eine Rechnungsnummer generiert werden. Diese soll um 1 größer sein, als die letzte vergebene Rechnungsnummer. Allgemeiner Anwendungsfall: Erzeugen eines künstlichen, sequentiellen Primärschlüssels. Uta Störl Datenbanken 1 WS 2015/16 5-54

Datenbank-Anwendungsprogrammierung Grundprinzipien SQL-Zugriff über APIs Einbettung von SQL Prozedurale SQL-Erweiterungen Integrität und Trigger Uta Störl Datenbanken 1 WS 2015/16 5-55

Vorlesung Datenbanken Ausschnitt aus der realen Welt Konzeptuelles Modell (z.b. ER-Modell) Anwendungsprogramm Logisches Modell (z.b. Relationenmodell) DBMS 6 DB Uta Störl Datenbanken 1 WS 2015/16 5-56