Tårar och smärta

Fel kan uppstå när ett Java-program körs. När man arbetar med databasen uppstår fel . Allt handlar om vilka av dem du kan förutse och erbjuda en adekvat lösning.

Den första stora gruppen av fel kommer att vänta på dig när du kör den här raden:

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

Vad kan du förvänta dig här?

Fel 1. Drivrutinen hittades inte .

Om du får felet "Ingen lämplig drivrutin hittades för ..." betyder det att DriverManager inte kunde förstå vilken typ av DBMS som ligger bakom din URL. Till exempel skrev du jdbc_mysql: istället för jdbc:mysql:

Fel 2. Anslutningsfel .

Om du gör ett misstag i värdnamnet kommer du med största sannolikhet att få ett meddelande som "Ingen sådan värd är känd" eller "Kommunikationslänkfel".

Fel 3. Databasnamnet är felaktigt .

Om du stavat databasnamnet fel eller ansluter till en annan server där det inte finns, får du ett meddelande som " Okänd databas 'supershop3'" .

Fel 4. Fel inloggning eller lösenord .

Om du har glömt databaslösenordet eller skrivit in det felaktigt, kommer du troligen att få ett meddelande som " Åtkomst nekad för användaren 'root'@'localhost' (med lösenord: YES)" .

SQL-undantag

Om anslutningen till basen ändå är etablerad, kommer det att bli mer intressant ytterligare. Vid fel när man arbetar med databasen har JDBC ett speciellt undantag - java.sql.SQLException . Samt flera av dess sorter.

Detta undantag har bara en ytterligare metod (jämfört med klassen Exception) - metoden getSQLState(), som returnerar statuskoden (strängen) som SQL-servern returnerade till den. Felhanteringen ser ut så här:

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 finns hundratals felkoder. Du kan se hela listan här .

Men ibland hjälper felkoder JDBC att förstå felet bättre och då kastar det inte bara SQLException, utan specialiserad SQLException:

BatchUpdateException Fel under gruppförfrågan
DataTruncation Uppstår ofta vid trunkering av långa data
SQLClientInfoException Klienten skickade parametrar som inte kan ställas in på anslutningen: Anslutning
SQLDataException Fel med data, detaljer beror på typen av DBMS
SQLException Databasåtkomstfel eller andra allmänna fel
SQLFeatureNotSupportedException DBMS stöder inte denna funktion
SQLIntegrityConstraintViolationException Alla fel med för SQLState ==22
SQLInvalidAuthorizationSpecException Åtkomst- och/eller auktoriseringsfel
SQLNonTransientConnectionException Alla fel med för SQLState ==08
SQLRecoverableException Det finns ett fel, men det kan åtgärdas med hjälp av ansökan
SQLSyntaxErrorException Fel i frågesyntax
SQLTimeoutException Begäran tog för lång tid
SQLTransactionRollbackException Fel under återställning av transaktion
SQL-varning Varning utfärdad av DBMS

Exempel på fel

Om ett fel inträffade i serverapplikationsstadiet kan det vanligtvis bara loggas och sedan behandlas mer detaljerat. Men om det hände medan applikationen kördes på programmerarens dator, måste du noggrant undersöka orsaken till detta.

Det finns två största felklasser när man arbetar med en databas:

  • Begär textfel
  • Fel vid arbete med ResultSet

Ett fel i förfrågningstexten kan uppstå mycket ofta. Frågan kan vara mycket lång, innehålla flera tabeller (sammanfogade via JOIN) och underfrågor (SUBSELECT). Det är inte lätt att hitta ett fel i en sådan begäran. Dessutom limmas förfrågningar ofta ihop från delar, data läggs till där.

Det allra första felet du bör vara medveten om är SQLSyntaxErrorException . Ett sådant fel innebär vanligtvis att du har ett stavfel i förfrågan.

Låt oss ta vårt favoritexempel:

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

Och "av misstag" radera asterisken i förfrågan:

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

Då får vi ett undantag:

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-servern berättar att det fanns ett syntaxfel innan FROM.

Vi tittar noga på förfrågan och funderar. Om ingenting kommer att tänka på, och detta händer väldigt ofta, måste du be någon att se vad som är fel.

Ett annat populärt misstag är felaktigt arbete med ResultSet - resultatet av begäran. Anta att du glömde att innan du läste data kommer den "aktuella raden" i ResultSet-objektet före den första raden, då kommer du att ha följande kod:

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

Du kommer att få detta fel:


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 tittar noga på felet och funderar. Sedan googlar vi och hittar ett par exempel och försöker förstå lösningen.