# Komme mit dem SQL Statement nicht weiter



## Thomas Lorenz (25. Jul 2010)

Servus Gemeinde, 

in der 'updateMission' -Methode komme ich nicht weiter.
Die erste System.out.... Anweisung wird ausgeführt, die zweite nicht.
Darum gehe ich davon aus, dass der SQL-String nicht richtig ist.
Allerdings habe ich mich an die Anleitung gehalten.


```
package _Pol649;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;



public class ReportDBController {
      private ArrayList<Statement> list = new ArrayList<Statement>();

    private String driver = "org.apache.derby.jdbc.ClientDriver"; // Clienttreiber
    private String protocol = "jdbc:derby://localhost:1527/649DB;create =true; dataEncryption=true; bootPassword=6ma0inNENIgCz9Z1Uesb";
    private String tableReports = "Reports"; // Tabellenname für die Vorgänge
    private String tableExpositions = "Expositions"; // Tabellenname für die
    // schriftlichen Arbeiten
    private String tableMissions = "Missions"; // Tabellenname für die Einsätze

    SystemData _Sys = (SystemData) CollectionController.getObject("SystemData");

    /**
     * Überschreibt einen Einsatz in der Datenbannk.
     * 
     * @param i
     * @param missionNumber
     * @throws SQLException
     */
    public void updateMission(String missionNumber, String beginnOfMission,
	    String endOfMission, String taskOffice, String rushOrder,
	    String nameOfMission, String firstLocation,
	    String firstLocationNumber, String secondLocation,
	    String secondLocationNumber, String acrossFrom,
	    String streetNumber, String missionReport, String timeOfCreation)
	    throws SQLException
    {
	/*
	 * Zum Überschreiben eines Einsatzes bekommen wir alle aktuellen
	 * Feldinhalte der GUI übergeben. Da sich die Einsatznummer und die
	 * 'timeOfCreation' NICHT ändern werden, können wir mit diesen beiden
	 * Werten in der DB suchen.
	 */

	loadDriver();
	Connection conn = null;
	PreparedStatement p = null;
	list.add(p);
	ResultSet rs = null;
	try{
	    conn = DriverManager.getConnection(protocol);
	    conn.setAutoCommit(false);
	    System.out.println("ein");
	    p = conn
		    .prepareStatement("UPDATE "
			    + getTableMissions()
			    + "SET EINSATZBEGINN = ?, EINSATZENDE = ?, AUFTRAGDIENSTSTELLE = ?, "
			    + "EILE = ?, EINSATZANLASS = ?, EINSATZORT_EINS = ?, HAUSNUMMER_EINS = ?, EINSATZORT_ZWEI = ?, "
			    + "HAUSNUMMER_ZWEI = ?, GEGENUEBER = ?, KEINEHAUSNUMMER = ?, ERLEDIGUNG = ?  WHERE ENUMMER = ? AND"
			    + "ERSTELLUNGSZEIT = ?");
	    System.out.println("zwei");
	    p.setString(1, beginnOfMission);
	    p.setString(2, endOfMission);
	    p.setString(3, taskOffice);
	    p.setString(4, rushOrder);
	    p.setString(5, nameOfMission);
	    p.setString(6, firstLocation);
	    p.setString(7, firstLocationNumber);
	    p.setString(8, secondLocation);
	    p.setString(9, secondLocationNumber);
	    p.setString(10, acrossFrom);
	    p.setString(11, streetNumber);
	    p.setString(12, missionReport);
	    p.setString(13, missionNumber);
	    p.setString(14, timeOfCreation);
	    
	    p.executeUpdate();
	    
	   }
	catch (SQLException sqle){
	    printSQLException(sqle);

	}
	finally{
	    // release all open resources to avoid unnecessary memory usage
	    // ResultSet

	    closeResultSet(rs);
	    closeTransactions(null);
	    closeConnection(conn);
	}
    }

  
    /**
     * Erstellen der Datenbank für die Einsätze
     * 
     * @throws SQLException
     * 
     */

    void createMissionTables() throws SQLException {
	loadDriver();
	Connection conn = null;
	Statement s = null;
	list.add(s);
	ResultSet rs = null;
	PreparedStatement ps = null;
	try{
	    conn = DriverManager.getConnection(protocol);
	    // manuelle Kontrolle mit 'setAutoCommit(false)'
	    // conn.setAutoCommit(false);

	    s = conn.createStatement();
	    // Das Löschen der Tabelle kann nur erfolgen, wenn es eine solche
	    // Tabelle gibt
	    s.execute("DROP TABLE Missions");

	    s.execute("CREATE TABLE Missions ("
		    + "ENummer VARCHAR(20) NOT NULL,"
		    + "Einsatzbeginn VARCHAR(10) NOT NULL,"
		    + "Einsatzende VARCHAR(10),"
		    + "Auftragdienststelle VARCHAR(15)," 
		    + "Eile VARCHAR(10),"
		    + "Einsatzanlass VARCHAR(200) NOT NULL,"
		    + "Einsatzort_Eins VARCHAR(100),"
		    + "Hausnummer_Eins VARCHAR(10),"
		    + "Einsatzort_Zwei VARCHAR(100),"
		    + "Hausnummer_Zwei VARCHAR(10),"
		    + "gegenueber VARCHAR(10),"
		    + "keineHausnummer VARCHAR(10),"
		    + "Erledigung VARCHAR(2000),"
		    + "Erstellungszeit VARCHAR(30) NOT NULL)");
	    conn.commit();
	    s.close();
	    conn.close();
	}
	catch (SQLException sqle){
	    printSQLException(sqle);
	}
	finally{
	    // release all open resources to avoid unnecessary memory usage
	    // ResultSet

	    closeResultSet(rs);
	    closeTransactions(null);
	    closeConnection(conn);
	}
    }

 
    /**
     * Ausgabe eines aufgetretenen Fehlers auf dem Fenster der
     * Mitarbeiterverwaltung.
     * 
     * @param e
     * @param frame
     */
    public static void printSQLException(SQLException e, EmployeeAdmin frame) {
	// Unwraps the entire exception chain to unveil the real cause of the
	// Exception.
	while (e != null){
	    ErrorHelper _Error = (ErrorHelper) CollectionController
		    .getObject("ErrorHelper");
	    _Error.getErrorMessage(150, new Exception().getStackTrace()[0]
		    .getClassName()
		    + "/" + new Exception().getStackTrace()[0].getMethodName(),
		    "SQL-Status:" + e.getSQLState() + ", Fehlercode: "
			    + e.getErrorCode());
	    frame.setInfoText(_Error.getErrorClassification(), _Error
		    .getErrorText1(), _Error.getErrorText2(), _Error
		    .getErrorText3(), _Error.getErrorText4(), "SQL-State:"
		    + e.getSQLState() + ", Fehlercode: " + e.getErrorCode());

	    // for stack traces, refer to derby.log or uncomment this:
	    // e.printStackTrace(System.err);
	    e = e.getNextException();

	}
    }

    /**
     * Schließt alle geöffneten Transaktionen (Betrifft das Verwalten von
     * Mitarbeitern).
     * 
     * 
     * @param frame
     */
    private void closeTransactions(EmployeeAdmin frame) {
	int i = 0;
	while (!list.isEmpty()){
	    // PreparedStatement extend Statement
	    Statement st = list.remove(i);
	    try{
		if (st != null){
		    st.close();
		    st = null;
		}
	    }
	    catch (SQLException sqle){
		printSQLException(sqle, frame);
	    }
	}

    }

    /**
     * Lädt den Treiber für die Datenbank
     * 
     */
    private void loadDriver() {
	try{
	    Class.forName(driver).newInstance();
	}
	catch (ClassNotFoundException cnfe){
	    cnfe.printStackTrace(System.err);
	}
	catch (InstantiationException ie){
	    ie.printStackTrace(System.err);
	}
	catch (IllegalAccessException iae){
	    System.err.println("\nSie haben keinen Zugriff auf den Treiber."
		    + driver);
	    iae.printStackTrace(System.err);
	}
    }

    /**
     * Schließt das ResultSet
     * 
     * @param rs
     */
    private void closeResultSet(ResultSet rs) {
	if (rs != null){
	    try{
		rs.close();
		rs = null;
	    }
	    catch (SQLException e){
		e.printStackTrace();
	    }
	    rs = null;
	}
    }

    /**
     * Beendet die DB-Verbindung
     * 
     * @param conn
     * @throws SQLException
     */
    private void closeConnection(Connection conn, EmployeeAdmin frame)
	    throws SQLException
    {
	// Connection
	try{
	    if (conn != null){
		conn.close();
		conn = null;
	    }
	}
	catch (SQLException sqle){
	    conn.rollback();
	    printSQLException(sqle, frame);

	}
    }

    /**
     * Beendet die DB-Verbindung
     * 
     * @param conn
     * @throws SQLException
     */
    private void closeConnection(Connection conn) throws SQLException {
	// Connection
	try{
	    if (conn != null){
		conn.close();
		conn = null;
	    }
	}
	catch (SQLException sqle){
	    conn.rollback();
	    printSQLException(sqle);
	}

    }

    public static void printSQLException(SQLException e) {
	// Unwraps the entire exception chain to unveil the real cause of the
	// Exception.
	while (e != null){
	    // for stack traces, refer to derby.log or uncomment this:
	    // e.printStackTrace(System.err);
	    e = e.getNextException();
	}
    }

    /**
     * @param tableReports
     *            the tableReports to set
     */
    public void setTableReports(String tableReports) {
	this.tableReports = tableReports;
    }

    /**
     * @param tableExpositions
     *            the tableExpositions to set
     */
    public void setTableExpositions(String tableExpositions) {
	this.tableExpositions = tableExpositions;
    }

    /**
     * @param tableMissions
     *            the tableMissions to set
     */
    public void setTableMissions(String tableMissions) {
	this.tableMissions = tableMissions;
    }

    /**
     * @return the tableExpositions
     */
    public String getTableExpositions() {
	return tableExpositions;
    }

    /**
     * @return the tableMissions
     */
    public String getTableMissions() {
	return tableMissions;
    }

    /**
     * @return the tableReports
     */
    public String getTableReports() {
	return tableReports;
    }

}
```


