ORA-01001: invalid cursor . Passing cursor to a procedure - oracle

When I execute the code below I got ORA-01001: invalid cursor and ORA-06512 error. It was not always the case.I thought I pass the cursor to MY_READ procedure by reference and can close it there. But as I started to get the error above suddenly I concluded, that maybe I'm not passing a reference but the copy of the cursor. Am I right? Is it possible to read close the cursor in MY_READ function?
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PROCEDURE REP_HELPER1 (myIdx IN BINARY_INTEGER, from_d IN DATE, rep_table IN OUT rep_table_T) IS
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
myCUR1 SYS_REFCURSOR;
BEGIN
OPEN myCUR1 FOR SELECT myField1,
myField2,
myField3,
myField4,
myField5,
myField6,
myField7,
myField8,
myField9,
myField10,
myField11,
myField12,
myField13,
myField14,
myField15,
myField16,
myField17,
myField18,
myField19,
myField20,
myField21,
myField22,
myField23,
myField24,
myField25,
myField26,
myField27,
myField28,
myField29,
myField30,
myField31
FROM myTable;
MY_READ(myIdx , myCUR1, rep_table)
END REP_HELPER1;
--Am I passing here a copy of a cursor and not a reference?
PROCEDURE MY_READ(myIdx IN BINARY_INTEGER, cur IN SYS_REFCURSOR, rep_table IN OUT rep_table_T) IS
BEGIN
FETCH cur INTO rep_table(myIdx).day1, rep_table(myIdx).day2, rep_table(myIdx).day3, rep_table(myIdx).day4, rep_table(myIdx).day5,
rep_table(myIdx).day6, rep_table(myIdx).day7, rep_table(myIdx).day8, rep_table(myIdx).day9, rep_table(myIdx).day10,
rep_table(myIdx).day11, rep_table(myIdx).day12, rep_table(myIdx).day13, rep_table(myIdx).day14, rep_table(myIdx).day15,
rep_table(myIdx).day16, rep_table(myIdx).day17, rep_table(myIdx).day18, rep_table(myIdx).day19, rep_table(myIdx).day20,
rep_table(myIdx).day21, rep_table(myIdx).day22, rep_table(myIdx).day23, rep_table(myIdx).day24, rep_table(myIdx).day25,
rep_table(myIdx).day26, rep_table(myIdx).day27, rep_table(myIdx).day28, rep_table(myIdx).day29, rep_table(myIdx).day30,
rep_table(myIdx).day31;
IF cur%NOTFOUND THEN -- here comes ORA-06512 in a stack
dbms_output.put_line('ERROR' || nIndex);
END IF;
CLOSE cur;
END MY_READ;
When I do FETCH and close in REP_HELPER1 I'm not getting the error.

This simple example seems equivalent to yours and works fine:
declare
mycur sys_refcursor;
procedure my_read (cur sys_refcursor) is
job long;
sal number;
begin
fetch cur into job, sal;
dbms_output.put_Line(job||' '||sal);
close cur;
end;
begin
open mycur for select job, sal from emp where ename = 'KING';
my_read (mycur);
end;
So I don't think that is the issue.
According to https://www.techonthenet.com/oracle/errors/ora01001.php:
You tried to reference a cursor that does not yet exist. This may have
happened because:
You've executed a FETCH cursor before OPENING the cursor.
You've executed a CLOSE cursor before OPENING the cursor.
You've executed a FETCH cursor after CLOSING the cursor.

Related

Upper Function is not working in out cursor

I tried to execute the select query with UPPER function that's working fine, while trying to execute through out cursor in oracle, it's not working. kindly tell what i am did wrong here?
QUERY:
SELECT ISSUEID,CATEGORY_1,CATEGORY_2,CATEGORY_3 FROM ISSUES
WHERE UPPER(CATEGORY_2)=UPPER('ORDERNAME');
OUT CURSOR:
OPEN OUT_CURSOR FOR SELECT ISSUEID,CATEGORY_1,CATEGORY_2,CATEGORY_3 FROM ISSUES
WHERE UPPER(CATEGORY_2)=UPPER('ORDERNAME');
Complete Procedure:
PROCEDURE ISSUE_SEARCH(
IN_ISSUEID IN NUMBER DEFAULT NULL,
IN_ORDERJOURNEY IN NVARCHAR2 DEFAULT NULL,
OUT_CURSOR OUT SYS_REFCURSOR
)
AS
BEGIN
DBMS_OUTPUT.PUT_LINE('INSIDE IF..');
OPEN OUT_CURSOR FOR SELECT ISSUEID,CATEGORY_1,CATEGORY_2,CATEGORY_3, FROM ISSUES
WHERE UPPER(CATEGORY_2)=UPPER('IN_ORDERJOURNEY');
EXCEPTION
WHEN NO_DATA_FOUND THEN
OUT_CURSOR :=null;
END ISSUE_SEARCH;

