“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
What does "java.sql.SQLException: Unsupported feature" mean?
提问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 过程时将 REF_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.jar
the 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 JavaRefCursorTest
class 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.SQLFeatureNotSupportedException
instead of java.sql.SQLException
. So upgrading the JDBC driver JAR won't help.
我还使用 Oracle 12c JDBC 驱动程序 (ojdbc7.jar)回答您之前的问题之一来运行我的JavaRefCursorTest
课程。最终结果只是略有不同:调用时抛出的异常类型是而不是. 因此升级 JDBC 驱动程序 JAR 无济于事。setCursor()
java.sql.SQLFeatureNotSupportedException
java.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 ResultSet
straight 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();