# einfache Frage bei DB-Zugriff



## ernst (22. Feb 2011)

Hallo allerseits,
in meinem einfachen Demo-Programm unten greife ich auf eine ACCESS-DB zu.
Dabei habe ich folgendes Problem mit dem ResultSet:
Es wird ein ResultSet erzeugt und dann innerhalb der Methode
mArtikel_.sucheArtikel(pDBVerbindung);
nochmals ein ResultSet erzeugt.
Dann bekomme ich die Fehlermeldung:
Exception in thread "main" java.lang.Throwable: Datensatz in erzeugeListe konnte nicht gelesen werden
        at w2006aenr2ver1.Artikelliste.erzeugeListe(MainW2006AENr2Ver1.java:177)
        at w2006aenr2ver1.MainW2006AENr2Ver1.main(MainW2006AENr2Ver1.java:20)
Java Result: 1
Was habe ich falsch gemacht?
Wie kann ich den Fehler beseitigen?

mfg
Ernst
----------------------------------------------------------------------------------------



		Java:In die Zwischenablage kopieren


        mySQL = "SELECT ArtNr, Bezeichnung, Lagerbestand, KleinBestPreis, GrossBestPreis, Lieferzeit FROM tblArtikel ";
        rsA = pDBVerbindung.executeQuery(mySQL);
        mArtikel = new Artikel[anzahl];
        for(i=0;i<anzahl;i++){
            mArtikel[i]=new Artikel();
        }

        for(i=0;i<anzahl;i++){
            try {
                b=rsA.next();
                if(b==false){
                    break;
                }
                // ArtNr dem ResultSet entnehmen
                // ---------- Hier gibt es Probleme -----------
                artNr = rsA.getString("ArtNr");
                // Setze ArtNr im i-ten Element
                mArtikel[i].setArtNr(artNr);
                // Suche nach diesem Artikel
                mArtikel[i].sucheArtikel(pDBVerbindung);  // <--- diese Methode benutzt wieder einen ResultSet 
            } catch (Throwable t) {
                t = new Throwable("Datensatz in erzeugeListe konnte nicht gelesen werden");
                throw t;
            }


    public void  sucheArtikel(DBConnection pDBConnection) throws Throwable {
        // der gefundene Artikel
        String mSQL;
        ResultSet rsA;
        mSQL = "SELECT ArtNr, Bezeichnung, Lagerbestand, KleinBestPreis, GrossBestPreis, Lieferzeit FROM tblArtikel ";
        mSQL = mSQL + "WHERE ArtNr = '" + artNr + "';";

        rsA = pDBConnection.executeQuery(mSQL);

        try {
            //System.out.println("mSQL="+mSQL);
            rsA.next();
            //artikelnummer = rsA.getString("Artikelnummer");
            bezeichnung = rsA.getString("Bezeichnung");
            lagerbestand = rsA.getInt("Lagerbestand");
            kleinBestPreis = rsA.getDouble("KleinBestPreis");
            grossBestPreis = rsA.getDouble("GrossBestPreis");
            lieferzeit = rsA.getInt("Lieferzeit");
        } catch (Throwable t) {
            t = new Throwable("Datensatz in sucheArtikel konnte nicht gelesen werden");
            throw t;
        }
        rsA.close();
    }
}

...



Hier das ganze Programm:


		Java:In die Zwischenablage kopieren


package w2006aenr2ver1;

import java.sql.*;

public class MainW2006AENr2Ver1 {

    public static void main(String[] args) throws Throwable {
        int anz;
        int i;
        DBZugriff dbZugriff;
        dbZugriff = new DBZugriff();
        Artikel artikel;
        artikel = new Artikel();
        artikel.setArtNr("1");
        //artikel.sucheArtikel(dbZugriff.getVerbindung());
        System.out.println("artikel-Bezeichnung="+artikel.getBezeichnung());
        Artikelliste al;
        al = new Artikelliste();
        // Hier gibt es Probleme
        al.erzeugeListe(dbZugriff.getVerbindung());
        anz = al.getmArtikel().length;
        for(i=0;i<anz;i++){
            System.out.println("Artnr="+al.getmArtikel()[i].getArtNr());
        }



    }
}

class Artikel {
    private String artNr;
    private String bezeichnung;
    private int lagerbestand;
    private double kleinBestPreis;
    private double grossBestPreis;
    private int lieferzeit;

    Artikel() {
    }

