# Fehlerhandling bei JDBC



## famco (23. Mrz 2011)

Hallo,
ich verwende folgenden Code um auf eine Datenbank zuzugreifen:

```
try {           
            Class.forName("net.sourceforge.jtds.jdbc.Driver");          // Treiber laden, Verbindung herstellen
            Connection conn = DriverManager.getConnection("jdbc:jtds:sqlserver://localhost/testdb;instance=test", "sa", "*****");
            System.out.println("connected");
            Statement stmt = conn.createStatement();              
            ResultSet rs = stmt.executeQuery("select * from personen"); // Statement ausführen
            while (rs.next()) {
                System.out.printf("%5d %10s %20s %5s\n", rs.getLong("pnr"), rs.getString("vorname"), rs.getString("name"), rs.getString("knrhex"));
            }
            conn.close();
            System.out.println("closed");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
```
Im Fehlerfall läuft das ganze wir geplant in den catch-Teil.
Allerdings bietet die Exception nur sehr wenig Möglichkeiten (GetMessage()) den Fehler auszulesen. SQLState ist leider nicht öffentlich und hat auch keinen getter.
Wie komme ich an den Fehlercode ? Wie macht Ihr soetwas ?
Danke


----------



## Javacode (23. Mrz 2011)

Hey, ich würde in dem Fall einfach Breakpoints setzen und das ganze im Debug Modus Schritt für Schritt abarbeiten. Dann solltest du auch an deine Fehlerquelle stoßen.

Ansonsten: den StackTrace ausgeben lassen, log4j benutzen 

Grüße,
Javacode


----------



## famco (23. Mrz 2011)

ich glaube Du hast mich falsch verstanden. Das Programm läuft im Moment ohne Fehler 

Meine Frage betrifft das generelle Fehlerhandling: ich würde gerne im Programm gezielt auf bestimmte Meldungen reagieren können. Aber leider liefert mir die Exception keinen vernünftigen Code, sondern nur einen String, den ich mit getMessage abholen kann ....


----------



## Javacode (23. Mrz 2011)

Aso Ok jetzt verstehe ich.

Kurzer Review zu deinem Code:

Bei so viel arten an Anweisungen in einem try catch Block wirds schwer sein.

1. Du solltest die DB Connection auslagern.
2. Datenbank anfragen am besten auch auslagern
3. Exception Klassen entwickeln (Dies wäre möglich wenn du die Punkte 1-2 befolgst dann hast du nämlich den Fehlerkreis eingegrenzt und kannst dementsprechende Exceptions werfen)
4. im catch Block dann die jeweilige Exception werfen mit: throw new NamederException mit dem (e) + solltest dann auch natürlich die Passende Exception werfen. Bsp. bei SQL Sachen (SQLException e) und so weiter.

Grüße,
Javacode


----------



## famco (23. Mrz 2011)

Ja, das hört sich gut an. 
Habe halt Jahrzehnte C und VFP(oop) programmiert und bin jetzt ins JAVA-Wasser geworfen worden   aber es ist warm und ich bin noch nicht untergegangen ... 
Was mich stört ist, das die SQL Exception mir nicht den Fehlercode der Datenbank liefert. Weisst Du etwas darüber? Oder habe ich da etwas ganz falsch verstanden ?

Danke


----------



## maki (23. Mrz 2011)

Die SQL Exception message wird dir IME sehr wohl u.a. den Fehlercode der DB enthalten, wenn denn einer vorhanden ist.
Manchmal treten die Fehler nämlich schon vor der DB auf 

Die Frage ist doch, was möchtest du mit einem eventuellen Fehlercode machen?


----------



## JimPanse (23. Mrz 2011)

noch besser wäre wenn du:


```
Connection conn = null;

try {           
            Class.forName("net.sourceforge.jtds.jdbc.Driver");         
             conn = DriverManager.getConnection("jdbc:jtds:sqlserver://localhost/testdb;instance=test", "sa", "*****");
           
             Statement stmt = conn.createStatement();              
            ResultSet rs = stmt.executeQuery("select * from personen"); 
            ...
                // würde nicht aufgerufen werden, wenn ein Fehler eintritt!
               //conn.close();

        } catch (Exception e) {
            System.out.println(e.getMessage());
            throw new DeineExceptionKlasse(e);
        }finally {
             
             if(con != null)try {  conn.close(); } catch (Exception e) {throw new DeineExceptionKlasse(e);}
        }
```

das schließen der Connection im finally Block auslagerst! Denn dann wird auch im Fehlerfall die Verbindung immer geschlossen! Immomement würde im Fehlerfall bsp. dein SQL-Statement ist nicht valid eine Exception geworfen und deine Verbindung wird nicht geschlossen werden!

Grüße


----------



## famco (23. Mrz 2011)

im Debugger sehe ich das Attribut mit dem Fehlercode durchaus (SQLState). Aber es ist nicht öffentlich und es gibt keine get-Methode um es auszulesen.
Was ich damit machen möchte ist ganz einfach:  Im Fehlerfall (z.B. beim Aufbau der Verbindung) dem Anwender die Klartextmeldung anzeigen und zusätzlich den Fehlercode der Datenbank, um einem eventuellen Telefonsupporter einen etwas genaueren Hinweis zu geben, warum(!) der Connect nicht funktioniert hat.
Der MS-SQL-Server liefert da durchaus verschiedene Codes, aber die Meldung ist immer die gleich allgemein gehalten.


----------



## maki (23. Mrz 2011)

Habe jetzt nochmals nachgesehen in der JDBC API Doku, würde ich dir auch empfehlen 

Du kannst bei SQLException sehr wohl den SQLState abfragen (getSQLState), und den ErrorCode (getErrorCode) auch.

SQLException (Java Platform SE 6)


----------



## famco (23. Mrz 2011)

oh, mein Fehler. Ich hatte mich auf die Codevervollständigung von NetBeans verlassen und die zeigt nur GetMessage()

Sorry ...

und Danke für die Hilfe.


----------

