[Java] Datenbankanbindung MS Access

B4LU

Lt. Commander
Registriert
Dez. 2006
Beiträge
1.990
Hallo,

und zwar möchte ich in Java eine Datenbankanbindung mit Access realisieren.
Allerdings schlägt diese immer fehl.
Daraufhin habe ich das Problem mal eingerenzt und es scheint am Treiber zu liegen.
Da ich noch totaler Anfänger bin, bitte ich euch mal drüberzuschauen, ob ich alles richtig gemacht habe:

Code:
public class Datenbankanbindung 
{

	public static void main(String[] args) 
	
	{
		try
		{
			Class.forName("sun.odbc.JdbcOdbcDriver");
			System.out.println("Treiber erfolgreich geladen");
		}
			
		
		catch (ClassNotFoundException e)
		{
			System.out.println("Treiber konnte nich geladen werden "+e);
			System.exit (0);
		}
			
		
	} 
}

Wenn ich das jetzt ausführe kommt immer folgende Konsolenausgabe:
Treiber konnte nich geladen werden java.lang.ClassNotFoundException: sun.odbc.JdbcOdbcDriver

Heisst das, dass mir der JdbcOdbc Treiber fehlt? Ich habe aber das aktuelle SDK von Sun installiert, der Treiber sollte da enthalten sein.

Vielen Dank für eure Hilfe
 
Hast du die Treiber.jar eingebunden? Ich kenne das nur von HSQLDB das man da die .jar einbinden muss im Netbeansprojekt. Dann müsste es klappen. Er sagt in der Fehlermeldung ja auch das er den Treiber
nicht finden kann.
 
Wie gesagt, ich hab keinen Plan. Habe nur das SDK installiert, mir wurde gesagt, dass der Treiber da enthalten sein soll.
Wo bekomme ich den einzeln her, konnt den nirgends finden? Gibts den bei Sun oder MS?
Und kann mir bitte jemand erklären, wie ich den einbinden muss?
 
Probier mal
Code:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Wenn du mal mit nem ZIP-Programm die rt.jar öffnest (ist bei der JRE dabei, normalerweise C:\Programme\Java\jre6\lib\rt.jar), dann ist dieser Treiber nämlich dort genau im Ordner sun/jdbc/odbc vorhanden. Du musst halt sicherstellen, dass die rt.jar im CLASSPATH ist, aber das ist normalerweise eh der Fall weil diese ja praktisch alle Standard-Java-Klassen mitliefert.

Achja: Die Klasse ist NUR bei der JVM von Sun dabei (nicht aber bei der IBM, Microsoft oder was es sonst noch für JVM-Hersteller gibt). Insofern ist die Plattformunabhängigkeit nicht 100%ig gegeben wenngleich das für dich wohl eh egal sein dürfte.
 
Zuletzt bearbeitet:
Das ist ja ein Ding. Früher war es wirklich "sun.odbc.JdbcOdbcDriver" (Nachtrag: Zumindest glaube ich das....). Das haben die wohl irgendwann in ein neues Paket "jdbc" verfrachtet.

Mit
Code:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
sollte es klappen.
 
Hey, vielen Dank euch erstmal für die schnelle Hilfe, hat geklappt, danke!

Neues Problem:
Code:
                try
		{
			
			String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=C:/Users/****/Desktop/Datenbank";
		        Connection dbVerbindung= DriverManager.getConnection(url);
			sqlStatement = dbVerbindung.createStatement();
			System.out.println("SQL-Statement erzeugt");
			resultSet=sqlStatement.executeQuery(sqlString);
			while (resultSet.next());
			System.out.println(resultSet.getString(1)+ "\t"+
					   resultSet.getString(2)+ "\t"+
					   resultSet.getString(3));
			resultSet.close();
			System.out.println("resultSet-Objekt zerstört...");
			sqlStatement.close();
			System.out.println("sqlStatement-Objekt zerstört...");
			dbVerbindung.close();
			System.out.println("Verbindung geschlossen");
			
		}
		
		catch (SQLException e)
		{
			System.out.println("Fehler beim DB-Zugriff: "+e);
			System.exit(0);
		}

Wenn ich das nun ausführe, kommt:

SQL-Statement erzeugt
Fehler beim DB-Zugriff! java.sql.SQLException: [Microsoft][ODBC Driver Manager] Ungültiger Cursorstatus

Kann mir jemand bitte weiterhelfen was das heißt und wo mein Fehler liegt?
 
