Tårer og smerte

Det kan oppstå feil under kjøring av et Java-program. Når du arbeider med databasen vil det oppstå feil. Det handler om hvilke av dem du kan forutsi og tilby en adekvat løsning.

Den første store gruppen av feil vil vente på deg når du utfører denne linjen:

Connection connection  = DriverManager.getConnection("jdbc:mysql://localhost:3306/test",  "root", "secret");

Hva kan du forvente her?

Feil 1. Driver ikke funnet .

Hvis du får feilmeldingen "Ingen passende driver funnet for ..." betyr det at DriverManager ikke kunne forstå hvilken type DBMS som ligger bak URL-en din. For eksempel skrev du jdbc_mysql: i stedet for jdbc:mysql:

Feil 2. Tilkoblingsfeil .

Hvis du gjør en feil i vertsnavnet, vil du mest sannsynlig få en melding som "Ingen slik vert er kjent" eller "Communications link failure".

Feil 3. Databasenavnet er feil .

Hvis du feilstavet databasenavnet eller kobler til en annen server der det ikke eksisterer, vil du få en melding som "Ukjent database 'supershop3'" .

Feil 4. Feil pålogging eller passord .

Hvis du har glemt databasepassordet eller skrevet det inn feil, vil du mest sannsynlig motta en melding som "Tilgang nektet for brukeren 'root'@'localhost' (bruker passord: JA)" .

SQL-unntak

Hvis forbindelsen til basen likevel er etablert, vil det være mer interessant videre. Ved feil ved arbeid med databasen har JDBC et spesielt unntak - java.sql.SQLException . Samt flere av dens varianter.

Dette unntaket har bare én ekstra metode (sammenlignet med Exception-klassen) - metoden getSQLSate(), som returnerer statuskoden (strengen) som SQL-serveren returnerte til den. Feilhåndtering ser slik ut:

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();
 }

Det er hundrevis av feilkoder. Du kan se hele listen her .

Men noen ganger hjelper feilkoder JDBC med å forstå feilen bedre, og da kaster den ikke bare SQLException, men spesialisert SQLException:

BatchUpdateException Feil under gruppeforespørsel
DataTrunkering Oppstår ofte ved trunkering av lange data
SQLClientInfoException Klienten sendte parametere som ikke kan settes på tilkoblingen: Tilkobling
SQLDataException Feil med data, detaljer avhenger av typen DBMS
SQLException Databasetilgangsfeil eller andre generelle feil
SQLFeatureNotSupportedException DBMS støtter ikke denne funksjonaliteten
SQLIntegrityConstraintViolationException Alle feil med for SQLState ==22
SQLInvalidAuthorizationSpecException Tilgangs- og/eller autorisasjonsfeil
SQLNonTransientConnectionException Alle feil med for SQLState ==08
SQLRecoverableException Det er en feil, men den kan fikses ved hjelp av søknaden
SQLSyntaxErrorException Feil i søkesyntaks
SQLTimeoutException Forespørselen tok for lang tid
SQLTransactionRollbackException Feil under tilbakeføring av transaksjon
SQL-advarsel Advarsel utstedt av DBMS

Eksempler på feil

Hvis det oppstod en feil på stadiet av serverapplikasjonen, kan den vanligvis bare logges og deretter behandles mer detaljert. Men hvis det skjedde mens applikasjonen kjørte på programmererens datamaskin, må du nøye undersøke årsaken til dette.

Det er to største kategorier av feil når du arbeider med en database:

  • Forespørselstekstfeil
  • Feil under arbeid med ResultSet

En feil i forespørselsteksten kan oppstå svært ofte. Spørringen kan være veldig lang, inneholde flere tabeller (samlet via JOIN) og underspørringer (SUBSELECT). Det er ikke lett å finne en feil i en slik forespørsel. I tillegg er forespørsler ofte limt sammen fra deler, data legges til der.

Den aller første feilen du bør være klar over er SQLSyntaxErrorException . En slik feil betyr vanligvis at du har en skrivefeil i forespørselsteksten.

La oss ta vårt favoritteksempel:

ResultSet results = statement.executeQuery("SELECT Count(*) FROM user");
results.next();
    int count = results.getInt(1);

Og "ved et uhell" sletter stjernen i forespørselsteksten:

ResultSet results = statement.executeQuery("SELECT Count() FROM user");
results.next();
    int count = results.getInt(1);

Da får vi et unntak:

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 forteller oss at det var en syntaksfeil før FROM.

Vi ser nøye på forespørselen og tenker. Hvis ingenting kommer til tankene, og dette skjer veldig ofte, må du be noen om å se hva som er galt.

En annen populær feil er feil arbeid med ResultSet - resultatet av forespørselen. Anta at du glemte at før du leser dataene, kommer den "gjeldende raden" til ResultSet-objektet før den første raden, da vil du ha følgende kode:

ResultSet results = statement.executeQuery("SELECT Count(*) FROM user");
//    results.next();
    int count = results.getInt(1);

Du får denne feilen:


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øye på feilen og tenker. Så googler vi og finner et par eksempler og prøver å forstå løsningen.