Wer kann mir helfen ?


----------



## gman (25. Jul 2010)

Hi,

zwei Fragen:

- Wird eine Exception geworfen, bricht das Programm einfach ab, oder was passiert?
- Bekommst du denn in Zeile 58 ein Connection-Objekt zurück?

EDIT: Was mir noch gerade aufgefallen ist: In Zeile 64 könnte ein Leerzeichen am Anfang
der Zeichenkette helfen. Denn so wie es jetzt ist hängt der Tabellenname direkt mit
dem ersten Feld zusammen.


----------



## Thomas Lorenz (25. Jul 2010)

Es wird keine Exception geworfen. Das 2. System.out. wird nicht mehr ausgeführt.

Mit einem System.out.println(conn.getConnection()); bekomme ich ausgegeben : 

org.apache.derby.client.net.NetConnection40@37567e6c

Habe in Zeile 64 (Anfang) und in der 'Where'-Klausel ein Leerzeichen nach dem 'AND' gesetzt.
Trotzdem geht's nicht.

Keine Fehlermeldung, kein 2.System.out.


----------



## gman (25. Jul 2010)

Speichere die SQL-Zeichenkette mal ein einen String und lass ihn dir ausgeben und eventuell
selber ausführen. So kannst du ausschliessen das es an der Abfrage liegt.

