JDBC - 異常處理



異常處理允許您以受控的方式處理異常情況,例如程式定義的錯誤。

當發生異常情況時,會丟擲異常。“丟擲”表示當前程式執行停止,控制權重定向到最近適用的 catch 子句。如果不存在適用的 catch 子句,則程式執行結束。

JDBC 異常處理與 Java 異常處理非常相似,但對於 JDBC,您將處理的最常見異常是java.sql.SQLException。

SQLException 方法

SQLException 既可能發生在驅動程式中,也可能發生在資料庫中。當發生此類異常時,型別為 SQLException 的物件將傳遞到 catch 子句。

傳遞的 SQLException 物件具有以下可用於檢索有關異常的附加資訊的方法:

方法 描述
getErrorCode( ) 獲取與異常關聯的錯誤號。
getMessage( ) 獲取 JDBC 驅動程式的錯誤訊息(由驅動程式處理的錯誤),或獲取資料庫錯誤的 Oracle 錯誤號和訊息。
getSQLState( ) 獲取 XOPEN SQLstate 字串。對於 JDBC 驅動程式錯誤,此方法不會返回任何有用的資訊。對於資料庫錯誤,將返回五位數的 XOPEN SQLstate 程式碼。此方法可能返回 null。
getNextException( ) 獲取異常鏈中的下一個 Exception 物件。
printStackTrace( ) 將當前異常或可丟擲物件及其回溯列印到標準錯誤流。
printStackTrace(PrintStream s) 將此可丟擲物件及其回溯列印到您指定的列印流。
printStackTrace(PrintWriter w) 將此可丟擲物件及其回溯列印到您指定的列印寫入器。

透過利用從 Exception 物件中獲得的資訊,您可以捕獲異常並適當地繼續您的程式。以下是 try 塊的一般形式:

try {
   // Your risky code goes between these curly braces!!!
}
catch(Exception ex) {
   // Your exception handling code goes between these 
   // curly braces, similar to the exception clause 
   // in a PL/SQL block.
}
finally {
   // Your must-always-be-executed code goes between these 
   // curly braces. Like closing database connection.
}

在 JDBC 示例中使用 try catch 塊

學習下面的示例程式碼以瞭解try....catch 塊的用法。在此示例中,我們有四個靜態字串用於資料庫連線字串、使用者名稱、密碼和一個呼叫儲存過程的 SQL 查詢。在 main 方法中,我們使用 DriverManager.getConnection() 方法準備與資料庫的連線。我們使用 connection.prepareCall() 方法準備了一個 CallableStatement。下一步,設定佔位符值並註冊輸出引數。最後,使用 CallableStatement.execute() 方法呼叫儲存過程,並使用 getString() 方法檢索員工姓名。在 catch() 語句中,我們處理 SQL 異常。由於使用了 try-with-resources,因此不需要 finally 語句,連線物件在 try-catch 語句完成後會自動關閉。

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class JDBCExample {
   static final String DB_URL = "jdbc:mysql:///TUTORIALSPOINT";
   static final String USER = "guest";
   static final String PASS = "guest123";
   static final String QUERY = "{call getEmpName (?, ?)}";

   public static void main(String[] args) {
      // Open a connection
      try(Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
         CallableStatement stmt = conn.prepareCall(QUERY);
      ) {		      
         // Bind values into the parameters.
         stmt.setInt(1, 1);  // This would set ID
         // Because second parameter is OUT so register it
         stmt.registerOutParameter(2, java.sql.Types.VARCHAR);
         //Use execute method to run stored procedure.
         System.out.println("Executing stored procedure..." );
         stmt.execute();
         //Retrieve employee name with getXXX method
         String empName = stmt.getString(2);
         System.out.println("Emp Name with ID: 1 is " + empName);
      } catch (SQLException e) {
         e.printStackTrace();
      } 
   }
}

現在,讓我們按如下方式編譯上述示例:

C:\>javac JDBCExample.java
C:\>

如果您執行JDBCExample,如果沒有任何問題,它將產生以下結果;否則,將捕獲相應的錯誤並顯示錯誤訊息:

C:\>java JDBCExample
Executing stored procedure...
Emp Name with ID: 1 is Zara
C:\>

嘗試透過傳遞錯誤的資料庫名稱或錯誤的使用者名稱或密碼來執行上述示例,並檢查結果。

針對無效表名處理 SQLException 並使用 JDBC 示例中的錯誤程式碼

