Universität Augsburg, Institut für Informatik WS 2006/2007 Dr. W.-T. Balke 11. Dez. 2006 M. Endres, A. Huhn, T. Preisinger Lösungsblatt 7 Aufgabe 2 + 3: Datenbanksysteme I import java.sql.*; import oracle.jdbc.driver.*; import java.text.*; // fuer SimpleDateFormat // Fuer die Datenbankverbindung muessen USER und PWD // entsprechend Ihrer Matrikelnummer angepasst werden // Mit // javac -cp.;oracle10gjdbcjar.jar DBConnection.java // koennen Sie das Programm uebersetzen und mit // java -cp.;oracle10gjdbcjar.jar DBConnection // ausfuehren public class mydbconnection { // Statement und Connection private Statement stmt; private Connection con; // USER und PWD muessen Ihrem Login angepasst werden private String USER="USER"; private String PWD="PWD"; private String URL="jdbc:oracle:thin:@info-dbis-srv1." + "informatik.uni-augsburg.de:1521:dbs1"; // *** Aufgabe 2a // ctor public mydbconnection() throws SQLException { // Laden des Oracle-Treibers DriverManager.registerDriver( new oracle.jdbc.driver.oracledriver()); // Datenbankverbindung oeffnen con = DriverManager.getConnection(URL,USER,PWD); // Datenbankverbindung schlieszen public void close() throws SQLException { con.close(); 1
// *** Aufgabe 2b // erstellen der Relationen public void createrelations() throws SQLException { // Vorstellung String v = "create table vorstellung(" + "Name varchar(100) primary key," + "Datum Date not null, Uhrzeit Timestamp not null)"; // Buchung // Als Tabellenname wurde kbuchung // anstelle von Buchung verwendet String b = "create table kbuchung(name varchar(100) " + "primary key references vorstellung," + "Sitzplaetze_Max integer not null, " + "Sitzplaetze_Gebucht integer default 0)"; // zyklischer Fremdschluessel String z = "alter table vorstellung add constraint VBFK" + " foreign key (Name) references kbuchung(name)" + " DEFERRABLE"; // Transaktion, AutoCommit auf false setzen con.setautocommit(false); stmt.executeupdate(v); stmt.executeupdate(b); stmt.executeupdate(z); con.commit(); // Transaktion beenden catch (SQLException e) { con.rollback(); // im Fehlerfall rollback throw e; // Exception finally { con.setautocommit(true); 2
// Aufgabe 2c // Einfuegen der Tupel in die Relationen // java.sql.date unterscheidet sich von java.util.date public void insertvalues(string Name, java.sql.date Datum, java.sql.time Uhrzeit, int Sitzplaetze_Max, int Sitzplaetze_Gebucht) throws SQLException { // Statement fuer insert into Vorstellung // Verwendung von PreparedStatement um // das Datum als Date verarbeiten zu koennen PreparedStatement insv = con.preparestatement("insert into " + "vorstellung values(?,?,?)" ); insv.setstring(1,name); insv.setdate(2,datum); insv.settime(3,uhrzeit); // Statement fuer insert into Buchung // PreparedStatement nicht notwendig String insb = "insert into kbuchung values( " + Name + "," + Sitzplaetze_Max + "," + Sitzplaetze_Gebucht + ")"; // Transaktion con.setautocommit(false); // Constraints auf deferred setzen, //also bis zum commit hinauszoegern stmt.executeupdate("set CONSTRAINTS VBFK DEFERRED"); // PreparedStatement ausfuehren insv.executeupdate(); stmt.executeupdate(insb); // Constraints muessen ab jetzt wieder beachtet werden stmt.executeupdate("set CONSTRAINTS VBFK IMMEDIATE"); con.commit(); // Transaktion beenden catch (SQLException e) { con.rollback(); // bei Exception rollback throw e; finally { // zum Schlusz noch ein wenig aufraeumen con.setautocommit(true); 3
// Aufgabe 2d // Loeschen einer Vorstellung aus den Relationen public void deleteshow(string name) throws SQLException { String delv = "delete from vorstellung where name= " + name + " "; String delb = "delete from kbuchung where name= " + name + " "; // Transaktion wichtig! con.setautocommit(false); // autocommit false // zunaechst die Constraints ausschalten stmt.executeupdate("set CONSTRAINTS VBFK DEFERRED"); stmt.executeupdate(delb); stmt.executeupdate(delv); // Constraints muessen ab jetzt wieder beachtet werden stmt.executeupdate("set CONSTRAINTS VBFK IMMEDIATE"); con.commit(); // Transaktion committen catch (SQLException e) { con.rollback(); // bei Fehlerfall rollback throw e; // finally { // zum Schluss... con.setautocommit(true); 4
// Aufgabe 3a // Alle Vorstellungsnamen zurueckgeben public String[] getshownames() throws SQLException { String q = "select name from vorstellung"; ResultSet rs; // createstatement mit // TYPE_SCROLL_INSENSITIVE und CONCUR_READ_ONLY // Mit TYPE_SCROLL_INSENSITIVE kann durch // das ResultSet gesprungen werden // wird gebraucht um die Anzahl der // Vorstellungen zu ermitteln // Auch moeglich: select count(*)... // Man koennte statt String[] natuerlich // auch Vector oder aehnliches verwenden stmt = con.createstatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); rs = stmt.executequery(q); System.out.println("FetchSize = " + rs.getfetchsize()); // Anzahl der Zeilen ermitteln rs.last(); String names[] = new String[rs.getRow()]; // wieder an den Anfang springen, // sonst kann man das ResultSet nicht durchlaufen rs.beforefirst(); int c=0; while(rs.next()) names[c++] = rs.getstring("name"); // und wieder aufraeumen rs.close(); return names; 5
// Aufgabe 3b // Anzahl der freien Plaetze ermitteln public int getfreeseats(string name) throws SQLException { ResultSet rs; // freie Plaetze = max. Anzahl Plaetze - gebuchte Plaetze String s = "select Sitzplaetze_Max, Sitzplaetze_Gebucht " + "from kbuchung where name= " + name + " "; int seats_max = 0; int seats_booked = 0; // Query absetzen rs = stmt.executequery(s); // falls es ein Ergebnis gibt if(rs.next()) { seats_max = rs.getint("sitzplaetze_max"); seats_booked = rs.getint("sitzplaetze_gebucht"); // das uebliche rs.close(); return seats_max - seats_booked; // Aufgabe 3c // Sitzplaetze buchen public boolean bookseats(string v_name, int nr) throws SQLException { con.setautocommit(false); // falls noch genuegend Plaetze frei sind if(getfreeseats(v_name) < nr) { return false; // else // update statement String s = "update kbuchung set Sitzplaetze_Gebucht = " + nr + " + (select Sitzplaetze_Gebucht" + " from kbuchung where name = " + v_name + " )" + " where name = " + v_name + " "; 6
stmt.executeupdate(s); con.commit(); catch (SQLException e) { con.rollback(); throw e; finally { con.setautocommit(true); return true; // Aufgabe 3d // Datum und Zeit // als Rueckgabetyp verwenden wir Object, // da ein Date (Datum) und ein String (Uhrzeit) // zurueckgegeben wird // Eine innere Klasse mit oeffentlichen Attributen // Date und Timestamp koennte hier auch als // Rueckgabetyp Verwendung finden public Object[] getdateandtime(string name) throws SQLException { ResultSet rs; String s = "select datum, uhrzeit from " + "vorstellung where name= " + name + " "; Object data[] = new Object[2]; rs = stmt.executequery(s); if(rs.next()) { data[0] = rs.getdate("datum"); data[1] = rs.gettime("uhrzeit"); // aufraeumen rs.close(); return data; // Anzahl der gebuchten Sitzplaetze auf 0 setzen public boolean setbookedseats2zero(string name) throws SQLException { 7
// SQL Statement String del = "update kbuchung set " + "Sitzplaetze_Gebucht = 0 where name= " + name + " "; // wenn nicht genau ein Tupel // geaendert wurde ist was schief gegangen if(stmt.executeupdate(del)!= 1) return false; return true; catch (SQLException e) { con.rollback(); throw e; finally { // aufraeumen // main public static void main(string args[]) { // Instanz erzeugen mydbconnection dbcon = new mydbconnection(); // *** Aufgabe 2e // erstellen der Relationen // wenn was schiefgeht wird eine Exception geworfen dbcon.createrelations(); // einfuegen der Tupel // Date(int,int,int) deprecated // aber fuer diese kleine Anwendung reichts noch // Achtung: In Java werden die Monate von 0 bis 11 gezaehlt, // die Jahre seit 1900 und die Tage ab 1 // GregorianCalender waere fuer das Datum besser geeignet dbcon.insertvalues("schneewittchen", new java.sql.date(105,11,23), new java.sql.time(15,0,0), 80, 23); dbcon.insertvalues("aschenputtel", new java.sql.date(106,0,6), new java.sql.time(19,0,0), 100, 20); dbcon.insertvalues("dornroeschen", new java.sql.date(106,0,11), new java.sql.time(17,0,0), 60, 30); dbcon.insertvalues("db1-klausur", 8
new java.sql.date(107,1,9), new java.sql.time(15,0,0), 255, 0); // Aufgabe 3a // alle Vorstellungsnamen holen String[] s = dbcon.getshownames(); // ausgeben System.out.println("Namen der Vorstellungen:"); for(int i=0;i<s.length;i++) System.out.println(s[i]); // Aufgabe 3b // Anzahl der freien Sitzplaetze // fuer die Aschenputtel-Vorstellung System.out.println("\n#freie Sitzplaetze " + "fuer Aschenputtel:" + dbcon.getfreeseats("aschenputtel")); // Aufgabe 3c if(!dbcon.bookseats("dornroeschen",2)) System.out.println("Anzahl freier " + "Sitzplaetze ueberschritten"); Object data[] = dbcon.getdateandtime("db1-klausur"); // das richtige Format fuer das Datum SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy"); // Ausgabe von Datum und Uhrzeit System.out.println("\nDatum DB1-Klausur: " + df.format((java.sql.date)data[0]) + " Uhrzeit = " + data[1].tostring()); catch(sqlexception e) { System.out.println("error: " + e.getmessage()); e.printstacktrace(); 9