Wenn der Fehler nicht daran liegt, würde ich mal schrittweise mit dem Debugger durch den 
entsprechenden Code-Abschnitt gehen.


----------



## Thomas Lorenz (25. Jul 2010)

Habe das jetzt so gemacht : 


```
String sql = "UPDATE "
		    + getTableMissions()
		    + " SET EINSATZBEGINN = ?, EINSATZENDE = ?, AUFTRAGDIENSTSTELLE = ?, "
		    + "EILE = ?, EINSATZANLASS = ?, EINSATZORT_EINS = ?, HAUSNUMMER_EINS = ?, EINSATZORT_ZWEI = ?, "
		    + "HAUSNUMMER_ZWEI = ?, GEGENUEBER = ?, KEINEHAUSNUMMER = ?, ERLEDIGUNG = ?  WHERE ENUMMER = ? AND "
		    + "ERSTELLUNGSZEIT = ?";
	    p = conn
		    .prepareStatement(sql);
```


Jetzt geht es.
Vielen Dank.

Aber warum geht es jetzt ??
Hast Du eine Antwort für mich?

Aber erstmal einen großen Dank an Dich !


----------



## gman (25. Jul 2010)

Öhhh, keine Ahnung.

Hast du denn wirklich nur den SQL-String in eine lokale Variable gepackt oder hast du ihn noch
weiter angepasst? Die beiden Änderungen (Leerzeichen vor dem SET und nach dem AND) hattest du ja
schon richtig beschrieben.

Noch ein Tipp: Ich würde mir solche SQL-Strings immer mit einem StringBuilder zusammenbauen. Ich
verwende den SQL-Developer von Oracle um meine Abfragen zu testen. Dann kann ich sie direkt aus
dem Programm als StringBuilder-Code über die Zwischenablage in meinen Java-Code kopieren. Macht
die Entwicklung und den Test von SQL-Abfragen erheblich einfacher.


----------

