文档

Java™教程
隐藏目录
处理SQLExceptions
路径: JDBC数据库访问
教程: JDBC基础

处理SQLExceptions

本页面涵盖以下主题:

SQLException概述

当JDBC在与数据源交互过程中遇到错误时,会抛出SQLException的实例,而不是Exception。(在此上下文中,数据源代表Connection对象连接的数据库。)SQLException实例包含以下信息,可以帮助您确定错误的原因:

检索异常

以下方法,JDBCTutorialUtilities.printSQLException,输出SQLException中包含的SQLState、错误代码、错误描述和原因(如果有)以及与之链接的任何其他异常:

public static void printSQLException(SQLException ex) {

    for (Throwable e : ex) {
        if (e instanceof SQLException) {
            if (ignoreSQLException(
                ((SQLException)e).
                getSQLState()) == false) {

                e.printStackTrace(System.err);
                System.err.println("SQL状态: " +
                    ((SQLException)e).getSQLState());

                System.err.println("错误代码: " +
                    ((SQLException)e).getErrorCode());

                System.err.println("消息: " + e.getMessage());

                Throwable t = ex.getCause();
                while(t != null) {
                    System.out.println("原因: " + t);
                    t = t.getCause();
                }
            }
        }
    }
}

例如,如果你使用Java DB作为你的数据库管理系统,并调用CoffeesTable.dropTable方法,而表COFFEES不存在,并且你移除了对JDBCTutorialUtilities.ignoreSQLException方法的调用,输出结果将类似于以下内容:

SQL状态: 42Y55
错误代码: 30000
消息: 因为它不存在,无法执行“DROP TABLE”操作于“TESTDB.COFFEES”。

你可以不打印SQLException信息,而是首先检索SQLState,然后根据SQLException进行处理。例如,如果SQLState等于代码42Y55(并且你使用Java DB作为你的数据库管理系统),JDBCTutorialUtilities.ignoreSQLException方法返回true,这将导致JDBCTutorialUtilities.printSQLException忽略这个SQLException

public static boolean ignoreSQLException(String sqlState) {

    if (sqlState == null) {
        System.out.println("未定义SQL状态!");
        return false;
    }

    // X0Y32: 架构中已经存在JAR文件
    if (sqlState.equalsIgnoreCase("X0Y32"))
        return true;

    // 42Y55: 架构中已经存在表
    if (sqlState.equalsIgnoreCase("42Y55"))
        return true;

    return false;
}

检索警告信息

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

警告可以在Connection对象、Statement对象(包括PreparedStatementCallableStatement对象)或ResultSet对象上报告。每个这些类都有一个getWarnings方法,你必须调用它才能看到在调用对象上报告的第一个警告。如果getWarnings返回一个警告,你可以调用SQLWarning方法getNextWarning来获取任何其他警告。执行语句会自动清除前一个语句的警告,所以它们不会积累。这意味着,如果你想要检索报告在一个语句上的警告,你必须在执行另一个语句之前这样做。

以下来自JDBCTutorialUtilities.java中的方法演示了如何获取关于StatementResultSet对象报告的任何警告的完整信息:

public static void getWarningsFromResultSet(ResultSet rs)
    throws SQLException {
    JDBCTutorialUtilities.printWarnings(rs.getWarnings());
}

public static void getWarningsFromStatement(Statement stmt)
    throws SQLException {
    JDBCTutorialUtilities.printWarnings(stmt.getWarnings());
}

public static void printWarnings(SQLWarning warning)
    throws SQLException {

    if (warning != null) {
        System.out.println("\n---警告---\n");

    while (warning != null) {
        System.out.println("消息: " + warning.getMessage());
        System.out.println("SQL状态: " + warning.getSQLState());
        System.out.print("供应商错误代码: ");
        System.out.println(warning.getErrorCode());
        System.out.println("");
        warning = warning.getNextWarning();
    }
}

最常见的警告是DataTruncation警告,它是SQLWarning的子类。所有的DataTruncation对象都有一个SQL状态码01004,表示读取或写入数据时发生了问题。DataTruncation方法可以让您查找数据在哪个列或参数中被截断,截断是读取操作还是写入操作,应该传输多少字节以及实际传输了多少字节。

分类的SQLExceptions

您的JDBC驱动程序可能会抛出SQLException的子类,对应于常见的SQL状态码或不与特定SQL状态码类值关联的常见错误状态码。这样可以编写更可移植的错误处理代码。这些异常是以下类的子类之一:

有关这些子类的更多信息,请参见java.sql包的最新Javadoc或您的JDBC驱动程序的文档。

其他SQLException的子类

还可以抛出以下SQLException的子类:


上一页: 连接数据源对象
下一页: 设置表