简体   繁体   English

“ java.sql.SQLException:不支持的功能”是什么意思?

[英]What does “java.sql.SQLException: Unsupported feature” mean?

My question is related to this post and a post of mine . 我的问题与这个职位和我的一个职位有关 I am trying to pass REF_CURSOR as an IN parameter while calling a PL/SQL procedure using JDBC. 我试图在使用JDBC调用PL / SQL过程时将REF_CURSOR作为IN参数传递。 Here is my code: 这是我的代码:

 public int printMaxSalAllDept()
 {
     Connection conn = null;
     OracleCallableStatement callStmt = null;
     int rowCount = -1;

     try 
     {
         // Register the Jdbc Driver
         // Class.forName(JDBC_DRIVER_ORACLE);

         // Create a Database connection
         conn = DriverManager.getConnection(DB_URL,DB_USER,DB_PWD);

         // Create a query string to get the ResultSet of your choice
         String getRsQuery = "SELECT e.department_id , e.last_name , "
                             + "e.salary FROM employees e , (SELECT department_id , "
                             + "MAX(salary) AS maxSal FROM employees GROUP BY department_id) "
                             + "m WHERE e.department_id = m.department_id "
                             + "AND e.salary = m.maxSal ORDER BY e.salary";

         // Create a Statement
         Statement stmt = conn.createStatement();

         // Execute the statement
         ResultSet rs = stmt.executeQuery(getRsQuery);


         // Create a SQL String
         String callProc = "{ call HR.EMP_PKG.print_max_sal_all_dept(? , ?) }";

         // Create a Callable Statement
         callStmt = (OracleCallableStatement) conn.prepareCall(callProc);

         // Bind values to the IN parameter
         callStmt.setCursor(1, rs);
         // callStmt.setNull(1,OracleTypes.CURSOR);

         // Register OUT parameters type to the SQL type of the value returned
         callStmt.registerOutParameter(2, java.sql.Types.NUMERIC);

         // Execute Callable Statements
         callStmt.execute();

         // Retrieve value from the OUT parameters
         rowCount = callStmt.getInt(0);
         System.out.println("Number of rows in the cursor :" + rowCount);
     } 
     catch (SQLException se) 
     {
        System.out.println("Exception occured in the database");
        System.out.println("Exception message: "+ se.getMessage());
        System.out.println("Database error code: "+ se.getErrorCode());
        se.printStackTrace();
     }
     finally
     {
        // Clean up
        if(callStmt != null)
        {
            try
            {
                callStmt.close();
            } 
            catch (SQLException se2) 
            {
                se2.printStackTrace();
            }
        }

        if(conn != null)
        {
            try
            {
                conn.close();
            } 
            catch (SQLException se2) 
            {
                se2.printStackTrace();
            }
        }
     }
     return rowCount;
 }

When I run the above code I get the following exception: 当我运行上面的代码时,出现以下异常:

Exception occured in the database
java.sql.SQLException: Unsupported feature
    at oracle.jdbc.driver.OraclePreparedStatement.setCursorInternal(OraclePreparedStatement.java:5867)
    at oracle.jdbc.driver.OracleCallableStatement.setCursor(OracleCallableStatement.java:5297)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.setCursor(OraclePreparedStatementWrapper.java:410)
    at com.rolta.HrManager.printMaxSalAllDept(HrManager.java:1038)
    at com.rolta.HrManager.main(HrManager.java:1344)
Exception message: Unsupported feature
Database error code: 17023

I have seen couple of posts in this forum and others which suggests updating to the latest version of JDBC driver fixes this issue. 我在该论坛和其他论坛上看到过几篇文章,这些文章建议更新到最新版本的JDBC驱动程序可以解决此问题。 In my case I am using the latest version of JDBC driver for Oracle ( ojdbc6.jar the very first jar under Oracle Database 11g Release 2 11.2.0.4 JDBC Drivers ) . 就我而言,我正在使用Oracle的最新版本的JDBC驱动程序( ojdbc6.jarOracle Database 11g第2版11.2.0.4 JDBC驱动程序下的第一个jar)。 So i don't think its the version that's causing the issue. 所以我不认为是引起问题的版本。

