我正在使用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)
你能帮我理解是什么造成的吗?
答案 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
;
答案 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;