在此示例中,我們有三個靜態字串用於資料庫連線字串、使用者名稱、密碼。在 main 方法中,我們使用 DriverManager.getConnection() 方法準備與資料庫的連線。我們使用 connection.createStatement() 方法準備了一個 Statement。使用 statement.executeQuery() 執行帶有無效表名的查詢,這將導致 SQLException。異常在 catch 塊中處理,並列印錯誤程式碼、SQL 狀態和詳細的錯誤訊息。

import java.sql.*; 
 
public class JDBCExceptionExample {
    static final String MYSQL_URL = "jdbc:mysql:///TUTORIALSPOINT";
    static final String USER_NAME = "guest";
    static final String PASSWORD = "guest123";
    
    public static void main(String args[]) {
        try{            
            Connection conn = DriverManager.getConnection(MYSQL_URL, USER_NAME, PASSWORD);
            
            Statement stmt = conn.createStatement();
            // Giving incorrect table name to get Exceptions
            ResultSet rs = stmt.executeQuery("SELECT * FROM EMPLOYEES10");
            
            while( rs.next()){
                System.out.println("ID:" + rs.getInt("id"));
                System.out.println(", Age: " + rs.getInt("age"));
            }
            
        }catch(SQLException e){
            int errorCode = e.getErrorCode();
            String sqlState = e.getSQLState();
            String errorMsg = e.getMessage();
            
            System.out.println("Error code: " + errorCode);
            System.out.println("SqlState: " + sqlState);
            System.out.println("Error Message: " + errorMsg);
            
            e.printStackTrace();
        }
    }
}

輸出

現在,讓我們按如下方式編譯上述示例:

C:\>javac JDBCExceptionExample.java
C:\>

執行JDBCExceptionExample時,它會產生以下結果:

C:\>java JDBCExceptionExample
Error code: 1146
SqlState: 42S02
Error Message: Table 'tutorialspoint.employees10' doesn't exist
java.sql.SQLSyntaxErrorException: Table 'tutorialspoint.employees10' doesn't exist
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:112)
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:113)
	at com.mysql.cj.jdbc.StatementImpl.executeQuery(StatementImpl.java:1286)
	at JDBCExceptionExample.main(JDBCExceptionExample.java:26)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at jdk.compiler/com.sun.tools.javac.launcher.Main.execute(Main.java:484)
	at jdk.compiler/com.sun.tools.javac.launcher.Main.run(Main.java:208)
	at jdk.compiler/com.sun.tools.javac.launcher.Main.main(Main.java:135)

C:\>

針對無效列名處理 SQLException 並使用 JDBC 示例中的錯誤程式碼

在此示例中,我們有三個靜態字串用於資料庫連線字串、使用者名稱、密碼。在 main 方法中,我們使用 DriverManager.getConnection() 方法準備與資料庫的連線。我們使用 connection.createStatement() 方法準備了一個 Statement。使用 statement.executeQuery() 執行帶有無效列名的查詢,這將導致 SQLException。異常在 catch 塊中處理,並列印錯誤程式碼、SQL 狀態和詳細的錯誤訊息。

import java.sql.*;

public class JDBCExceptionExample {
    
    static final String MYSQL_URL = "jdbc:mysql:///TUTORIALSPOINT";
    static final String USER_NAME = "guest";
    static final String PASSWORD = "guest123";
    
    public static void main(String args[]) {
        try{
            Connection conn = DriverManager.getConnection( MYSQL_URL, USER_NAME, PASSWORD);
            System.out.println("Connection to db established..");
            String query = "select * from employees";
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            System.out.println("Successfully executed query.");
            while(rs.next()){
                System.out.println("Intentionally giving emp_id column name, when the correct "
                        + "one is: id. Giving this, to see exception handling.");
                System.out.println("ID: " + rs.getString("emp_id"));
            }
        }catch(SQLException e){
            Throwable t = e.getCause();
            System.out.println("Exception caught. Cause: " + t.toString());
            System.out.println("------------------------------------");
            e.printStackTrace();
        }
    }
}

輸出

現在,讓我們按如下方式編譯上述示例:

C:\>javac JDBCExceptionExample.java
C:\>

執行JDBCExceptionExample時,它會產生以下結果:

C:\>java JDBCExceptionExample
Connection to db established..
Successfully executed query.
Intentionally giving emp_id column name, when the correct one is: id. Giving this, to see exception handling.
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.Throwable.toString()" because "" is null
	at JDBCExceptionExample.main(JDBCExceptionExample.java:55)

C:\>
廣告