# .dbf (IV) Datenbank einlesen



## H2SO4 (24. Apr 2009)

Hallo!

Gibt es eine Möglichkeit eine DBase .dbf vom Typ 4 auszulesen? Ich habe schon ein paar Dinge bei google gefunden, nur leider nicht für IV. StelsDBF JDBC Driver ist definitv das beste, nur ist das leider ein Trail-Version.

Habt ihr ne Lösung?


----------



## Lennart (24. Apr 2009)

Geht es um eine einmalige Migration oder um wiederholte Zugriffe?

Nur lesend oder auch schreibend?

Hast du Memofelder in der dBase-Tabelle?

Beste Grüße
Lennart


----------



## sparrow (26. Apr 2009)

Ich weiss nicht was genau das für Dateien sind mit denen ich im Moment rum spiele (sind halt das Daten-Backend einer Fremdanwendung), aber da funktioniert es ganz ausgezeichnet indem ich per JDBC-ODBC-Bridge drauf rum spiele.

Gruß
Sparrow


----------



## H2SO4 (27. Apr 2009)

Also, der Zugriff soll nur lesend erfolgen, und ja, leider habe ich ein Memo-Feld. Sonst hätte ich bei dem Programm, aus dem ich die Datenbank als Export bekomme, eine Textdatei als Ausgabeformat gewählt. Aber das eine Memo-Feld wird so leider nicht in die Datei geschrieben. Und die einzige andere Möglichkeit ist eine DBase.

Wäre echt cool wenn euch irgendwie was einfallen würde. Ich habe nämlich schon so alles durch was es gibt (ich gefunden habe =)) und nichts funktioniert. Bei diesen Programmen, die die DDase direkt als Datei auslesen, treten immer Fheler auf, wie: Feld konnte nicht konvertiert werden, oder Feld entspricht nicht Standard-Format, etc. Aber da kann ich ja nichts dran ändern.


----------



## H2SO4 (27. Apr 2009)

Ich habe es jetzt nochmal mit xBaseJ versucht. 

```
try {
	DBF dbf = new DBF("rechnung.dbf", DBF.READ_ONLY );
			
} catch (xBaseJException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
} catch (IOException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}
```

Und wie bei allen anderen Lösungen, ein Fehler wie dieser:

org.xBaseJ.xBaseJException: Wrong Version -116
	at org.xBaseJ.DBF.openDBF(DBF.java:332)
	at org.xBaseJ.DBF.<init>(DBF.java:172)
	at controlling.Import.importiereRechnungen(Import.java:656)
	at controlling.Import.main(Import.java:668)


----------



## sparrow (27. Apr 2009)

Falls du unter Windows arbeitest (unter anderen Betriebssystemen habe ich es noch nicht probiert, da ich nur für die Firma auf .dbf-Dateien zugreifen muss), hast du es schon einmal mit der ODBC-Bridge versucht?
Funktioniert hier wunderbar, auch mit Memo-Feldern.
Außerdem kann man dann "richtige" SQL-Kommandos ausführen.

Gruß
Sparrow


----------



## H2SO4 (27. Apr 2009)

Ja, habe ich. Nur als die Verbindung stand, konnte ich keine Daten auswählen, da ich den Tabellenname nicht kenne. Das Programm, aus dem ich exportiere, SHM, hat verschiedene Datenbanken. In diesem Fall gehts um die Projekt.db. Dann kann ich die vers. Spalten wählen und das Exportformat -> Rechnung.dbf , Rechnung.dbt. Die Tabelle heißt aber weder Rechung, noch Projekt. Alles ausprobiert.


----------



## sparrow (27. Apr 2009)

Vielleicht stimmt etwas mit den exportierten Daten nicht.

Ich arbeite hier, just in diesem Moment, an einem Projekt das bei einer älteren DOS-Anwendung direkt auf das Daten-Backend zugreifen soll.
Das ist soweit kein Problem, entsprechend die ODBC-Datenschnittstelle in Windows eingestellt (Systemsteuerung -> Verwaltung -> Datenquellen (ODBC) -> Hinzufügen -> Driver do Microsoft dBase) und entsprechend das Verzeichnis in dem die .dbf liegt bei Directory eingetragen.

Anschließend mit dem JDBC/ODBC-Treiber eine Verbindung zu neuen Datenquelle aufnehmen und es kann entsprechend selektiert werden. Der Tabellenname entspricht dem Dateinamen ohne .dbf. Also Z_TEXT.DBF ist die Tabelle Z_TEXT.

Bitte probier den Weg doch nochmal aus und poste hier die genaue Fehlermeldung.


Danke!

Sparrow


----------



## H2SO4 (27. Apr 2009)

Ok, hat mir schonmal ein bisschen weitergeholfen. DNS habe ich angelegt, Verbindung steht, Tabellenname findet er so wie von dir angegeben auch, nur jetzt:

java.sql.SQLException: [Microsoft][ODBC dBASE Driver] Unerwarteter Fehler vom externen Datenbanktreiber (15877).
	at sun.jdbc.odbc.JdbcOdbc.createSQLException(Unknown Source)
	at sun.jdbc.odbc.JdbcOdbc.standardError(Unknown Source)
	at sun.jdbc.odbc.JdbcOdbc.SQLExecDirect(Unknown Source)
	at sun.jdbc.odbc.JdbcOdbcStatement.execute(Unknown Source)
	at sun.jdbc.odbc.JdbcOdbcStatement.executeQuery(Unknown Source)
	at controlling.Import.importiereRechnungen(Import.java:660)
	at controlling.Import.main(Import.java:672)

Mit den exportierten Daten muss alles in Ordnung sein, da die von dem Programm so ausgegeben werden. Da habe ich wie gesagt keinen Einfluss drauf und muss sie als gegeben sehen.

Aber wenigstens nen kleinen Schritt weitergekommen...


----------



## sparrow (27. Apr 2009)

Ah genau, DNS heisst das... bin ich vorhin nicht gleich drauf gekommen.

Ich greife übrigens nur per Spaltennamen auf die Spalten zu (also ResultSet.getObject("Spaltenname"))
Ein Kollege meinte er hatte Schwierigkeiten als er mit Nummern arbeiten wollte.


Gruß
Sparrow

EDIT:
Stimmt nicht!
Aber man kann jedes Feld aus dem ResultSet nur 1x auslesen.


```
private void showTable(String dns, String table) {
        try {
            Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
            cwscon = DriverManager.getConnection("jdbc:odbc:" + dns);
            PreparedStatement st = cwscon.prepareStatement("SELECT * FROM " + table);
            ResultSet rs = st.executeQuery();
            int rowcount = 0;
            while (rs.next()) {
                rowcount++;
                System.out.println("--- DATENSATZ NR. " + rowcount + "---");
                for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
                    System.out.print(rs.getMetaData().getColumnName(i) + ": ");
                    Object obj = rs.getObject(i);
                    if (obj == null) {
                        System.out.println("NULL");
                    } else {
                        System.out.println(obj);
                    }
                }
            }
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }   
    }
```


----------

