Documentation

The Java™ Tutorials
Hide TOC
Handling SQLExceptions处理SQLException
Trail: JDBC Database Access
Lesson: JDBC Basics

Handling SQLExceptions处理SQLException

This page covers the following topics:本页涵盖以下主题:

Overview of SQLExceptionSQLException概述

When JDBC encounters an error during an interaction with a data source, it throws an instance of SQLException as opposed to Exception. 当JDBC在与数据源的交互过程中遇到错误时,它抛出一个SQLException实例,而不是Exception实例。(A data source in this context represents the database to which a Connection object is connected.) (此上下文中的数据源表示Connection对象所连接的数据库。)The SQLException instance contains the following information that can help you determine the cause of the error:SQLException实例包含以下信息,可帮助您确定错误原因:

Retrieving Exceptions检索异常

The following method, JDBCTutorialUtilities.printSQLException outputs the SQLState, error code, error description, and cause (if there is one) contained in the SQLException as well as any other exception chained to it:以下方法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("SQLState: " +
                    ((SQLException)e).getSQLState());

                System.err.println("Error Code: " +
                    ((SQLException)e).getErrorCode());

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

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

For example, if you call the method CoffeesTable.dropTable with Java DB as your DBMS, the table COFFEES does not exist, and you remove the call to JDBCTutorialUtilities.ignoreSQLException, the output will be similar to the following:例如,如果使用Java DB作为DBMS调用方法CoffeesTable.dropTable,而且表COFFEES不存在,并且删除了对JDBCTutorialUtilities.ignoreSQLException的调用,输出将类似于以下内容:

SQLState: 42Y55
Error Code: 30000
Message: 'DROP TABLE' cannot be performed on
'TESTDB.COFFEES' because it does not exist.

Instead of outputting SQLException information, you could instead first retrieve the SQLState then process the SQLException accordingly. 您可以先检索SQLState,然后相应地处理SQLException,而不是输出SQLException信息。For example, the method JDBCTutorialUtilities.ignoreSQLException returns true if the SQLState is equal to code 42Y55 (and you are using Java DB as your DBMS), which causes JDBCTutorialUtilities.printSQLException to ignore the SQLException:例如,如果SQLState等于代码42Y55(并且您正在使用Java DB作为DBMS),则方法JDBCTutorialUtilities.ignoreSQLException返回true,这会导致JDBCTutorialUtilities.printSQLException忽略SQLException

public static boolean ignoreSQLException(String sqlState) {

    if (sqlState == null) {
        System.out.println("The SQL state is not defined!");
        return false;
    }

    // X0Y32: Jar file already exists in schema
    if (sqlState.equalsIgnoreCase("X0Y32"))
        return true;

    // 42Y55: Table already exists in schema
    if (sqlState.equalsIgnoreCase("42Y55"))
        return true;

    return false;
}

Retrieving Warnings检索警告

SQLWarning objects are a subclass of SQLException that deal with database access warnings. SQLWarning对象是处理数据库访问警告的SQLException的子类。Warnings do not stop the execution of an application, as exceptions do; they simply alert the user that something did not happen as planned. 警告不会像异常一样停止应用程序的执行;它们只是提醒用户某些事情没有按计划发生。For example, a warning might let you know that a privilege you attempted to revoke was not revoked. 例如,警告可能会让您知道您试图撤销的特权未被撤销。Or a warning might tell you that an error occurred during a requested disconnection.或者,警告可能会告诉您,在请求的断开连接过程中发生了错误。

A warning can be reported on a Connection object, a Statement object (including PreparedStatement and CallableStatement objects), or a ResultSet object. 可以在Connection对象、Statement对象(包括PreparedStatement对象和CallableStatement对象)或ResultSet对象上报告警告。Each of these classes has a getWarnings method, which you must invoke in order to see the first warning reported on the calling object. 这些类中的每一个都有一个getWarnings方法,您必须调用该方法才能看到在调用对象上报告的第一个警告。If getWarnings returns a warning, you can call the SQLWarning method getNextWarning on it to get any additional warnings. 如果getWarnings返回警告,则可以对其调用SQLWarning方法getNextWarning以获取任何其他警告。Executing a statement automatically clears the warnings from a previous statement, so they do not build up. 执行一条语句会自动清除上一条语句中的警告,因此它们不会累积。This means, however, that if you want to retrieve warnings reported on a statement, you must do so before you execute another statement.但是,这意味着,如果要检索语句中报告的警告,则必须在执行另一条语句之前进行检索。

The following methods from JDBCTutorialUtilities illustrate how to get complete information about any warnings reported on Statement or ResultSet objects:JDBCTutorialUtilities中的以下方法说明了如何获取有关在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---Warning---\n");

    while (warning != null) {
        System.out.println("Message: " + warning.getMessage());
        System.out.println("SQLState: " + warning.getSQLState());
        System.out.print("Vendor error code: ");
        System.out.println(warning.getErrorCode());
        System.out.println("");
        warning = warning.getNextWarning();
    }
}

The most common warning is a DataTruncation warning, a subclass of SQLWarning. 最常见的警告是DataTruncation警告,它是SQLWarning的子类。All DataTruncation objects have a SQLState of 01004, indicating that there was a problem with reading or writing data. 所有DataTruncation对象的SQLState均为01004,这表明读取或写入数据时存在问题。DataTruncation methods let you find out in which column or parameter data was truncated, whether the truncation was on a read or write operation, how many bytes should have been transferred, and how many bytes were actually transferred.DataTruncation方法可以让您找出截断了哪些列或参数数据,截断是在读操作还是写操作上,应该传输多少字节,以及实际传输了多少字节。

Categorized SQLExceptions给SQLException分类

Your JDBC driver might throw a subclass of SQLException that corresponds to a common SQLState or a common error state that is not associated with a specific SQLState class value. 您的JDBC驱动程序可能会抛出SQLException的子类,该子类对应于与特定SQLState类值无关的公共SQLState或公共错误状态。This enables you to write more portable error-handling code. 这使您能够编写更多可移植的错误处理代码。These exceptions are subclasses of one of the following classes:这些异常是以下类之一的子类:

See the latest Javadoc of the java.sql package or the documentation of your JDBC driver for more information about these subclasses.有关这些子类的更多信息,请参阅java.sql包的最新Javadoc或JDBC驱动程序的文档。

Other Subclasses of SQLExceptionSQLException的其他子类

The following subclasses of SQLException can also be thrown:还可以抛出SQLException的以下子类:


Previous page: Connecting with DataSource Objects
Next page: Setting Up Tables