Zur praktischen Anwendung der Kenntnisse, die in diesem Kapitel vermittelt wurden, werden nun die Grundlagen der JDBC-Datenbanktechnik anhand eines Beispiels betrachtet. Es sei darauf hingewiesen, dass dieses Beispiel das DBMS Access der Firma Microsoft verwendet. Um andere Datenbanken zu verwenden, muss lediglich der JDBC-ODBC-Treiber in der folgenden Zeile auf den gewünschten Treibertyp umgestellt werden. Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver"); Das hier betrachtete Beispiel ist eine Java-Anwendung, die lokal auf dem Rechner eines Clients ausgeführt wird. Im Einzelnen werden die folgenden Aufgaben wahrgenommen: Laden eines JDBC-Treibers und Herstellung einer Verbindung zur Datenbank. Löschen einer in der Datenbank vorhandenen Tabelle und anschließende Erzeugung einer neuen Tabelle. Hinzufügen von Datensätzen zur erzeugten Tabelle. Versenden einer Anfrage an die Datenbank, um den Inhalt der Tabelle zu ermitteln, bzw. um einige Datensätze zu löschen. Dabei wird sowohl von Statement-Objekten als auch von PreparedStatement-Objekten Gebrauch gemacht. Abfrage und Anzeige der verschiedenen Metadaten der Tabelle. Schließen der Datenbankverbindung. Um das Beispiel fehlerfrei ausführen zu können, muss im ersten Schritt der JDBC-ODBC-Treiber für die Datenbank installiert werden. Das geschieht unter Windows, indem die folgenden Schritte durchgeführt werden: Anlegen eines Verzeichnisses für die Datenbank. Verwendung der Datenbank openjava.mdb, die Teil der CD ist, die dem Buch beiliegt. Doppelklicken des Icons ODBC (32-bit ODBC) in der Systemsteuerung. Hierdurch öffnet sich ein Fenster mit dem Titel ODBC-Datenquellen-Administrator. Auswahl des Buttons Hinzufügen, um einen Treiber für die gewünschte Datenbank auswählen zu können. Eingabe des Namens der Datenquelle, in diesem Beispiel openjava. Angabe der Datenbank, wobei das angelegte Verzeichnis ausgewählt werden muss. Auswahl des JDBC-ODBC-Treibers für die gewünschte Datenbank, indem der OK-Button betätigt wird. Wie in allen weiteren Kapiteln dieses Buches auch wird der Java-Code dieses Beispiels im Folgenden Schritt für Schritt durchgegangen. Setzt man die Code-Segmente wieder zusammen, so erhält man das übersetzungsfähige Programm. import java.sql.*; // Klassendefinition class OpenJavaDB { static String query_str; // fuer die Abfrage static ResultSet mein_ergebnis; // Ergebnissatz static Integer spieler_nummer; // fuer die Spielernummer static String spieler_vorname; // fuer den Spielervornamen static String spieler_name; // fuer den Spielernachnamen // Anzahl gespielter Runden static Integer spieler_gespielt; Zunächst werden die Komponenten des Packages java.sql importiert, zu denen die Klassen Connection, DriverManager, Statement, PreparedStatement, ResultSet, DataBaseMetaData und SQLException gehören, die im Laufe dieses Beispiels benötigt werden. Anschließend werden einige statische Variablen definiert, anhand derer Anfragen gesendet und Ergebnisse bearbeitet werden können. public static void main(String args[]) { // Programminformationen ausgeben: System.out.println(); System.out.println("--openjava----openjava----openja va----openjava----openjava----openjava--"); System.out.println(" "); System.out.println(); System.out.println("Programm: OpenJavaDB "); System.out.println("Zweck: Erzeugt eine Tabelle für eine MS-Access-Datenbank "); System.out.println("Version: 1.0 "); System.out.println("Erstellt am: 06.04.99 "); System.out.println(" "); System.out.println(); System.out.println("--openjava----openjava----openja va----openjava----openjava----openjava--"); System.out.println(); System.out.println(); Die main-Methode wird ohne Argumente aufgerufen. Man könnte das Programm auch mit Argumenten aufrufen, um bspw. ein Passwort und eine Benutzeridentifikation zu übergeben. Zweck der oben dargestellten Zeilen ist es, Ausgabeinformationen anzuzeigen. Die formatierte Ausgabe der obigen Zeilen sieht bspw. wie folgt aus: --openjava----openjava----openjava----openjava----openja va----openjava-- Programm: erzeugeTabelle Zweck: Erzeugt eine Tabelle für eine MS-Access-Datenbank Version: 1.0 Erstellt am: 06.04.99 --openjava----openjava----openjava----openjava----openja va----openjava-- Anschließend wird der Treiber geladen und eine Datenbank-URL spezifiziert, woraufhin die Verbindung zur Datenbank geöffnet werden kann. Bei der Herstellung dieser Verbindung werden weder Benutzername noch Passwort verwendet. Die dazu vorgesehenen Felder bleiben dementsprechend leer. try { // Laden des JDBC-ODBC-Treibers Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver"); // Datenbank-URL spezifizieren. Die Datenbank heisst hier //openjava String db_url = "jdbc:odbc:openjava"; // Eine Verbindung zur Datenbank herstellen Connection mein_con = DriverManager.getConnection(db_url, "", ""); System.out.println(" "); System.out.println("INFO: Verbindung zur Datenbank erfolgreich hergestellt."); System.out.println(" "); // Weiterer Verlauf dieses Beispiels } // Benoetigtes Exception-Handling catch(SQLException sqlex) { System.out.println("ERROR: Datenbankfehler: " + sqlex.getMessage()); System.out.println("--------------------"); sqlex.printStackTrace(); } catch(Exception exp) { System.out.println("ERROR: Sonstiger Fehler: " + exp.getMessage()); exp.printStackTrace(); Die formatierte Ausgabe besteht hier lediglich aus der folgenden Zeile. INFO: Verbindung zur Datenbank erfolgreich hergestellt. Anschließend wird ein Statement erzeugt, das im weiteren Verlauf dazu verwendet wird, um die Tabelle zu löschen. Das Code-Fragment befindet sich innerhalb einer try-catch Anweisung, damit das Programm nicht abstürzt, wenn keine Tabelle, die gelöscht werden kann, vorhanden ist. Eine andere Möglichkeit wäre, abzufragen, ob eine Tabelle vorhanden ist oder nicht. Wie diese Abfrage formuliert werden muss, wird im Folgenden durch die Metadaten-Abfrage näher erläutert. Nachdem die Tabelle gelöscht wurde, wird eine neue Tabelle erzeugt, die aus vier Spalten besteht. Hiermit kann demonstriert werden, wie die im Laufe dieses Kapitels besprochene Tabelle „Spieler" mit Java erzeugt werden kann. Das Löschen bzw. das Erzeugen der Tabelle ist nicht zwingend notwendig und wurde nur vorgenommen, um die in diesem Kapitel erläuterte Theorie anhand eines praktischen Beispiels zu zeigen. // Statements erzeugen Statement mein_stmnt = mein_con.createStatement(); // Loeschen der Spielertabelle, falls sie existiert try{ mein_stmnt.execute("DROP TABLE Spieler" ); } catch (Exception e){ System.out.println(" Tabelle Spieler existiert nicht "); } // Neue Spielertabelle erzeugen mein_stmnt.execute("CREATE TABLE Spieler(" + "Spieler_Nr integer,"+ "Nachname varchar (32)," + "Vorname varchar (32),"+"Gespielt integer );" ); System.out.println(" "); System.out.println("INFO: Tabelle erfolgreich erzeugt."); System.out.println(" "); } Nachdem die Tabelle erfolgreich kreiert wurde, wird die folgende Zeile ausgegeben: INFO: Tabelle erfolgreich erzeugt. Die Datensätze, die im theoretischen Teil erläutert wurden, werden in die derart erzeugte Tabelle eingefügt. Dafür wurde der SQL-Befehl INSERT INTO innerhalb der Methode executeUpdate des Objekts Statement verwendet. Um feststellen zu können, ob die Angaben tatsächlich in die Datenbank eingefügt wurden, wird in der Folge eine Anfrage an die Datenbank gestellt. Diese Anfrage ruft alle in der Tabelle vorhandenen Datensätze ab, die anschließend mit Hilfe der Methode SchreibeErgebnis angezeigt werden. // Daten in die Tabelle Einfügen mein_stmnt.executeUpdate ("INSERT INTO Spieler " + " VALUES (1, 'ElSaddik', 'Abed', 4)" ); mein_stmnt.executeUpdate ("INSERT INTO Spieler " + " VALUES (2, 'Fischer', 'Stephan', 6)" ); mein_stmnt.executeUpdate ("INSERT INTO Spieler " + " VALUES (3, 'ElSaddik', 'Abutti', 8)" ); mein_stmnt.executeUpdate ("INSERT INTO Spieler " + " VALUES (4, 'Frankfurter', 'Richard', 2)" ); System.out.println(" "); System.out.println("INFO: Werte erfolgreich in die Tabelle eingegeben."); System.out.println(" "); // Nun wird eine Anfrage an die Datenbank gestellt, // um zu sehen, ob die Daten enthalten sind query_str = "SELECT Spieler_Nr, Nachname, Vorname, Gespielt FROM Spieler"; // Abfrage ausfuehren und Ergebnisse anschauen mein_ergebnis = mein_stmnt.executeQuery(query_str); System.out.println(); System.out.println("--openjava----openjava----Zeige Tabellen Inhalt----openjava----openjava--"); System.out.println(); SchreibeErgebnis(mein_ergebnis); Das formatierte Ergebnis dieser Transaktionen sieht wie folgt aus: INFO: Werte erfolgreich in die Tabelle eingegeben. openjava----openjava----Zeige Tabellen Inhalt----openjava----openjava-- Spieler_Nr: Name Vorname Gespielt 1 ElSaddik Abed 4 2 Fischer Stephan 6 3 ElSaddik Abutti 8 4 Frankfurter Richard 2 Anschließend wird das Objekt PreparedStatement verwendet, um die Anzahl der gespielten Runden für die Spieler mit Nachnamen „ElSaddik" auf 44 zu setzen. Hierbei wurde explizit nicht die Spielernummer ausgewählt, um darzulegen, dass eine derartige Änderung alle Datensätze betrifft, wenn nicht mit einem eindeutigen Schlüssel gearbeitet wird. Die Anweisung PreparedStatement erwartet zwei Variablen: Die Anzahl der gespielten Runden und den Nachnamen des Spielers. Diese werden durch das Verwenden der zwei setxxx-Methoden (setInt() und setString()) auf die entsprechenden Werte gesetzt. Jede dieser Methoden akzeptiert wiederum zwei Argumente. Das erste Argument repräsentiert die Ordinalposition der einzusetzenden Variablen, das zweite Argument den Wert dieser Variablen. // Verwendung von PreparedStatement PreparedStatement mein_prstmnt = mein_con.prepareStatement("UPDATE Spieler SET Gespielt=? WHERE Nachname=?"); // Setzen der jeweiligen Variablen mit den entsprechenden // setxxx-Methoden mein_prstmnt.setInt(1, 44); mein_prstmnt.setString(2, "ElSaddik"); // Tabelle Aktualisieren mein_prstmnt.executeUpdate(); Um das Ergebnis dieser Aktualisierung ansehen zu können, wird eine neue Anfrage an die Datenbank gesendet, woraufhin als Resultat die Ergebnisse angezeigt werden. Das Argument der Methode executeQuery kann hierbei entweder direkt oder durch die Definition einer String-Variablen (query_str) angegeben werden: // Neue Anfrage an Datenbank senden, // um zu sehen, ob die Daten aktualisiert wurden query_str = "SELECT Spieler_Nr, Nachname, Vorname, Gespielt FROM Spieler WHERE Gespielt < 50"; // Abfrage ausfuehren und Ergebnisse anschauen mein_ergebnis = mein_stmnt.executeQuery(query_str); System.out.println(); System.out.println("--openjava----openjava----Prepar edStatement Verwenden----openjava----openjava--"); System.out.println(); SchreibeErgebnis(mein_ergebnis); Das formatierte Ergebnis ist im Folgenden angegeben. Hierbei erkennt man, dass die Datensätze beider Spieler mit dem Nachnamen „ElSaddik" aktualisiert worden sind. -openjava----openjava----PreparedStatement Verwenden----openjava- Spieler_Nr: Name Vorname Gespielt 1 ElSaddik Abed 44 2 Fischer Stephan 6 3 ElSaddik Abutti 44 4 Frankfurter Richard 2 Abschließend wird nochmals die Verwendung der Anweisung PreparedStatement betrachtet. Diese Klasse wird nun dazu eingesetzt, um Datensätze aus der Datenbank zu löschen. Dies muss erfolgen, indem ein PreparedStatement-Objekt definiert und anschließend zur Ausführung an die Datenbank gesendet wird. Hierbei wird nur eine Variable übergeben, in diesem Fall der Nachname eines Spielers. Deswegen muss nur eine der setxxx-Methoden verwendet werden, hier die Methode setString(): // Benutzung von PreparedStatement, // um Datensaetze aus der Datenbank zu loeschen PreparedStatement mein2_prstmnt = mein_con.prepareStatement("DELETE FROM Spieler Where Nachname=?"); // Setzen der jeweiligen Variablen mit der entsprechenden // setxxx-Methode mein2_prstmnt.setString(1, "ElSaddik"); // Tabelle aktualisieren mein2_prstmnt.executeUpdate(); // Senden einer neuen Anfrage an die Datenbank, // um festzustellen, ob die Daten aktualisiert wurden query_str = "SELECT Spieler_Nr, Nachname, Vorname, Gespielt FROM Spieler"; // Abfrage ausfuehren und Ergebnisse darstellen mein_ergebnis = mein_stmnt.executeQuery(query_str); System.out.println(); System.out.println("--openjava----openjava----Prepar edStatement zum Löschen verwenden----openjava----openjava--"); System.out.println(); SchreibeErgebnis(mein_ergebnis); Das Ergebnis dieses Löschvorgangs ist im Folgenden angegeben. --openjava----openjava----PreparedStatement zum Löschen verwenden----openjava----openjava-- Spieler_Nr: Name Vorname Gespielt 2 Fischer Stephan 6 4 Frankfurter Richard 2 Bis zu dieser Stelle wurden das Erzeugen und das Löschen einer Tabelle bzw. verschiedene Manipulationsoperationen betrachtet. Im Folgenden wird das Beispiel um die Eigenschaft, JDBC-Metadaten der Datenbanken während der Laufzeit eines Java-Programms zu ermitteln, erweitert. JDBC-Metadaten Die Ermittlung von Metadaten einer Datenbank wird dadurch möglich, dass JDBC die Klasse DatabaseMetaData zur Verfügung stellt. Die Erzeugung einer Instanz dieser Klasse ähnelt der eines Connection-Objekts, das nicht mit Hilfe des Schlüsselwortes new erzeugt wird, sondern durch die Verwendung des bereits vorhandenen Connection-Objekts bzw. der Methode getMetaData(). // Erzeugen des Metadatenobjekts DatabaseMetaData meine_metadata = mein_con.getMetaData(); if (meine_metadata == null) { System.out.println ("Keine Datenbank-Metadaten vorhanden"); } else { // Ausgeben der Informationen ueber das RDBMS System.out.println(); System.out.println("--openjava----openjava----Da tenbank Information----openjava----openjava--"); System.out.println(); System.out.println(); System.out.println("Datenbank Produktname: " + meine_metadata.getDatabaseProductName()); System.out.println("Datenbankversion: " + meine_metadata.getDatabaseProductVersion()); System.out.println("JDBC-Treibername: " + meine_metadata.getDriverName()); System.out.println("Treiberversion: " + meine_metadata.getDriverVersion()); System.out.println("URL: " + meine_metadata.getURL()); System.out.println("Benutzer: " + meine_metadata.getUserName()); System.out.println(); System.out.println(); // Weitere Abfragen, um Metadateninformationen der // Datenbank abzufragen, die im Folgenden erlaeutert werden, // sollen hier aufgezaehlt werden. So z.B. // die Ausgabe von Informationen ueber unterstuetzte // Eigenschaften } Die allgemeinen Metadaten der Datenbank dieses Beispieles sind im Folgenden angegeben. Wird eine andere Datenbank verwendet, so sehen die unten angegebenen Metadaten dementsprechend anders aus. --openjava----openjava----Datenbank Information----openjava----openjava-- Datenbank Produktname: ACCESS Datenbankversion: 3.5 Jet JDBC-Treibername: JDBC-ODBC Bridge (ODBCJT32.DLL) Treiberversion: 1.2001 (03.50.3428.00) URL: jdbc:odbc:openjava Benutzer: admin Das folgende Code-Fragment wird benötigt, um den ANSI-Standard für die SQL-Version abzufragen, die durch die Datenbank unterstützt wird: if(meine_metadata.supportsANSI92FullSQL()) { System.out.println("Ansi92 SQL: Voll unterstützt"); } else { if(meine_metadata.supportsANSI92IntermediateSQL( )) { System.out.println("Ansi92 SQL (1): Teilweise unterstützt"); } else { if(meine_metadata.supportsANSI92EntryLevelS QL()) { System.out.println("Ansi92 SQL: Ansatzweise unterstützt"); } else { System.out.println("Ansi92 SQL: wird nicht unterstützt"); } } } Das Ergebnis dieser Abfrage könnte wie im Folgenden dargestellt aussehen. Das Ergebnis kann aber von Benutzer zu Benutzer variieren, da es in großem Maße von der verwendeten Datenbank abhängig ist. Ansi92 SQL: Ansatzweise unterstützt Diese Ausgabe bedeutet, dass nur SQL der Form ANSI92-EntryLevel unterstützt wird. Durch die Methode supportsStoredProcedures() wird festgestellt, ob die Datenbank gespeicherte Prozeduren unterstützen kann. if(meine_metadata.supportsStoredProcedures()) { System.out.println("Stored Procedures: werden unterstützt"); } else { System.out.println("Stored Procedures: werden nicht unterstützt"); } Die Datenbank dieses Beispiels unterstützt gespeicherte Prozeduren, weshalb sich die folgende Ausgabe ergibt: Stored Procedures: werden unterstützt Das JDBC-API beinhaltet eine Vielzahl von Methoden, um Metadaten einer Datenbank abzufragen. Im Folgenden sind die Transaktionsmöglichkeiten der Datenbank, die in diesem Beispiel verwendet wird, aufgelistet. if(meine_metadata.supportsTransactions()) { System.out.println("Transaktionen: werden unterstützt"); } else { System.out.println("Transaktionen: werden nicht unterstützt"); } if(meine_metadata.supportsMultipleTransactions()) { System.out.println("Multiple Transaktionen: werden unterstützt"); } else { System.out.println("Multiple Transaktionen: werden nicht unterstützt"); } if(meine_metadata.supportsDataDefinitionAndDataManip ulatio nTransactions()) { System.out.println("Datendefinitions- und Datenmanipulationstransaktionen: werden unterstützt"); } else { System.out.println("Datendefinitions- und Datenmanipulationstransaktionen: werden nicht unterstützt"); } Das Ergebnis einer derartigen Abfrage könnte wie folgt aussehen: Transaktionen: werden unterstützt Multiple Transaktionen: werden unterstützt Datendefinitions- und Datenmanipulationstransaktionen: werden unterstützt Im Folgenden wird aufgezeigt, wie anhand der Metadaten sowohl der Name der Tabelle als auch deren Struktur ausgelesen werden kann. Die Tabellen werden hierbei mit Hilfe der Methode getTables() abgefragt. // Ermittle die Tabellen sowie deren Aufbau String meine_Tabellen[] = { "TABLE" }; // Liste aller Tabellen ermitteln ResultSet meine_Tabellen_Ergebnisse = meine_metadata.getTables(null, null, "%", meine_Tabellen); // Tabellen-Information ausgeben while(meine_Tabellen_Ergebnisse.next()) { String tabellen_name = meine_Tabellen_Ergebnisse.getString(3); System.out.println("Tabellenname: " + tabellen_name); // Anfrage stellen, um Tabellenspalten und // Inhalt ermitteln zu können, wie unten angegeben ist. } Da in der betrachteten Datenbank nur die Tabelle „Spieler" existiert, sieht das Ergebnis wie folgt aus: Tabellenname: Spieler Anschließend wird eine Anfrage formuliert, um alle Spalten der Tabelle als Ergebnis zu erhalten. ResultSet meine_Spalten_Ergebnisse = mein_stmnt.executeQuery("SELECT * FROM "+ tabellen_name); Nachdem durch die oben beschriebene Anfrage der Inhalt der Tabelle abgefragt wurde, wird die Anzahl der Spalten durch die Methode getColumnCount() ermittelt. Aus jeder Spalte können nun Informationen ausgelesen werden. Im folgenden Beispiel werden der Spaltenname, der Datentyp der Spalte und die Möglichkeit, Werte der Spalten zu überschreiben, abgefragt. Abschließend wird ermittelt, ob der Inhalt bezüglich der Groß- und Kleinschreibung unterschieden werden kann. ResultSetMetaData rsmd = meine_Spalten_Ergebnisse.getMetaData(); int anzahlDerSpalten = rsmd.getColumnCount(); for (int i=1; i<=anzahlDerSpalten; i++){ String spaltenName = rsmd.getColumnName(i); String datenTyp = rsmd.getColumnTypeName(i); boolean schreibbar = rsmd.isWritable(i); boolean caseSens = rsmd.isCaseSensitive(i); System.out.println("Name der Spalte: " + spaltenName); System.out.println("Verwendeter SQL-Datentyp: " + datenTyp); System.out.println("Ist die Spalte schreibbar: " + schreibbar); System.out.println("Ist der Spaltename case-sensitive: " + caseSens); } Die Ergebnisse dieser Anfragen sieht wie folgt aus: Name der Spalte: Spieler_Nr Verwendeter SQL-Datentyp: LONG Ist die Spalte schreibbar: false Ist der Spaltename case sensitive: false Name der Spalte: Nachname Verwendeter SQL-Datentyp: TEXT Ist die Spalte schreibbar: false Ist der Spaltename case sensitive: true Name der Spalte: Vorname Verwendeter SQL-Datentyp: TEXT Ist die Spalte schreibbar: false Ist der Spaltename case sensitive: true Name der Spalte: Gespielt Verwendeter SQL-Datentyp: LONG Ist die Spalte schreibbar: false Ist der Spaltename case sensitive: false Mittels der Metadaten kann auch der Inhalt einer Tabelle gelesen werden. Dies wird im folgenden Beispiel verdeutlicht: while(meine_Spalten_Ergebnisse.next()) { System.out.println(" "); for (int i=1; i<=anzahlDerSpalten; i++){ String derString = meine_Spalten_Ergebnisse.getString(i); System.out.print(derString + " "); } System.out.println(); } In der abgefragten Tabelle existieren daher zwei Zeilen, wodurch folgendes Ergebnis erscheint: 2 Fischer Stephan 6 4 Frankfurter Richard 2 Abbau der Datenbankverbindung Nach Beendigung der Arbeit mit der Datenbank muss die Verbindung zur Datenbank abgebaut werden. Hierzu ist der folgende Code notwendig. // Verbindung zur Datenbank beenden mein_con.close(); System.out.println(" "); System.out.println("INFO: Verbindung zur Datenbank geschlossen."); System.out.println(); Hilfsroutinen Für das im Laufe dieses Teilkapitels betrachtete Beispiel wurden zwei Hilfsmethoden geschrieben, die Methoden FormatierteAusgabe und SchreibeErgebnis. Die Methode FormatierteAusgabe dient dazu, die Ausgabe in eine lesbare Form zu bringen. Ein als Parameter übergebener String wird daher mit Leerzeichen bis zu einer angegebenen Länge aufgefüllt. Die Methode FormatierteAusgabe wurde wie folgt realisiert: private static String FormatierteAusgabe(String st, int i) { String leereZeile = " "; if(st.length() < i) return st.concat(leereZeile.substring(0, ( i-st.length() ) )); else return st; } Die zweite Methode, SchreibeErgebnis, dient dazu, Texte auszugeben, die als Ausgabe der Methode FormatierteAusgabe() entstehen. public static void SchreibeErgebnis(ResultSet rs) { //Abfrageergebnis bearbeiten und ausgeben System.out.println(); System.out.print(FormatierteAusgabe("Spieler_Nr:",17 )); System.out.print(FormatierteAusgabe("Name",17)); System.out.print(FormatierteAusgabe("Vorname",17)); System.out.print(FormatierteAusgabe("Gespielt",7)); System.out.println(); System.out.println(" "); try{ // Solange die Tabelle Daten enthaelt, // werden diese ausgegeben while(rs.next()) { spieler_nummer = new Integer(rs.getInt("Spieler_Nr")); spieler_name = rs.getString("Nachname"); spieler_vorname = rs.getString("Vorname"); spieler_gespielt = new Integer(rs.getInt("Gespielt")); System.out.print(FormatierteAusgabe(spieler _nummer.to String(),17)); System.out.print(FormatierteAusgabe(spieler _name,17)) ; System.out.print(FormatierteAusgabe(spieler _vorname,1 7); System.out.print(FormatierteAusgabe(spieler _gespielt. toString(),7)); System.out.println(); } } catch(SQLException sqlex) { System.out.println("ERROR: Datenbankfehler: " + sqlex.getMessage()); System.out.println("-------------------"); sqlex.printStackTrace(); } }