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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27111344/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 11:15:13  来源:igfitidea点击:

What does "java.sql.SQLException: Unsupported feature" mean?

javaexceptionjdbcoracle11g

提问by Chiseled

My question is related to this postand a post of mine. I am trying to pass REF_CURSOR as an IN parameter while calling a PL/SQL procedure using JDBC. Here is my code:

我的问题与这篇文章和我的一篇文章有​​关。我试图在使用 JDBC 调用 PL/SQL 过程时将 RE​​F_CURSOR 作为 IN 参数传递。这是我的代码:

 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. In my case I am using the latest version of JDBC driver for Oracle ( ojdbc6.jarthe very first jar under Oracle Database 11g Release 2 11.2.0.4 JDBC Drivers) . So i don't think its the version that's causing the issue.

我在这个论坛和其他论坛上看到过一些帖子,建议更新到最新版本的 JDBC 驱动程序可以解决这个问题。就我而言,我使用的是最新版本的 Oracle JDBC 驱动程序( Oracle 数据库 11g 第 2 版 11.2.0.4 JDBC 驱动程序ojdbc6.jar下的第一个 jar )。所以我不认为它是导致问题的版本。

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. Is this the right interpretation of this exception ?

如果我的行为是非法的,抛出的异常消息就会表明这一点。但是这里有“不支持的功能”消息,似乎此功能对我的数据库(或其我使用的版本 (11g) )或我正在使用的 JDBC 驱动程序版本不可用。这是对这个例外的正确解释吗?

回答by Luke Woodward

I would say that the feature is not supported in any version of the JDBC driver, and will never be supported. The version of the database in this situation is not relevant.

我会说该功能在任何版本的 JDBC 驱动程序中都不受支持,并且永远不会得到支持。这种情况下的数据库版本无关。

I can't say why there ever was a setCursor()method declared in OraclePreparedStatement. I would guess that it was a mistake in the design of the API. In fact, you get a deprecation warning if you compile any code that attempts to call setCursor():

我不能说为什么setCursor()OraclePreparedStatement. 我猜这是 API 设计中的一个错误。事实上,如果您编译任何试图调用的代码,您会收到弃用警告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 JavaRefCursorTestclass from my answer to one of your previous questionswith the Oracle 12c JDBC driver (ojdbc7.jar). The end result is only slightly different: the type of exception thrown when calling setCursor()is java.sql.SQLFeatureNotSupportedExceptioninstead of java.sql.SQLException. So upgrading the JDBC driver JAR won't help.

我还使用 Oracle 12c JDBC 驱动程序 (ojdbc7.jar)回答您之前的问题之一来运行我的JavaRefCursorTest课程。最终结果只是略有不同:调用时抛出的异常类型是而不是. 因此升级 JDBC 驱动程序 JAR 无济于事。setCursor()java.sql.SQLFeatureNotSupportedExceptionjava.sql.SQLException

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 ResultSetstraight back to the database. You can call the procedure with a ref cursor directly, using a PL/SQL block such as the one below:

在您的情况下,我看不出您想要将 ref 游标从数据库中取出并放入 JDBC 的原因ResultSet,只是为了将相同的ResultSet直接传递回数据库。您可以使用 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();