淚與痛
運行 Java 程序時可能會出現錯誤。使用數據庫時,會發生錯誤。這完全取決於您可以預測其中的哪些並提供適當的解決方案。
執行此行時,第一大組錯誤將等待您:
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "secret");
你能在這裡期待什麼?
錯誤 1.未找到驅動程序。
如果您收到錯誤“No suitable driver found for …”,這意味著 DriverManager 無法理解您的 URL 後面的 DBMS 類型。例如,你寫了 jdbc_mysql: 而不是 jdbc:mysql:
錯誤 2.連接錯誤。
如果您輸入的主機名有誤,您很可能會收到類似“不知道這樣的主機”或“通信鏈接失敗”之類的消息。
錯誤3,數據庫名稱不正確。
如果您拼錯了數據庫名稱或連接到另一個不存在的服務器,您將收到一條消息,如“Unknown database 'supershop3'”。
錯誤 4.登錄名或密碼錯誤。
如果您忘記了數據庫密碼或輸入錯誤,那麼您很可能會收到類似“用戶 'root'@'localhost'(使用密碼:YES)的訪問被拒絕”的消息。
SQL異常
如果仍然建立了與基地的聯繫,那麼它將更加有趣。如果在使用數據庫時出錯,JDBC 有一個特殊的異常 - java.sql.SQLException。以及它的幾個品種。
這個異常只有一個額外的方法(與Exception類相比)——getSQLState()方法,它返回SQL服務器返回給它的狀態碼(字符串)。錯誤處理如下所示:
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();
}
有數百個錯誤代碼。您可以在此處查看完整列表。
但有時錯誤代碼有助於 JDBC 更好地理解錯誤,然後它不僅拋出 SQLException,而且拋出專門的 SQLException:
批量更新異常 | 群組請求期間出錯 |
數據截斷 | 經常發生在截斷長數據時 |
SQLClientInfoException異常 | 客戶端傳遞了無法在連接上設置的參數:Connection |
SQL數據異常 | 數據錯誤,詳細信息取決於 DBMS 的類型 |
SQL異常 | 數據庫訪問錯誤或其他一般錯誤 |
SQLFeatureNotSupportedException | DBMS 不支持此功能 |
SQLIntegrityConstraintViolationException | SQLState ==22 的所有錯誤 |
SQLInvalidAuthorizationSpecException | 訪問和/或授權錯誤 |
SQLNonTransientConnectionException | SQLState ==08 的所有錯誤 |
SQLRecoverableException | 有錯誤,但可以通過應用程序的干預來修復 |
SQL語法錯誤異常 | 查詢語法錯誤 |
SQL超時異常 | 請求時間過長 |
SQLTransactionRollbackException | 事務回滾時出錯 |
SQL警告 | DBMS發出的警告 |
錯誤示例
如果在服務器應用階段發生了錯誤,那麼通常只能記錄下來,然後再進行更詳細的處理。但如果它是在應用程序在程序員的計算機上運行時發生的,那麼您需要仔細調查其原因。
使用數據庫時有兩類最大的錯誤:
- 請求文本錯誤
- 使用 ResultSet 時出錯
請求文本中的錯誤經常發生。查詢可以很長,包含多個表(通過 JOIN 連接)和子查詢 (SUBSELECT)。在這樣的請求中不容易發現錯誤。此外,請求通常由多個部分粘合在一起,在那裡添加數據。
您應該注意的第一個錯誤是SQLSyntaxErrorException。這種錯誤通常意味著您在請求正文中有錯別字。
讓我們舉一個我們最喜歡的例子:
ResultSet results = statement.executeQuery("SELECT Count(*) FROM user");
results.next();
int count = results.getInt(1);
並“不小心”刪除了請求正文中的星號:
ResultSet results = statement.executeQuery("SELECT Count() FROM user");
results.next();
int count = results.getInt(1);
然後我們會得到一個異常:
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 Server 告訴我們 FROM 之前有一個語法錯誤。
我們仔細查看請求並思考。如果什麼都沒有想到,而且這種情況經常發生,那麼你需要請人看看哪裡出了問題。
另一個常見的錯誤是不正確地使用 ResultSet——請求的結果。假設你忘記了在讀取數據之前,ResultSet對象的“當前行”排在第一行之前,那麼你就會有如下代碼:
ResultSet results = statement.executeQuery("SELECT Count(*) FROM user");
// results.next();
int count = results.getInt(1);
你會得到這個錯誤:
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)
大家仔細看看錯誤,思考一下。然後我們谷歌並找到幾個例子並嘗試理解解決方案。
GO TO FULL VERSION