    public Artikel(String ArtNr, String bezeichnung, int lagerbestand, double kleinBestPreis, double grossBestPreis, int lieferzeit) {
        this.artNr = artNr;
        this.bezeichnung = bezeichnung;
        this.lagerbestand = lagerbestand;
        this.kleinBestPreis = kleinBestPreis;
        this.grossBestPreis = grossBestPreis;
        this.lieferzeit = lieferzeit;
    }

    public void setArtNr(String artNr) {
        this.artNr = artNr;
    }


    public void setBezeichnung(String bezeichnung) {
        this.bezeichnung = bezeichnung;
    }

    public void setGrossBestPreis(double grossBestPreis) {
        this.grossBestPreis = grossBestPreis;
    }

    public void setKleinBestPreis(double kleinBestPreis) {
        this.kleinBestPreis = kleinBestPreis;
    }

    public void setLagerbestand(int lagerbestand) {
        this.lagerbestand = lagerbestand;
    }

    public void setLieferzeit(int lieferzeit) {
        this.lieferzeit = lieferzeit;
    }

    public String getArtNr() {
        return artNr;
    }

    public String getBezeichnung() {
        return bezeichnung;
    }

    public double getGrossBestPreis() {
        return grossBestPreis;
    }

    public int getLagerbestand() {
        return lagerbestand;
    }

    public int getLieferzeit() {
        return lieferzeit;
    }

// Zugriff auf DB (eigentlich schlechtes Design)
    public void  sucheArtikel(DBConnection pDBConnection) throws Throwable {
        // der gefundene Artikel
        String mSQL;
        ResultSet rsA;
        mSQL = "SELECT ArtNr, Bezeichnung, Lagerbestand, KleinBestPreis, GrossBestPreis, Lieferzeit FROM tblArtikel ";
        mSQL = mSQL + "WHERE ArtNr = '" + artNr + "';";

        rsA = pDBConnection.executeQuery(mSQL);

        try {
            //System.out.println("mSQL="+mSQL);
            rsA.next();
            //artikelnummer = rsA.getString("Artikelnummer");
            bezeichnung = rsA.getString("Bezeichnung");
            lagerbestand = rsA.getInt("Lagerbestand");
            kleinBestPreis = rsA.getDouble("KleinBestPreis");
            grossBestPreis = rsA.getDouble("GrossBestPreis");
            lieferzeit = rsA.getInt("Lieferzeit");
        } catch (Throwable t) {
            t = new Throwable("Datensatz in sucheArtikel konnte nicht gelesen werden");
            throw t;
        }
        rsA.close();
    }
}


class Artikelliste {
    // enthält alle Artikel aus der Datenbank
    private Artikel[] mArtikel;

    public Artikel[] getmArtikel() {
        return mArtikel;
    }

    public Artikelliste() {
    }



    public void erzeugeListe(DBConnection pDBVerbindung) throws Throwable{
        boolean b;
        int i;
        int anzahl=0;
        String mySQL;
        ResultSet rsA;

        String artNr;
        String bezeichnung;
        int lagerbestand;
        double kleinBestPreis;
        double grossBestPreis;
        int lieferzeit;

        anzahl = anzahlArtikel(pDBVerbindung);
        // Nochmals der ResulSet holen, da im alten ResultSet der Zeiger ganz am Ende ist.
        // rsA.beforeFirst(); funktioniert leider nicht wegen FORWARD_ONLY
        //

        mySQL = "SELECT ArtNr, Bezeichnung, Lagerbestand, KleinBestPreis, GrossBestPreis, Lieferzeit FROM tblArtikel ";
        rsA = pDBVerbindung.executeQuery(mySQL);
        mArtikel = new Artikel[anzahl];
        for(i=0;i<anzahl;i++){
            mArtikel[i]=new Artikel();
        }
        
        for(i=0;i<anzahl;i++){
            try {
                b=rsA.next();
                if(b==false){
                    break;
                }
                // ArtNr dem ResultSet entnehmen
                // Hier gibt es Probleme
                artNr = rsA.getString("ArtNr");
                // Setze ArtNr im i-ten Element
                mArtikel[i].setArtNr(artNr);
                // Suche nach diesem Artikel
                mArtikel[i].sucheArtikel(pDBVerbindung);
            } catch (Throwable t) {
                t = new Throwable("Datensatz in erzeugeListe konnte nicht gelesen werden");
                throw t;
            }
        }
        rsA.close();
       
    }

// Länge
    public int anzahlArtikel(DBConnection pDBVerbindung) throws Throwable{
        boolean b;
        int i;
        int anzahl=0;
        String mySQL;
        ResultSet rsA;

        String artNr;
        String bezeichnung;
        int lagerbestand;
        double kleinBestPreis;
        double grossBestPreis;
        int lieferzeit;

        mySQL = "SELECT ArtNr, Bezeichnung, Lagerbestand, KleinBestPreis, GrossBestPreis, Lieferzeit FROM tblArtikel ";
        rsA = pDBVerbindung.executeQuery(mySQL);
        // Länge des ResultSet bestimmen
        do{
            b = rsA.next();
            anzahl++;
        }while (b==true);

        rsA.close();
        return(anzahl);
    }
}


/*
Hier wird die Verbindung zur Datenbank aufgebaut.
Die Verbindung wird charakterisiert durch 3 Zustände:
- Datenquelle: Datei
- Connection: Die eigentliche Anbindung
- Statement: Möglichkeit Datenbankanfragen zu stellen
Diese werden in der Klasse DBConnection verwaltet.
*/
class DBZugriff {
    private DBConnection DBVerbindung;

    public DBZugriff() throws Throwable{
        DBVerbindung = new DBConnection();
        // Die o.g. 3 Zustände werden geeignet initialisiert und in
        // DBVerbindung gespeichert.
        aufbaueVerbindung();
    }

    //public void oeffneDB() throws SQLException{
    public void aufbaueVerbindung() throws SQLException {
        String datenQuelle;
        Connection connectionDB;
        Statement statementSQL;
        try {
            // LÃ¤dt die Klasse mit dem Namen "sun.jdbc.odbc.JdbcOdbcDriver"
            Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
            // Variable fÃ¼r den Treiber und den Pfad zur DB (Deklaration und Wertzuweisung)
            // getConnection(...) benÃ¶tigt 3 Parameter:
            // eine Datenquelle, einen User, ein Passwort
            // eine Datenquelle ist wie folgt aufgebaut:
            // jdbc:Subprotokoll:Datenquellennamen
            // FÃ¼r ODBC-Datenquellen ist das Subprotokoll obcd
            //
            datenQuelle = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=H:/Daten_Austausch/dBMSAccess2.mdb";

            // getConnection(...) liefert die Verbindung zur Datenbank zurÃ¼ck.
            // obenstehender Pfad muss jeweils angepasst werden!
            connectionDB = DriverManager.getConnection(datenQuelle, "", "");
            statementSQL = connectionDB.createStatement();
            //DBVerbindung.setConnectionDB(connectionDB);
            //DBVerbindung.setDatenQuelle(datenQuelle);
            DBVerbindung.setStatementSQL(statementSQL);
        } catch (SQLException fehler) {
            fehler = new SQLException("Treiber existiert nicht");
            throw fehler;
        } catch (ClassNotFoundException fehler) {
            System.out.println("Treiber existiert nicht");
            fehler.printStackTrace();
        }
    }


    public void abbauenVerbindung() throws SQLException {
        try {
            DBVerbindung.getConnectionDB().close();
            DBVerbindung.getStatementSQL().close();
        } catch (SQLException fehler) {
            fehler = new SQLException("DB konnte nicht geschlossen werden");
            throw fehler;
        }
    }

    public DBConnection getVerbindung() throws SQLException {
        aufbaueVerbindung();
        return DBVerbindung;
    }
}


/*
Die Verbindung wird charakterisiert durch 3 Zustände:
- Datenquelle: Datei
- Connection: Die eigentliche Anbindung
- Statement: Möglichkeit Datenbankanfragen zu stellen
*/

class DBConnection {
    private String datenQuelle;
    private Connection connectionDB;
    private Statement statementSQL;

    public DBConnection(){
    }
    public Connection getConnectionDB() {
        return connectionDB;
    }

    public String getDatenQuelle() {
        return datenQuelle;
    }

    public Statement getStatementSQL() {
        return statementSQL;
    }

    public void setConnectionDB(Connection connectionDB) {
        this.connectionDB = connectionDB;
    }

    public void setDatenQuelle(String datenQuelle) {
        this.datenQuelle = datenQuelle;
    }

    public void setStatementSQL(Statement statementSQL) {
        this.statementSQL = statementSQL;
    }

    public ResultSet executeQuery(String sqlString) throws SQLException{
        ResultSet rs;
        try{
            rs = statementSQL.executeQuery(sqlString);
        } catch (SQLException fehler) {
            fehler = new SQLException("Fehler bei rs = statementSQL.executeQuery(sqlString);");
            throw fehler;
        }
        return rs;
    }
}

_


----------



## XHelp (22. Feb 2011)

