statement.executeQuery() 之谜。代码未执行,也未捕获异常。

Posted

技术标签:

【中文标题】statement.executeQuery() 之谜。代码未执行,也未捕获异常。【英文标题】:statement.executeQuery() mystery. Code not being executed, nor exception is being caught. 【发布时间】:2018-02-08 10:47:41 【问题描述】:

提供代码和输出。搜索了互联网,但没有找到解决方案。一切都可以编译和运行,直到“//PROBLEMATIC LINE”,执行直接转到“//HERE”,没有任何指示、异常或错误。我已经多次将此代码与 SQLServer 的 jdbc 驱动程序一起使用并且工作正常,我可能在这里遗漏了什么?在同一个应用程序中,我也将此代码与 mysql jdbc 驱动程序一起使用,并且工作正常。只是在这段代码中存在问题。显然我正在使用 java.sql.*; .

try 
        Class.forName(driver);
        setResponse("Failure. 1");
        connectionTest = DriverManager.getConnection(url, username, password);
        setResponse("Failure. 2");
        String query = "SELECT TOP (1) [id] FROM "+ table + ";";
        PreparedStatement statement = connectionTest.prepareStatement(query);
        setResponse("Failure. 3");
        System.out.println(statement);
        ResultSet resultset = statement.executeQuery();  //PROBLEMATIC LINE
        System.out.println("DOES NOT EVEN PRINT THIS");
        setResponse("Failure. 4");
        if (resultset.first()) setResponse("Success.");
        else setResponse("Failure. 5");
        System.out.println("Query success: ");  
        setResponse("Failure. 6");
    
    catch (Exception e) 
        e.printStackTrace();
    
    finally 
        try 
            connectionTest.close();  //HERE
            return getResponse();
        
        catch (Exception e) 
            e.printStackTrace();
            return getResponse();
        
    

输出:

------------------------------------
-------------DATABASES--------------
------------------------------------
SQLServerPreparedStatement:1
Failure. 3
------------------------------------
----------TESTS COMPLETED-----------
------------------------------------

【问题讨论】:

您的输出未显示“Failure.1”或“Failure.2”。那是怎么回事? Java 有 2 种类型的可抛出对象,异常和错误。您的 catch 块仅捕获 ExceptionError 可能会被抛出(尽管不太可能)。尝试捕捉Throwable 看看是否是这种情况(并且 printStackTrace() 会打印一些有用的东西)。 “执行直接转到“//HERE”,没有任何指示、异常或错误”。那是不可能的。有一个例外,您似乎没有正确打印它。您的System.err 流指向哪里? @nicomp 我的输出只打印从方法返回的值。 请提供完整的异常堆栈跟踪。 【参考方案1】:

当抛出异常时,try 块将退出。当try 块退出时,finally 块将被执行。由于您的 finally 块中有 return 语句,因此您将永远无法到达 catch 块。

不要在 finally 块中使用 return。然后将打印堆栈跟踪,您可以处理异常。

【讨论】:

finally 块执行之前第一个 catch 块? 是的,确实如此。见这里:docs.oracle.com/javase/tutorial/essential/exceptions/… @O.O.Balance 我怎么不能在 finally 块中返回...我的方法必须返回一个语句。如果没有抛出异常,finally 必须返回.. 基本上就是说The finally block always executes when the try block exits。我的意思是如果try 块中抛出异常。如果是这种情况,catch 将被执行并且只有 then finally,对吗?见***.com/questions/3109353/… @MaralKay 写return getResponse(); finally 块之后怎么样?然后,无论是否捕获到异常,您的方法都会返回一些内容。【参考方案2】:

正如其他人提到的,你应该做一些不同的尝试。我的建议:

try 
    Class.forName(driver);
    setResponse("Failure. 1");
    connectionTest = DriverManager.getConnection(url, username, password);
    setResponse("Failure. 2");
    String query = "SELECT TOP (1) [id] FROM "+ table ;
    PreparedStatement statement = connectionTest.prepareStatement(query);
    setResponse("Failure. 3");
    System.out.println(query);
    ResultSet resultset = statement.executeQuery(); 
    while ( resultset.next() 
        System.out.println("only one result because of 'top (1)': " + rs.getInt(1));
    
     resultset.close();
     statement.close();
     connectionTest.close();        
 catch  SQLException sqlex) 
    System.out.println(getClass().getName() + " SQLException:  " + sqlex.getMessage();
  catch (Exception e) 
    System.out.println(getClass().getName() + " GenericException:  " + e.getMessage();
     e.printStrackTrace();

如果所有需要的库都在类路径中,尤其是 JDBC-Driver,它应该没问题

【讨论】:

以上是关于statement.executeQuery() 之谜。代码未执行,也未捕获异常。的主要内容,如果未能解决你的问题,请参考以下文章

无法从 Statement.executeQuery() 中获取选定的列

Can not issue data manipulation statements with executeQuery()的解决方案

StatementPreparedStatemntCallableStatement

Hive 查询 executeQuery() 在 java JDBC 代码中挂起

Java中带有sum的SQL语句不起作用

sql命令中的where子句