'.NET PL/SQL ORA-01001: invalid cursor
I'm using "ASP.NET Framework" with "Oracle.ManagedDataAccess.Client" to get result from ORACLE Procedure, but I get in some times error "ORA-01001: invalid cursor" or "ORA-01006: bind variable does not exist" for the same parameter in random tried, I can not find the issue because it's not allows occurred,
I'm try to increases number cursor open to 5000, but still issue occurred
public void checkStdHasExam(int studentId, int subjectId)
{
OracleConnection conn = DatabaseConnection.DBconn();
OracleCommand cmd = new OracleCommand("API_PACKAGE.CHECK_STD_LINKED_MATH", conn);
cmd.Parameters.Add(new OracleParameter(":P_STUDENT_ID", studentId));
cmd.Parameters.Add(new OracleParameter(":P_REF_CURSOR", OracleDbType.RefCursor)).Direction = ParameterDirection.Output;
cmd.CommandType = CommandType.StoredProcedure;
try
{
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
using (OracleDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
var hasExam = Convert.ToInt32(reader["math_linked"]);
}
}
}
catch (Exception ex)
{
Utils.CreateLOG("checkStdHasExam", ex, $"{studentId},{subjectId}");
throw ex;
}
finally
{
if (conn.State == ConnectionState.Open)
{
conn.Close();
conn.Dispose();
}
}
}
ORACLE Procedure:
PROCEDURE CHECK_STD_LINKED_MATH(P_STUDENT_ID NUMBER, P_REF_CURSOR OUT REF_SELECT)
AS
V_HOMEROOM VARCHAR2(500);
V_LINKED_MATH NUMBER;
V_LOG_ID NUMBER;
V_MESSAGE_LOG VARCHAR2(200);
BEGIN
SELECT HOMEROOM INTO V_HOMEROOM FROM SUBSCRIBERS WHERE ID = P_STUDENT_ID;
SELECT COUNT(1) INTO V_LINKED_MATH FROM TEACHER_HOMEROOMS WHERE SUBJECT_ID = 3 AND HOMEROOM = V_HOMEROOM;
IF V_LINKED_MATH > 0 THEN
OPEN P_REF_CURSOR FOR
SELECT 1 AS MATH_LINKED FROM DUAL;
ELSIF V_LINKED_MATH <= 0 THEN
OPEN P_REF_CURSOR FOR
SELECT 0 AS MATH_LINKED FROM DUAL;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
OPEN P_REF_CURSOR FOR
SELECT 0 AS MATH_LINKED FROM DUAL;
WHEN OTHERS THEN
V_LOG_ID := DBF_GENERATE_ID('SYSTEM_API_LOG');
V_MESSAGE_LOG := SQLERRM;
INSERT INTO SYSTEM_API_LOG VALUES(V_LOG_ID, SYSDATE, 'CHECK_STD_LINKED_MATH',V_MESSAGE_LOG, '');
END;
Can you provide help?
Solution 1:[1]
Instead of using type REF_SELECT- whatever that type is, i would recommend to use SYS_REFCURSOR instead.
Also dont forget to open refcursor when Other exception occurs.
Thats why sometimes you get invalid cursor.
Explanation: If a cursor or cursor variable is not open, referencing it raises the predefined exception INVALID_CURSOR.
You can also remove ELSIF and use ELSE instead. Its more guaranteed that it enters any part of code during execution, so you will be able to reference that cursor from C#.
I already corrected everything for you, try the following code:
PROCEDURE CHECK_STD_LINKED_MATH(P_STUDENT_ID NUMBER, P_REF_CURSOR OUT SYS_REFCURSOR)
AS
V_HOMEROOM VARCHAR2(500);
V_LINKED_MATH NUMBER;
V_LOG_ID NUMBER;
V_MESSAGE_LOG VARCHAR2(200);
BEGIN
SELECT HOMEROOM INTO V_HOMEROOM FROM SUBSCRIBERS WHERE ID = P_STUDENT_ID;
SELECT COUNT(1) INTO V_LINKED_MATH FROM TEACHER_HOMEROOMS WHERE SUBJECT_ID = 3 AND HOMEROOM = V_HOMEROOM;
IF V_LINKED_MATH > 0 THEN
OPEN P_REF_CURSOR FOR
SELECT 1 AS MATH_LINKED FROM DUAL;
ELSE
OPEN P_REF_CURSOR FOR
SELECT 0 AS MATH_LINKED FROM DUAL;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
OPEN P_REF_CURSOR FOR
SELECT 0 AS MATH_LINKED FROM DUAL;
WHEN OTHERS THEN
OPEN P_REF_CURSOR FOR
SELECT 0 AS MATH_LINKED FROM DUAL;
V_LOG_ID := DBF_GENERATE_ID('SYSTEM_API_LOG');
V_MESSAGE_LOG := SQLERRM;
INSERT INTO SYSTEM_API_LOG VALUES(V_LOG_ID, SYSDATE, 'CHECK_STD_LINKED_MATH',V_MESSAGE_LOG, '');
END;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