If what I was doing was illegal the exception message thrown would have indicated that. 如果我正在做的事情是非法的,则抛出异常消息将表明这一点。 But here with "Unsupported Feature" message it seems like this feature is either unavailable for my database(or its version that I am using (11g) ) or for the version of the JDBC driver that I am using. 但是在这里显示“不支持的功能”消息,似乎该功能对于我的数据库(或其正在使用的版本(11g))或我正在使用的JDBC驱动程序的版本不可用。 Is this the right interpretation of this exception ? 这是对这种例外的正确解释吗?

I would say that the feature is not supported in any version of the JDBC driver, and will never be supported. 我会说该功能在任何版本的JDBC驱动程序中均不受支持,并且永远不会得到支持。 The version of the database in this situation is not relevant. 在这种情况下,数据库的版本无关紧要。

I can't say why there ever was a setCursor() method declared in OraclePreparedStatement . 我不能说为什么在OraclePreparedStatement声明了setCursor()方法。 I would guess that it was a mistake in the design of the API. 我想这是API设计中的错误。 In fact, you get a deprecation warning if you compile any code that attempts to call setCursor() : 实际上,如果您编译任何尝试调用setCursor()代码,则会收到不赞成使用的警告:

C:\>javac -Xlint JavaRefCursorTest.java
JavaRefCursorTest.java:28: warning: [deprecation] setCursor(int,ResultSet) in OraclePreparedStatement has been deprecated
                    ((OracleCallableStatement)cstmt2).setCursor(1, rSet);
                                                     ^
1 warning

This deprecation warning suggests that Oracle are planning to remove this method in the future. 此弃用警告表明Oracle计划在将来删除此方法。

I've also run my JavaRefCursorTest class from my answer to one of your previous questions with the Oracle 12c JDBC driver (ojdbc7.jar). 我还通过对Oracle 12c JDBC驱动程序(ojdbc7.jar)的先前问题之一的回答运行了JavaRefCursorTest类。 The end result is only slightly different: the type of exception thrown when calling setCursor() is java.sql.SQLFeatureNotSupportedException instead of java.sql.SQLException . 最终结果只是略有不同:调用setCursor()时引发的异常类型是java.sql.SQLFeatureNotSupportedException而不是java.sql.SQLException So upgrading the JDBC driver JAR won't help. 因此,升级JDBC驱动程序JAR将无济于事。

In your case, I can't see the reason why you would want to get a ref cursor out of the database and into a JDBC ResultSet , only to pass the same ResultSet straight back to the database. 在您的情况下,我看不到为什么要将引用游标从数据库中移出并移到JDBC ResultSet ,而只是将相同的ResultSet直接传递回数据库。 You can call the procedure with a ref cursor directly, using a PL/SQL block such as the one below: 您可以使用PL / SQL块(例如以下代码)直接使用ref游标调用该过程:

String plsql = 
    "DECLARE" +
    "  l_curs   SYS_REFCURSOR; " +
    "BEGIN" +
    "  OPEN l_curs FOR" +
    "     SELECT e.department_id , e.last_name ," +
    "            e.salary FROM employees e , (SELECT department_id ," +
    "            MAX(salary) AS maxSal FROM employees GROUP BY department_id)" +
    "            m WHERE e.department_id = m.department_id" + 
    "            AND e.salary = m.maxSal ORDER BY e.salary;" +
    "" +            
    "  HR.EMP_PKG.print_max_sal_all_dept(l_curs, ?);" +
    "END;"

PreparedStatement stmt = conn.prepareStatement(plsql);
stmt.registerOutParameter(1, java.sql.Types.NUMERIC);
stmt.execute();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM