Java JDBC捕获登录失败异常并重新提示输入

Java JDBC捕获登录失败异常并重新提示输入,java,sql,jdbc,Java,Sql,Jdbc,我能找到的唯一异常是SQLException,但它如何区分登录失败和错误的sql语句呢 我想让它再次提示用户输入id和密码的机会,我要把它放在catch块中吗 如果是这样,我是否需要另一个嵌套的try-catch来处理异常 因为我想分别处理这两种情况,但似乎只有一个SQLException可以使用 事实上,您还会得到一些: try{ Class.forName ("oracle.jdbc.driver.OracleDriver"); // identify Connection con = D

我能找到的唯一异常是SQLException,但它如何区分登录失败和错误的sql语句呢

我想让它再次提示用户输入id和密码的机会,我要把它放在catch块中吗

如果是这样,我是否需要另一个嵌套的try-catch来处理异常


因为我想分别处理这两种情况,但似乎只有一个SQLException可以使用

事实上,您还会得到一些:

try{
Class.forName ("oracle.jdbc.driver.OracleDriver"); // identify

Connection con = DriverManager.getConnection
 ("jdbc:oracle...",userid,password); 


// create Statement and execute sql statement after
} catch (SQLException ex) {
        Logger.getLogger(Transcript.class.getName()).log(Level.SEVERE, null, ex);
    }
您可以将登录失败与SQL失败分开,因为它们发生在代码中的不同位置

If you don't have the right Oracle driver in the classpath in Class.forName:
Exception in thread "main" java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver

If DriverManager.getConnection fails because of a wrong jdbc url syntax:
Exception in thread "main" java.sql.SQLException: No suitable driver found for jdbc:oracle...

If login/password fails at DriverManager.getConnection
Exception in thread "main" java.sql.SQLException: ORA-01017: invalid username/password; logon denied

In case of an incorrect SQL statement:
Exception in thread "main" java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist

In case of an incorrect SQL statement:
Exception in thread "main" java.sql.SQLSyntaxErrorException: ORA-00900: invalid SQL statement

In case of an incorrect SQL statement:
Exception in thread "main" java.sql.SQLException: Invalid column name
注意:这是一个暴力示例,在生产代码中,您可能需要更精确的异常处理程序,并且您应该确保资源始终处于关闭状态。例如,如果在读取result集时发生SQL错误,并且由于引用无效列而发生错误,则可能需要关闭语句和结果集

还有两个特定于Oracle的提示:

  • 不要在DriverManager.getConnection中以参数形式传递登录名和密码。Oracle连接有更多的参数,更容易构建包含所有内容的JDBCURL:“JDBC:Oracle:thin:schema/password@host:端口:sid“

    • 请注意,主机:端口是必需的。很多时候,多个Oracle server实例可以共享同一端口。您可以使用服务id(SID)来区分它们
  • 对于真正的Oracle异常,该异常被包装为SQLException或SQLSyntaxErrorException,有时是这个,有时是那个。我发现在这上面加上自己的逻辑非常方便:

    • 我用try..catch捕捉任何异常。如果错误消息以ORA-开头,那么它是一个Oracle错误,我将它包装到一个自定义异常类中并重新抛出

    • 解析自定义异常中的Oracle错误代码可能很容易。您可以使用它来区分您在PL/SQL中抛出的定制Oracle异常(-20000..-20999)(并且可以表示业务级别的错误)。其余的错误代码总是显示技术错误,即代码或数据库结构中存在错误

要关闭资源(java7之前),请使用try..finally。请注意,当实际关闭资源失败时,对可能的进一步异常的悲观处理

public class Oracle {

    public static void main(final String[] args) throws ClassNotFoundException, SQLException {
        final Connection con;

        try {
            Class.forName ("oracle.jdbc.driver.OracleDriver"); 
        } catch (final Exception e) {
            throw new RuntimeException("Driver failure");
        }

        try {
            con = DriverManager.getConnection ("jdbc:oracle:thin:schema/password@host:port:sid");
        } catch (final Exception e) {
            throw new RuntimeException("Login failure");
        }


        try {
            final Statement stmt = con.createStatement();

            final String sql = "select 1 from dual";
            final ResultSet rs = stmt.executeQuery(sql);
            while(rs.next()) {
                // do something with the data
            }
            rs.close();
        } catch (final Exception e) {
            throw new RuntimeException("SQL failure");
        }
    }
}

要关闭Java7及更高版本上的资源,您可以使用try with resource块。请参见

事实上,您将获得更多:

try{
Class.forName ("oracle.jdbc.driver.OracleDriver"); // identify

Connection con = DriverManager.getConnection
 ("jdbc:oracle...",userid,password); 


// create Statement and execute sql statement after
} catch (SQLException ex) {
        Logger.getLogger(Transcript.class.getName()).log(Level.SEVERE, null, ex);
    }
您可以将登录失败与SQL失败分开,因为它们发生在代码中的不同位置

If you don't have the right Oracle driver in the classpath in Class.forName:
Exception in thread "main" java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver

If DriverManager.getConnection fails because of a wrong jdbc url syntax:
Exception in thread "main" java.sql.SQLException: No suitable driver found for jdbc:oracle...

If login/password fails at DriverManager.getConnection
Exception in thread "main" java.sql.SQLException: ORA-01017: invalid username/password; logon denied

In case of an incorrect SQL statement:
Exception in thread "main" java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist

In case of an incorrect SQL statement:
Exception in thread "main" java.sql.SQLSyntaxErrorException: ORA-00900: invalid SQL statement

In case of an incorrect SQL statement:
Exception in thread "main" java.sql.SQLException: Invalid column name
注意:这是一个暴力示例,在生产代码中,您可能需要更精确的异常处理程序,并且您应该确保资源始终处于关闭状态。例如,如果在读取result集时发生SQL错误,并且由于引用无效列而发生错误,则可能需要关闭语句和结果集

还有两个特定于Oracle的提示:

  • 不要在DriverManager.getConnection中以参数形式传递登录名和密码。Oracle连接有更多的参数,更容易构建包含所有内容的JDBCURL:“JDBC:Oracle:thin:schema/password@host:端口:sid“

    • 请注意,主机:端口是必需的。很多时候,多个Oracle server实例可以共享同一端口。您可以使用服务id(SID)来区分它们
  • 对于真正的Oracle异常,该异常被包装为SQLException或SQLSyntaxErrorException,有时是这个,有时是那个。我发现在这上面加上自己的逻辑非常方便:

    • 我用try..catch捕捉任何异常。如果错误消息以ORA-开头,那么它是一个Oracle错误,我将它包装到一个自定义异常类中并重新抛出

    • 解析自定义异常中的Oracle错误代码可能很容易。您可以使用它来区分您在PL/SQL中抛出的定制Oracle异常(-20000..-20999)(并且可以表示业务级别的错误)。其余的错误代码总是显示技术错误,即代码或数据库结构中存在错误

要关闭资源(java7之前),请使用try..finally。请注意,当实际关闭资源失败时,对可能的进一步异常的悲观处理

public class Oracle {

    public static void main(final String[] args) throws ClassNotFoundException, SQLException {
        final Connection con;

        try {
            Class.forName ("oracle.jdbc.driver.OracleDriver"); 
        } catch (final Exception e) {
            throw new RuntimeException("Driver failure");
        }

        try {
            con = DriverManager.getConnection ("jdbc:oracle:thin:schema/password@host:port:sid");
        } catch (final Exception e) {
            throw new RuntimeException("Login failure");
        }


        try {
            final Statement stmt = con.createStatement();

            final String sql = "select 1 from dual";
            final ResultSet rs = stmt.executeQuery(sql);
            while(rs.next()) {
                // do something with the data
            }
            rs.close();
        } catch (final Exception e) {
            throw new RuntimeException("SQL failure");
        }
    }
}

要关闭Java7及更高版本上的资源,您可以使用try with resource块。请参见

将这两个操作(获取连接和执行SQL语句)提取到各自的方法中,每个方法都可以有单独的try-catch块用于异常处理。将这两个操作(获取连接和执行SQL语句)提取到各自的方法中,每个都可以有单独的try-catch块用于异常处理。非常感谢!请问我在哪里关闭我的资源?我通常只是把它们放在最后,但是如果程序在某个点崩溃,并且没有达到close()语句,这会是一个大问题吗?当程序崩溃时,操作系统将关闭所有资源,所以不用担心。但是,如果在您的程序中运行1001条select语句,并且从未关闭这些语句和结果集,那么问题就更大了。Oracle可以打开的游标数量有限,每个打开的结果集使用一个。因此,不关闭资源会使程序在使用一段时间后抛出错误。我明白了!非常感谢您的解释!:)非常感谢你!请问我在哪里关闭我的资源?我通常只是把它们放在最后,但是如果程序在某个点崩溃,并且没有达到close()语句,这会是一个大问题吗?当程序崩溃时,操作系统将关闭所有资源,所以不用担心。但是,如果在程序中运行1001条select语句,并且从不关闭