Tårer og smerte
Der kan opstå fejl under kørsel af et Java-program. Når du arbejder med databasen, vil der opstå fejl. Det handler om, hvilken af dem du kan forudsige og tilbyde en passende løsning.
Den første store gruppe fejl venter på dig, når du udfører denne linje:
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "secret");
Hvad kan du forvente her?
Fejl 1. Driver ikke fundet .
Hvis du får fejlen "Ingen passende driver fundet til ..." betyder det, at DriverManager ikke kunne forstå, hvilken type DBMS der ligger bag din URL. For eksempel skrev du jdbc_mysql: i stedet for jdbc:mysql:
Fejl 2. Forbindelsesfejl .
Hvis du laver en fejl i værtsnavnet, vil du højst sandsynligt få en besked som "Ingen sådan vært er kendt" eller "Communications link failure".
Fejl 3. Databasenavnet er forkert .
Hvis du har stavet databasenavnet forkert eller opretter forbindelse til en anden server, hvor det ikke findes, får du en besked som "Ukendt database 'supershop3'" .
Fejl 4. Forkert login eller adgangskode .
Hvis du har glemt databaseadgangskoden eller indtastet den forkert, vil du højst sandsynligt modtage en besked som "Adgang nægtet for brugeren 'root'@'localhost' (ved hjælp af adgangskode: JA)" .
SQL-undtagelse
Hvis forbindelsen til basen alligevel er etableret, vil det være mere interessant yderligere. I tilfælde af fejl under arbejdet med databasen har JDBC en særlig undtagelse - java.sql.SQLException . Samt flere af dens varianter.
Denne undtagelse har kun én ekstra metode (sammenlignet med klassen Exception) - metoden getSQLState(), som returnerer den statuskode (streng), som SQL-serveren returnerede til den. Fejlhåndtering ser sådan ud:
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "secret");
try {
int rowsCount = statement.executeUpdate("DELETE FROM ‘Unemployees’");
} catch (SQLException ex) {
// If table doesn't exist
if (ex.getSQLState().compareTo("X0Y32") != 0) {
throw ex;
}
} finally {
connection.close();
}
Der er hundredvis af fejlkoder. Du kan se hele listen her .
Men nogle gange hjælper fejlkoder JDBC med at forstå fejlen bedre, og så kaster den ikke kun SQLException, men specialiseret SQLException:
BatchUpdateException | Fejl under gruppeanmodning |
DataTrunkering | Opstår ofte ved trunkering af lange data |
SQLClientInfoException | Klienten bestod parametre, der ikke kan indstilles på forbindelsen: Forbindelse |
SQLDataException | Fejl med data, detaljer afhænger af typen af DBMS |
SQLException | Databaseadgangsfejl eller andre generelle fejl |
SQLFeatureNotSupportedException | DBMS understøtter ikke denne funktionalitet |
SQLIntegrityConstraintViolationException | Alle fejl med for SQLState ==22 |
SQLInvalidAuthorizationSpecException | Adgangs- og/eller godkendelsesfejl |
SQLNonTransientConnectionException | Alle fejl med for SQLState ==08 |
SQLRecoverableException | Der er en fejl, men den kan rettes med applikationens indgriben |
SQLSyntaxErrorException | Fejl i forespørgselssyntaks |
SQLTimeoutException | Anmodningen tog for lang tid |
SQLTransactionRollbackException | Fejl under tilbagerulning af transaktion |
SQL-advarsel | Advarsel udstedt af DBMS |
Fejleksempler
Hvis der opstod en fejl på serverapplikationens stadium, kan den normalt kun logges og derefter behandles mere detaljeret. Men hvis det skete, mens applikationen kørte på programmørens computer, skal du omhyggeligt undersøge årsagen til dette.
Der er to største fejlklasser, når du arbejder med en database:
- Anmodningstekstfejl
- Fejl under arbejde med ResultSet
En fejl i anmodningsteksten kan forekomme meget ofte. Forespørgslen kan være meget lang, indeholde flere tabeller (sammenføjet via JOIN) og underforespørgsler (SUBSELECT). Det er ikke let at finde en fejl i en sådan anmodning. Derudover limes anmodninger ofte sammen fra dele, data tilføjes der.
Den allerførste fejl, du skal være opmærksom på, er SQLSyntaxErrorException . Sådan en fejl betyder normalt, at du har en tastefejl i forespørgselsteksten.
Lad os tage vores foretrukne eksempel:
ResultSet results = statement.executeQuery("SELECT Count(*) FROM user");
results.next();
int count = results.getInt(1);
Og "ved et uheld" slettes stjernen i anmodningsteksten:
ResultSet results = statement.executeQuery("SELECT Count() FROM user");
results.next();
int count = results.getInt(1);
Så får vi en undtagelse:
Exception in thread "main" java.sql.SQLSyntaxErrorException:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') FROM task' at line 1
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
SQL-serveren fortæller os, at der var en syntaksfejl før FROM.
Vi ser nøje på anmodningen og tænker. Hvis der ikke kommer noget i tankerne, og det sker meget ofte, så skal du bede nogen om at se, hvad der er galt.
En anden populær fejl er forkert arbejde med ResultSet - resultatet af anmodningen. Antag, at du har glemt, at før du læser dataene, kommer den "aktuelle række" af ResultSet-objektet før den første række, så vil du have følgende kode:
ResultSet results = statement.executeQuery("SELECT Count(*) FROM user");
// results.next();
int count = results.getInt(1);
Du får denne fejl:
2012 12:55:48 AM jButton5ActionPerformed
SEVERE: null
java.sql.SQLException: Before start of result set
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:982)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)
at com.mysql.jdbc.ResultSetImpl.checkRowPos(ResultSetImpl.java:841)
at com.mysql.jdbc.ResultSetImpl.getStringInternal(ResultSetImpl.java:5650)
at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5570)
Vi ser nøje på fejlen og tænker. Så googler vi og finder et par eksempler og forsøger at forstå løsningen.
GO TO FULL VERSION