Mach doch zusätzlich im catch-Block noch ein
Code:
e.printStackTrace();
bzw. (praktisch identisch)
Code:
System.out.println(e.getStackTrace());
Dann sieht man in welcher Zeile und welcher Funktion der Fehler passiert.

Außerdem ists oft besser, anstatt nur "+e" (welches intern ein e.getLocalizedMessage()" aufruft) ein "+e.getMessage()" zu machen, weil man dann die englische Fehlerausgabe hat und da besser was bei google findet.

Ich vermute, dass du einfach nach deinem while eine Klammer bräuchtest:
Code:
while (resultSet.next()){
    System.out.println(resultSet.getString(1)+ "\t"+ resultSet.getString(2)+ "\t"+ resultSet.getString(3)); 
}
resultSet.close();
 
Zuletzt bearbeitet:
Hey BerniG, vielen Dank für deine Hilfe und deine Tipps, es läuft nun soweit!

_____________________________________

Okay, nachdem die Datenbankanbindung über Konsole soweit geklappt hat, habe ich mich nun der GUI zugewandt.
Allerdings klappt es nicht so wie ich es mir vorstelle.

Fensterklasse:
Code:
public void anzeigen()
	{
		txtArtNr.setText(Integer.toString(fach.getArtikelNr()));
		txtArtBez.setText(fach.getArtikelBez());
		txtEKP.setText(Double.toString(fach.getArtikelEKP()));
		txtBestand.setText(Integer.toString(fach.getArtikelBestand()));
	}

Und in der Fachklasse
Code:
private Connection dbVerbindung;
	public void erzeugeDBVerbindung()
	{
	  { try
	     {      
	   String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=C:/Users/****/Desktop/Artikelverwaltung";
	    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
	    Connection dbVerbindung= DriverManager.getConnection(url);
	   JOptionPane.showMessageDialog(null, "Datenbankverbindung ok ");
	    }
	catch (Exception e)
	      {
	  JOptionPane.showMessageDialog(null, "Datenbankverbindung fehlgeschlagen! "+e);
	      }
	  }
	 } // Ende Erzeuge DBVerbindung()



	public void zeige()
	{
	  try
	{
	   Statement stmt = dbVerbindung.createStatement();
	   System.out.println("Statement erzeugt");
	    ResultSet abfrageErgebnis = stmt.executeQuery("SELECT * FROM Lager");
	  // Im Resultset von der Stelle 0 auf den ersten Datensatz springen
	    while(abfrageErgebnis.next()==true)
	    {
	      this.setArtikelNr(Integer.parseInt(abfrageErgebnis.getString("Artikelnummer")));
	      this.setArtikelBez(abfrageErgebnis.getString("Artikelbezeichnung"));
	      this.setArtikelEKP(Double.parseDouble(abfrageErgebnis.getString("Einkaufspreis")));
	      this.setArtikelBestand(Integer.parseInt(abfrageErgebnis.getString("Bestand")));
	     }
	  } 
	  
	catch (Exception e)
	{ 
		JOptionPane.showMessageDialog(null, "Auslesen fehlgeschlagen "+e);
	}


Wenn ich das nun ausführe, kommt keine Fehlermeldung und auch sonst keine Nachricht und in der GUI wird in den entsprechenden Textfeldern der Wert 0 angezeigt.
Das Textfeld Artikelbezeichnung bleibt komplett leer, also nicht mal 0.

Und wie kann ich es umsetzen, dass wenn ich bei Artikelnummer 1 angebe, mir der entsprechende Datensatz angezeigt wird?
 

Anhänge

  • Lager.JPG
    Lager.JPG
    24,2 KB · Aufrufe: 303
  • GUI.JPG
    GUI.JPG
    25,8 KB · Aufrufe: 328
Zuletzt bearbeitet:
Speicher doch mal in der zeige()-Funktion ALLE Werte in einen String (also immer anhängen mit z.B.
Code:
out = out + "|" + abfrageErgebnis.getString("Artikelnummer") + "|";
Und das gibst du dann in ein Textfeld aus. Oder du gibst die Felder einfach gleich auf die Konsole aus mit System.out.println().
// Im Resultset von der Stelle 0 auf den ersten Datensatz springen
Also eigtl. springt der durch die Schleife bis zum letzten Datensatz. Möglicherweise ist der auch leer und es liegt daran? Du könntest auch versuchen statt der Spaltenbezeichnung mal testweise die Spaltennummer zu verwenden. Außerdem kannst du mit abfrageErgebnis.getMetaData() Zugriff auf die Metadaten bekommen (z.B. Spaltennamen usw.). Interessant ist da vor Allem dann getColumnCount() damit man sieht ob überhaupt was kommt.

Achja und bitte IMMER Resultset und Statement (und evtl. auch die Connection wenn du sie länger nicht brauchst) schließen wenn du sie nimmer brauchst.
 
Zuletzt bearbeitet:
Ich hab den Fehler gefunden: Habe vergessen die zeige()-Methode in der Fensterklasse aufzurufen.

Jetzt kommt als Fehlermeldung: "Auslesen fehlgeschlagen java.lang.NullPointerException"

Kann mir jemand bitte sagen, wie ich dieses Problem nun beheben kann?

________________________________________________________________________________

Hat sich auch erledigt!
Habs einfach nochmal neu geschrieben und ein bisschen umgeändert und auf einmal klappts.

Allerings habe ich immer noch folgendes Problem:
Code:
while (resultSet.next())
{
	this.setArtikelNr(Integer.parseInt(resultSet.getString("Artikelnummer")));
	this.setArtikelBez(resultSet.getString("Artikelbezeichnung"));
	this.setArtikelEKP(Double.parseDouble(resultSet.getString("Einkaufspreis")));
	this.setArtikelBestand(Integer.parseInt(resultSet.getString("Bestand")));
}

Wenn ich nun SELECT * als Auswahl festlege, kommt immer nur der letzte Datensatz, da er die andern ja überspringt. Wie kann ich nun festlegen, dass er alle ausgibt?
 
Zuletzt bearbeitet:
Wie kommst du darauf, dass bei "SELECT *" was überprungen wird? Das Problem sind wohl eher die set-Methoden in der while-Schleife, die immer den vorherigen Wert überschreiben.
 
Oh, hast natürlich vollkommen recht, weriß auch nicht an was ich da grad gedacht hab...

Weiß vllt jemand wie alles ausgegeben wird, ohne dass die Werte überschrieben werden?
Mir fällt da gar nichts zu ein, und mit meinem Buch hier komm ich auch nicht mehr weiter.
 
Hallo,

ich versuche gerade eine DB Verbindung herzustellen.

Ich habe folgende Fehlermeldung:
java.lang.ClassNotFoundException: sun.jdbc.odbc.Jdbc0dbcDriver
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
Treiber konnte nicht erfolgreich geladen
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at deportfoliomanagement.DbVerbindungAccess.driver(DbVerbindungAccess.java:33)
at deportfoliomanagement.GuiRsl.abfragen(GuiRsl.java:77)
at deportfoliomanagement.GuiRsl.<init>(GuiRsl.java:26)
at deportfoliomanagement.Main.main(Main.java:34)

PHP:
 public static Connection driver()
    {
        Connection conn = null;
        try{
        
            
            Class.forName("sun.jdbc.odbc.Jdbc0dbcDriver");
            System.out.println("Treiber erfolgreich geladen");
        }
         catch (ClassNotFoundException cex)
        {
            cex.printStackTrace();
            System.out.println("Treiber konnte nicht erfolgreich geladen");
        }
        try{
            
            String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:/Programme/Quaccess/Quaccess.mdb";
            String username="";
            String passwort="";
            
            
            //Verbindung mit der Datenbank wird geöffnet
            conn = DriverManager.getConnection(url, username, passwort);      
           }
       
          catch (SQLException sqlex)
        {
            sqlex.printStackTrace();
        }
           catch (Exception ex)
        {
            ex.printStackTrace();
        }
        
        return conn;
    }

Ich habe mir die vorherigen Nachrichten durchgelesen und komme nicht weiter.

Bei Netbeans in meinem Projekt steht unter Libraries\JDK 1.6\ rt.jar, so dass ich dachte der OBCD -Treiber müßte installiert sein.

Ich habe auch unte Verwaltung\Datenquellen(OBCD) und dann unter Benutzerquellen: Microsoft Access-Datenbank, die Datenbank Quaccess hinzugefügt.

Ich bin nun schon seit ein paar Stunden am ausprobieren. Ich wäre euch dankbar, falls mir jemand helfen könnte.

Ich
 
Versuch mal statt:
Code:
Class.forName("sun.jdbc.odbc.Jdbc[U]0[/U]dbcDriver");
das hier zu nehmen:
Code:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

Du hast ne 0 (sprich: Null) statt O eingetippt.
 
verdammt! Eigentlich hatte ich es gestern auch schon nachgeschaut, ob es ein O oder eine Null ist, egal.

Vielen Dank- Jetzt funktioniert es bzw. die Fehlermeldung ist weg
 
Zurück
Oben