How to build a dynamic PLSQL query to fetch records?

I am trying to create a stored procedure in Oracle and make a dynamic query work to get a bunch of records. I have read many examples but so far I can't get this to work unless I do this:
CREATE OR REPLACE PROCEDURE GiveMeResultSet(
v_par1 IN CHAR,
v_par2 IN CHAR,
v_par3 IN CHAR,
v_par4 IN VARCHAR2,
v_par5 IN VARCHAR2,
v_par6 IN VARCHAR2,
cur_typ OUT SYS_REFCURSOR)
IS
BEGIN
OPEN cur_typ FOR 'select * from complex_query';
--CLOSE cur_typ;
END;
And I am executing it this way:
var c refcursor;
execute GiveMeResultSet(null,null,null,null,null,null,:c);
print c;
This way I get the header names and the records from the query, but I am not closing the cursor that is fetching the results. If I close it then I get nothing at all. I guess leaving it open could cause some kind of memory leak problem at some point.
I have seen similar cases in Oracle documentation where they do something like this:
sql_stmt := 'SELECT * FROM emp';
OPEN emp_cv FOR sql_stmt;
LOOP
FETCH emp_cv INTO emp_rec;
EXIT WHEN emp_cv%NOTFOUND;
-- process record
END LOOP;
CLOSE emp_cv;
But I have no clue what goes on the "process record" part of the code which would allow to get the whole set of records at the end, plus that my record has a complex structure that doesn't fit with a fixed set of fields as in a table.
Can you please show me the proper way to do this?.
Thanks a lot.
ok CodeRoller, here is my sample code for a unspecified ref cursor:
Code of the Function which returns the ref cursor:
create or replace function test_ref_cursor(pi_sql_statement in varchar2) return SYS_REFCURSOR is
result_cursor SYS_REFCURSOR;
begin
open result_cursor for pi_sql_statement;
return result_cursor;
end;
Now, in the next step I use this function to get data from v$parameter:
declare
type t_my_cursor is ref cursor;
my_cursor t_my_cursor;
l_rec v$parameter%rowtype;
begin
my_cursor := test_ref_cursor('select * from v$parameter');
loop
fetch my_cursor into l_rec;
exit when my_cursor%notfound;
dbms_output.put_line(l_rec.name || ' = ' || l_rec.value);
end loop;
close my_cursor;
end;
Take care, to close the ref-cursor!

expression of wrong type oracle error

I am trying to execute the below plsql program, but facing expression of wrong type. Could anyone let me know what might be the error?
CREATE OR REPLACE PROCEDURE CLN_TBL (CTRLM IN VARCHAR2, CTG IN VARCHAR,SBCT IN NUMBER, RTDT IN NUMBER )
AS
V_SQL VARCHAR(2000);
V_TABLE VARCHAR(30);
CURSOR TBL_CUR
IS
SELECT TGT_TABLE_NAME FROM ODS_USER.CLNP WHERE CONTROLM=CTRLM AND APPL_CTGY=CTG AND APPL_SUB_CTGY= SBCT;
L_TGT_TABLE_NAME TBL_CUR%ROWTYPE;
BEGIN
OPEN TBL_CUR;
LOOP
FETCH TBL_CUR INTO L_TGT_TABLE_NAME;
V_TABLE:= L_TGT_TABLE_NAME ;
EXIT WHEN TBL_CUR%NOTFOUND;
V_SQL:='DELETE FROM '||V_TABLE||' WHERE RPT_DT_ID'||'=:1';
EXECUTE IMMEDIATE V_SQL using RTDT;
END LOOP;
COMMIT;
CLOSE TBL_CUR;
END;
As Exhausted said you cant assign row variable to varchar so You should take TGT_TABLE_NAME from row variable, like below should work;
CREATE OR REPLACE PROCEDURE CLN_TBL (CTRLM IN VARCHAR2, CTG IN VARCHAR,SBCT IN NUMBER, RTDT IN NUMBER )
AS
V_SQL VARCHAR(2000);
V_TABLE VARCHAR(30);
CURSOR TBL_CUR
IS
SELECT TGT_TABLE_NAME FROM ODS_USER.CLNP WHERE CONTROLM=CTRLM AND APPL_CTGY=CTG AND APPL_SUB_CTGY= SBCT;
L_TGT_TABLE_NAME TBL_CUR%ROWTYPE;
BEGIN
OPEN TBL_CUR;
LOOP
FETCH TBL_CUR INTO L_TGT_TABLE_NAME;
V_TABLE:= L_TGT_TABLE_NAME.TGT_TABLE_NAME ;
EXIT WHEN TBL_CUR%NOTFOUND;
V_SQL:='DELETE FROM '||V_TABLE||' WHERE RPT_DT_ID'||'=:1';
EXECUTE IMMEDIATE V_SQL using RTDT;
END LOOP;
COMMIT;
CLOSE TBL_CUR;
END;