Lass dir doch fürs erste die Exception ausgeben, die auch wirklich fliegt. Die wird bestimmt aussagekräftiger als "Joar, da ist ein Fehler passiert".
Außerdem wenn du Fehlerangaben mit Zeilen postest, dann solltest du auch auf die entsprechenden Zeilen hinweisen.


----------



## DerEisteeTrinker (22. Feb 2011)

Überprüfe, ob die Verbindung wirklich besteht, dann schau nach ob die Bezeichnungen alle richtig sind und dann kannst du ja mal debuggen und nachsehen, was in der ergebnismenge drinsteht. vllt gehst in deiner schleife zu weit in der ergebnismenge oder ähnliches.


----------



## ernst (22. Feb 2011)

XHelp hat gesagt.:


> Lass dir doch fürs erste die Exception ausgeben, die auch wirklich fliegt. Die wird bestimmt aussagekräftiger als "Joar, da ist ein Fehler passiert".
> Außerdem wenn du Fehlerangaben mit Zeilen postest, dann solltest du auch auf die entsprechenden Zeilen hinweisen.



Danke für deine Antwort,
In Zeile 165 geschieht die Exception (da gibt es den "Abflug") und zwar beim 2. Durchgang durch die for-Schleife.
(Dann geht es in den catch-Teil Zeile Zeile 177)

mfg
Ernst


----------



## ernst (22. Feb 2011)

DerEisteeTrinker hat gesagt.:


> Überprüfe, ob die Verbindung wirklich besteht, dann schau nach ob die Bezeichnungen alle richtig sind und dann kannst du ja mal debuggen und nachsehen, was in der ergebnismenge drinsteht. vllt gehst in deiner schleife zu weit in der ergebnismenge oder ähnliches.



Danke für deine Antwort,
wenn ich z.B. Zeile 175 auskommentiere 
//                mArtikel_.sucheArtikel(pDBVerbindung);
gibt es keinen Fehler mehr

mfg
Ernst_


----------



## DerEisteeTrinker (22. Feb 2011)

sprich dann debugge mal die Methode, die da in der Zeile aufgerufen wird


----------



## ernst (22. Feb 2011)

DerEisteeTrinker hat gesagt.:


> sprich dann debugge mal die Methode, die da in der Zeile aufgerufen wird



Beim 1. Aufruf von 
mArtikel_.sucheArtikel(pDBVerbindung);
gibt es noch keine Probleme.
Nach dem 1. Aufruf von
mArtikel.sucheArtikel(pDBVerbindung);
komme ich nicht mehr zum 2. Aufruf von
mArtikel.sucheArtikel(pDBVerbindung);
weil es vorher in Zeile 165 den Abflug gibt (Exception).

mfg
Ernst_


----------



## DerEisteeTrinker (22. Feb 2011)

ja klar. du kannst nicht zwei konkurierende ResultSets aufmachen mit deinem executeQuery(). Du musst erst alle Artikelnummern speichern und sie dann nach dem speichern das erste Resultset schließt. Dnan kannst die ArtNr nachschauen in der DB


----------



## ernst (22. Feb 2011)

DerEisteeTrinker hat gesagt.:


> ja klar. du kannst nicht zwei konkurierende ResultSets aufmachen mit deinem executeQuery(). Du musst erst alle Artikelnummern speichern und sie dann nach dem speichern das erste Resultset schließt. Dnan kannst die ArtNr nachschauen in der DB



Ah ja, Ok.
Aber warum ist das os und wo steht das beschrieben?

mfg
Ernst


----------



## DerEisteeTrinker (22. Feb 2011)

Das kommt von der Tatsache, dass du einen ResultSet auch im Nachhinein noch bearbeiten kannst. WO das beschrieben ist? ka, ich weiß es, weil ich den gleichen Fehler am Anfang auch oft gemacht habe, dass geht iwann ins blut über


----------



## XHelp (22. Feb 2011)

Steht so in der API:


			
				http://download.oracle.com/javase/1.4.2/docs/api/java/sql/Statement.html hat gesagt.:
			
		

> By default, only one ResultSet object per Statement object can be open at the same time. Therefore, if the reading of one ResultSet object is interleaved with the reading of another, each must have been generated by different Statement objects. All execution methods in the Statement interface implicitly close a statment's current ResultSet object if an open one exists.


----------



## ernst (23. Feb 2011)

XHelp hat gesagt.:


> Steht so in der API:



Vielen Dank an alle!!!
Damit ist das Thema für mich erledigt.

mfg
Ernst


----------

