Java JDBC处理SQLExceptions

x33g5p2x  于2022-10-07 转载在 Java  
字(3.4k)|赞(0)|评价(0)|浏览(1047)

在这篇文章中,我们将讨论如何处理在与数据源交互时遇到的SQLExceptions

SQLException的概述

当JDBC在与数据源的交互中遇到错误时,它会抛出一个SQLException的实例,而不是Exception。(在这种情况下,数据源代表连接对象所连接的数据库)。SQLException实例包含以下信息,可以帮助你确定错误的原因。

  • 错误的描述 - 通过调用SQLException.getMessage方法检索包含该描述的字符串对象。
  • 一个SQLState代码 - 这些代码和它们各自的含义已经被ISO/ANSI和Open Group(X/Open)标准化,尽管有些代码被保留给数据库供应商自己定义。这个字符串对象由五个字母数字字符组成。通过调用SQLException.getSQLState方法检索这个代码。
  • 错误代码 - 这是一个整数值,用于识别导致SQLException实例被抛出的错误。它的值和含义是特定的,可能是由底层数据源返回的实际错误代码。通过调用SQLException.getErrorCode方法来获取错误。
  • 一个原因 - 一个SQLException实例可能有一个因果关系,它由一个或多个导致SQLException实例被抛出的Throwable对象组成。要浏览这个因果链,可以递归地调用SQLException.getCause方法,直到返回一个空值。
  • 对任何连锁异常的引用 - 如果发生了一个以上的错误,则通过这个连锁来引用这些异常。通过对被抛出的异常调用方法SQLException.getNextException来检索这些异常。

检索异常

让我们写一个通用的方法来检索SQLException中包含的SQLState、错误代码、错误描述和原因(如果有的话),以及任何其他与之相连的异常链。

  1. public static void printSQLException(SQLException ex) {
  2. for (Throwable e: ex) {
  3. if (e instanceof SQLException) {
  4. if (ignoreSQLException(((SQLException) e).getSQLState()) == false) {
  5. e.printStackTrace(System.err);
  6. System.err.println("SQLState: " + ((SQLException) e).getSQLState());
  7. System.err.println("Error Code: " + ((SQLException) e).getErrorCode());
  8. System.err.println("Message: " + e.getMessage());
  9. Throwable t = ex.getCause();
  10. while (t != null) {
  11. System.out.println("Cause: " + t);
  12. t = t.getCause();
  13. }
  14. }
  15. }
  16. }
  17. }

例如,如果我们的SQL语句有一个语法错误,那么上述方法会打印出以下结果:

  1. SQLState: 42000
  2. Error Code: 1064
  3. Message: 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 'where id = 3' at line 1

我们可以不输出SQLException信息,而是先检索SQLState,然后再相应地处理SQLException。例如,下面的ignoreSQLException()方法在SQLState等于代码42Y55时返回true(并且你使用Java DB作为你的DBMS),这使得上面的printSQLException()方法忽略了SQLException

  1. public static boolean ignoreSQLException(String sqlState) {
  2. if (sqlState == null) {
  3. System.out.println("The SQL state is not defined!");
  4. return false;
  5. }
  6. // X0Y32: Jar file already exists in schema
  7. if (sqlState.equalsIgnoreCase("X0Y32"))
  8. return true;
  9. // 42Y55: Table already exists in schema
  10. if (sqlState.equalsIgnoreCase("42Y55"))
  11. return true;
  12. return false;
  13. }

检索警告

SQLWarning对象是SQLException的一个子类,处理数据库访问警告。警告不会像异常那样停止应用程序的执行;它们只是提醒用户某些事情没有按计划发生。例如,一个警告可能让你知道你试图撤销的特权没有被撤销。或者一个警告可能会告诉你,在请求断开连接时发生了错误。

下面的方法说明了如何获得关于Statement或ResultSet对象上报告的任何警告的完整信息。

  1. public static void getWarningsFromResultSet(ResultSet rs)
  2. throws SQLException {
  3. printWarnings(rs.getWarnings());
  4. }
  5. public static void getWarningsFromStatement(Statement stmt)
  6. throws SQLException {
  7. printWarnings(stmt.getWarnings());
  8. }
  9. public static void printWarnings(SQLWarning warning)
  10. throws SQLException {
  11. if (warning != null) {
  12. System.out.println("\n---Warning---\n");
  13. while (warning != null) {
  14. System.out.println("Message: " + warning.getMessage());
  15. System.out.println("SQLState: " + warning.getSQLState());
  16. System.out.print("Vendor error code: ");
  17. System.out.println(warning.getErrorCode());
  18. System.out.println("");
  19. warning = warning.getNextWarning();
  20. }
  21. }
  22. }

最常见的警告是DataTruncation警告,是SQLWarning的子类。所有的DataTruncation对象的SQLState都是01004,表明在读或写数据时出现了问题。DataTruncation方法可以让你发现在哪一列或参数中的数据被截断,截断是在读或写操作中,有多少字节应该被传输,以及有多少字节实际被传输。

分类的SQLExceptions

你的JDBC驱动程序可能会抛出一个SQLException的子类,它对应于一个普通的SQLState或一个普通的错误状态,而这个错误状态并不与特定的SQLState类值相关。这使你能够写出更多可移植的错误处理代码。这些异常是以下类之一的子类。

  • SQLNonTransientException
  • SQLTransientException
  • SQLRecoverableException

SQLException的其它子类

以下是SQLException的子类,也可以抛出。

  • BatchUpdateException是在批量更新操作中发生错误时抛出的。除了SQLException提供的信息外,BatchUpdateException还提供在错误发生前执行的所有语句的更新计数。
  • SQLClientInfoException是在一个或多个客户信息属性无法在连接上设置时抛出的。除了SQLException提供的信息外,SQLClientInfoException还提供了一个没有设置的客户信息属性的列表。

相关文章

最新文章

更多