dbms_sql.to_cursor_number - Getting Invalid Cursor error for SYS_REFCURSOR

I have the following code for table and view creation.
create table test_company
(
comp_id number
, comp_name varchar2(500)
)
;
insert into test_company values(1, 'CompanyA');
insert into test_company values(2, 'CompanyB');
insert into test_company values(3, 'CompanyC');
create or replace view test_company_view as select * from test_company;
And I have the following code for my cursor testing. But dbms_sql.to_cursor_number got error ORA-01001: invalid cursor
set serveroutput on;
declare
reader test_company_view%ROWTYPE;
datacursor SYS_REFCURSOR;
v_cursor_id number;
begin
open datacursor for select * from test_company_view;
v_cursor_id := dbms_sql.to_cursor_number(datacursor); -- ERROR: invalid cursor
loop fetch datacursor into reader;
exit when datacursor%NOTFOUND;
dbms_output.put_line(reader.comp_id);
end loop;
close datacursor;
end;
What did I do wrong? Thank you for your helps!
I have tried strongly-typed REF CURSOR and weakly-typed REF CURSOR but they got the same error.
From the documentation:
After you convert a REF CURSOR variable to a SQL cursor number, native dynamic SQL operations cannot access it.
It is not dbms_sql.to_cursor_number that is raising the error, it is fetch datacursor into reader since datacursor can no longer be accessed.

TORA Execute Package Procedure with OUT REF CURSOR

I'm trying to execute a Package Procedure that has a couple in parameters and a REF CURSOR out parameter but can't seem to figure it out for TORA (my SQL IDE)
Here is a contrived example of a procedure I'd like to execute and see the cursor for:
PROCEDURE get_peeps_in_city ( pi_city IN varchar(100), po_recordset OUT REF CURSOR )
IS
BEGIN
OPEN po_recordset
FOR Select Id,
FName,
LName
FROM People
WHERE City like '%' || pi_city || '%'
END;
Here is what I've tried so far:
DECLARE
v_cursor REF CURSOR;
BEGIN
execute PKG_PEEPS.get_peeps_in_city('Chicago', v_cursor);
END
The error that I get is something along the lines of:
PLS-00103: Encountered the symbol "END" when expecting one of the
following:
begin function package pragma procedure subtype type use form current
cursor
You're probably looking for something like this:
DECLARE
v_cursor SYS_REFCURSOR;
v_Id NUMBER;
v_FName VARCHAR2(200);
v_LName VARCHAR2(200);
BEGIN
PKG_PEEPS.get_peeps_in_city('Chicago', v_cursor);
LOOP
FETCH v_cursor INTO v_Id, v_FName, v_LName;
EXIT WHEN v_cursor%NOTFOUND;
-- do something with v_Id, v_FName, v_LName
END LOOP;
CLOSE v_cursor;
END;
/
Update:
You probably would like that the result of your query is displayed in your IDE as if you had run the SELECT statement directly. This is not going to happen with the above code and I don't know of any code that could achieve that (unless you install a specific table function).
The best thing you can do is output the retrieved data in the loop (using DBMS_OUTPUT.PUT_LINE).

Resources