光标已关闭

时间:2012-04-25 08:48:27

标签: java oracle hibernate stored-procedures

我正在使用struts框架。我收到“光标已关闭”错误。 我检查了我的storedprocedure,它在oracle中运行良好,但我仍然得到“光标已关闭”错误。

    Caused by: 
java.sql.SQLException: Cursor is closed.
    at oracle.jdbc.driver.T4CResultSetAccessor.getCursor(T4CResultSetAccessor.java:323)
    at oracle.jdbc.driver.ResultSetAccessor.getObject(ResultSetAccessor.java:85)
    at oracle.jdbc.driver.OracleCallableStatement.getObject(OracleCallableStatement.java:1401)

你能帮我理解是什么造成的吗?

4 个答案:

答案 0 :(得分:2)

由于您没有提供代码,但根据我的假设,您通过打开它来从过程返回游标,但同时您可能在同一过程中关闭游标。

PROCEDURE S_S_TEST( 
  test_OUT OUT OAS_TYPES.REFCURSOR
) 
AS
BEGIN
  OPEN test_OUT FOR      
      SELECT *
      FROM table_p;
   CLOSE test_OUT;
END S_S_TEST;

调用存储过程的客户端负责关闭游标。请删除代码:CLOSE test_OUT;

参考:Cursor is Closed

答案 1 :(得分:0)

以下问题将会出现

例如:

while (rs.next()) {


            registartionServices.add(new RegistrationServices(rs.getString(1), rs.getString(2), rs.getString(3),
                    rs.getString(4), rs.getString(5), rs.getString(7), rs.getString(6), rs.getString(9)));
            noti[i] rs.getString(1);
            //System.out.println("amountList-" + rs.getString(7));
            //amountList.add(rs.getString(7));
            //serviceList.add(rs.getString(6));
            //serviceListAR.add(rs.getString(6));
            i++;
        }

在上面的例子中(rs.getString(1))试图访问两次。

而不是将(rs.getString(1))赋值给一个变量并使用该值。

例如:

while (rs.next()) {
                notid=rs.getString(1);
                registartionServices.add(new RegistrationServices(notid, rs.getString(2), rs.getString(3),
                        rs.getString(4), rs.getString(5), rs.getString(7), rs.getString(6), rs.getString(9)));
                noti[i] =notid;
                //System.out.println("amountList-" + rs.getString(7));
                //amountList.add(rs.getString(7));
                //serviceList.add(rs.getString(6));
                //serviceListAR.add(rs.getString(6));
                i++;
            }

希望你能得到答案。

答案 2 :(得分:0)

在您打开特定SQL查询的游标之前,最初REF_CURSOR处于关闭状态。如果在打开光标之前由于某些条件而从未打开过光标,则可能会出现光标已关闭 SQL错误。如果未满足条件,则如果没有故意打开某些虚拟值的光标,则永远不会打开游标。以下是一个例子:

IF condition = TRUE THEN
    OPEN CURSOR cursor_name FOR
    SELECT * FROM table_name;
END IF;

但在这里,条件是假的。因此,该过程返回一个未打开的游标。在这种情况下,我更喜欢从调用程序中捕获这个特殊的异常。例如,以下是一个Java代码,用于捕获特定类型的异常并保持静默。

try
{
    cursor = (ResultSet) stmt.getObject(x);
}
catch(SQLException e)
{
    if (!e.getMessage().toLowerCase().contains("cursor is closed")) {
        e.printStackTrace();
    }
}

而不是

try
{
    cursor = (ResultSet) stmt.getObject(x);
}
catch(SQLException e)
{
    e.printStackTrace();
}

答案 3 :(得分:0)

希望您可以将“过程输出”参数作为光标返回到调用位置,但是您可能错过了打开/添加过程内部的输出参数光标( OPEN RESULT FOR SELECT * FROM TABLE_NAME )的权限。

Example:
PROCEDURE TEST(RESULT OUT SYS_REFCURSOR) 
AS
BEGIN
  --your all codes
  OPEN RESULT FOR  SELECT * FROM TABLE_NAME;
END TEST;