An interesting question! Just wanted to add a few things.
To me, the real issue is in depending on IS_OPEN to determine if a cursor is valid or not. Oracle can throw INVALID_CURSOR for many reasons, and it is possible to have an «open» cursor that is not valid. Seems reasonable to assume that an open cursor must be valid (and we can therefore fetch from it or do other operations, like a simple close), but this isn’t necessarily the case.
For example, you cannot use cursor variables in remote procedure calls (via dblinks). This same example, even using Alex’s workaround, would fail if the open was called on 1 db instance and the fetch on another (if nested_test, any version, was defined on db_A and then called from db_B). The test for ISOPEN, however, would still return TRUE, but then trying to use the cursor (fetch) would fail.
INVALID_CURSOR can be raised for other reasons (like going beyond the max open cursors, or sometimes opening a cursor and waiting a while before trying to use it).
All that said, there is no «ISVALID» test that I know of. The best approach imo is to open, fetch and close cursors within the same program or subprogram. Creating a procedure whos responsibility is to just OPEN a cursor is a bit strange to me (but I’m sure there was some reason), and can cause hard to explain issues (like this one). If you must have another program open a cursor for you, then you might want to enclose the code that fetches and eventually closes the cursor in an anonymous block and catch the INVALID_CURSOR exception.
Just my ramblings 

PL/SQL является тесная интеграция с базой данных Oracle в отношении как изменения данных в таблицах, так и выборки данных из таблиц. В этом блоге рассматриваются элементы PL/SQL, связанные с выборкой информации из базы данных и ее обработкой в программах PL/SQL.
При выполнении команды SQL из PL/SQL РСУБД Oracle назначает ей приватную рабочую область, а некоторые данные записывает в системную глобальную область (SGA, System Global Area). В приватной рабочей области содержится информация о команде SQL и набор данных, возвращаемых или обрабатываемых этой командой. PL/SQL предоставляет программистам несколько механизмов доступа к этой рабочей области и содержащейся в ней информации; все они так или иначе связаны с определением курсоров и выполнением операций с ними.
- Неявные курсоры. Команда
SELECT.. .INTOсчитывает одну строку данных и присваивает ее в качестве значения локальной переменной программы. Это простейший (и зачастую наиболее эффективный) способ доступа к данным, но он часто ведет к написанию сходных и даже одинаковыхSQL-командSELECTво многих местах программы. - Явные курсоры. Запрос можно явно объявить как курсор в разделе объявлений локального блока или пакета. После этого такой курсор можно будет открывать и выбирать из него данные в одной или нескольких программах, причем возможности управления явным курсором шире, чем у неявного.
- Курсорные переменные. Курсорные переменные (в объявлении которых задается тип
REF CURSOR) позволяют передавать из программы в программу указатель на результирующий набор строк запроса. Любая программа, для которой доступна такая переменная, может открыть курсор, извлечь из него необходимые данные и закрыть его. - Курсорные выражения. Ключевое слово
CURSORпревращает командуSELECTв набор REF CURSOR, который может использоваться совместно с табличными функциями для повышения производительности приложения. - Динамические
SQL-запросы. Oracle позволяет динамически конструировать и выполнять запросы с использованием либо встроенного динамическогоSQLлибо программ пакетаDMBS_SQL. Этот встроенный пакет описывается в документации Oracle, а также в книге Oracle Built-in Packages (O’Reilly).
Основные принципы работы с курсорами
Курсор проще всего представить себе как указатель на таблицу в базе данных. Например, следующее объявление связывает всю таблицу employee с курсором employee_cur:
CURSOR employee_cur IS SELECT * FROM employee;
Объявленный курсор можно открыть:
OPEN employee_cur;
Далее из него можно выбирать строки:
FETCH employee_cur INTO employee_rec;
Завершив работу с курсором, его следует закрыть:
CLOSE employee_cur;
В этом случае каждая выбранная из курсора запись представляет строку таблицы employee. Однако с курсором можно связать любую допустимую команду SELECT. В следующем примере в объявлении курсора объединяются три таблицы:
DECLARE
CURSOR joke_feedback_cur IS
SELECT J.name, R.laugh_volume, C.name FROM Joke J, response R, comedian C WHERE J.joke_id = R.joke_id AND R.joker_id = C.joker_id;
BEGIN
END;
В данном случае курсор действует не как указатель на конкретную таблицу базы данных — он указывает на виртуальную таблицу или неявное представление, определяемое командой SELECT. (Такая таблица называется виртуальной, потому что команда SELECT генерирует данные с табличной структурой, но эта таблица существует только временно, пока программа работает с возвращенными командой данными.) Если тройное объединение возвращает таблицу из 20 строк и 3 столбцов, то курсор действует как указатель на эти 20 строк.
Терминология
В PL/SQL имеется множество возможностей выполнения команд SQL, и все они реализованы в программах как курсоры того или иного типа. Прежде чем приступить к их освоению, необходимо познакомиться с методами выборки данных и используемой при этом терминологией.
- Статический
SQL. КомандаSQLназывается статической, если она полностью определяется во время компиляции программы. - Динамический
SQL. КомандаSQLназывается динамической, если она строится и выполняется на стадии выполнения программы, так что в программном коде нет ее фиксированного объявления. Для динамического выполнения командSQLмогут использоваться программы встроенного пакетаDBMS_SQL(имеющегося во всех версиях Oracle) или встроенный динамическийSQL. - Результирующий набор строк. Набор строк с результирующими данными, удовлетворяющими критериям, определяемым командой
SQL.Результирующий набор кэшируется в системной глобальной области с целью ускорения чтения и модификации его данных. - Неявный курсор. При каждом выполнении команды
DML(INSERT, UPDATE, MERGEили delete) или команды select into, возвращающей строку из базы данных прямо в структуру данных программы,PL/SQLсоздает неявный курсор. Курсор этого типа называется неявным, посколькуOracleавтоматически выполняет многие связанные с ним операции, такие как открытие, выборка данных и даже закрытие. - Явный курсор. Команда
SELECT, явно определенная в программе как курсор. Все операции с явным курсором (открытие, выборка данных, закрытие и т. д.) в программе должны выполняться явно. Как правило, явные курсоры используются для выборки из базы данных набора строк с использованием статического SQL. - Курсорная переменная. Объявленная программистом переменная, указывающая на объект курсора в базе данных. Ее значение (то есть указатель на курсор или результирующий набор строк) во время выполнения программы может меняться, как у всех остальных переменных. В разные моменты времени курсорная переменная может указывать на разные объекты курсора. Курсорную переменную можно передать в качестве параметра процедуре или функции. Такие переменные очень полезны для передачи результирующих наборов из программ
PL/SQLв другие среды (например, Java или Visual Basic). - Атрибут курсора. Атрибут курсора имеет форму %имя_атрибута и добавляется к имени курсора или курсорной переменной. Это что-то вроде внутренней переменной Oracle, возвращающей информацию о состоянии курсора — например о том, открыт ли курсор, или сколько строк из курсора вернул запрос. У явных и неявных курсоров и в динамическом SQL в атрибутах курсоров существуют некоторые различия, которые рассматриваются в этой статье.
- SELECT FOR UPDATE. Разновидность обычной команды
SELECT, устанавливающая блокировку на каждую возвращаемую запросом строку данных. Пользоваться ею следует только в тех случаях, когда нужно «зарезервировать» запрошенные данные, чтобы никто другой не мог изменить их, пока с ними работаете вы. - Пакетная обработка. В
Oracle8iи вышеPL/SQLподдерживает запросы с секциейBULK COLLECT, позволяющей за один раз выбрать из базы данных более одной строки.
Типичные операции с запросами и курсорами
Независимо от типа курсора процесс выполнения команд SQL всегда состоит из одних и тех же действий. В одних случаях PL/SQL производит их автоматически, а в других, как, например, при использовании явного курсора, они явно организуются программистом.
- Разбор. Первым шагом при обработке команды
SQLдолжен быть ее разбор (синтаксический анализ), то есть проверка ее корректности и формирование плана выполнения (с применением оптимизации по синтаксису или по стоимости в зависимости от того, какое значение параметра0PTIMIZER_M0DEзадал администратор базы данных). - Привязка. Привязкой называется установление соответствия между значениями программы и параметрами команды
SQL.Для статическогоSQLпривязка производится ядромPL/SQL. Привязка параметров в динамическомSQLвыполняется явно с использованием переменных привязки. - Открытие. При открытии курсора определяется результирующий набор строк команд SQL, для чего используются переменные привязки. Указатель активной или текущей строки указывает на первую строку результирующего набора. Иногда явное открытие курсора не требуется; ядро
PL/SQLвыполняет эту операцию автоматически (так происходит в случае применения неявных курсоров и встроенного динамическогоSQL). - Выполнение. На этой стадии команда выполняется ядром
SQL. - Выборка. Выборка очередной строки из результирующего набора строк курсора осуществляется командой
FETCH. После каждой выборкиPL/SQLперемещает указатель на одну строку вперед. Работая с явными курсорами, помните, что и после завершения перебора всех строк можно снова и снова выполнять командуFETCH, ноPL/SQLничего не будет делать (и не станет инициировать исключение) — для выявления этого условия следует использовать атрибуты курсора. - Закрытие. Операция закрывает курсор и освобождает используемую им память. Закрытый курсор уже не содержит результирующий набор строк. Иногда явное закрытие курсора не требуется, последовательность
PL/SQLделает это автоматически (для неявных курсоров и встроенного динамическогоSQL).
На рис. 1 показано, как некоторые из этих операций используются для выборки информации из базы данных в программу PL/SQL.
Рис. 1. Упрощенная схема выборки данных с использованием курсора
Знакомство с атрибутами курсоров
В этом разделе перечисляются и вкратце описываются атрибуты курсоров.
PL/SQL поддерживает шесть атрибутов курсоров, перечисленных в табл. 1.
Таблица 1. Атрибуты курсоров
Чтобы обратиться к атрибуту курсора, укажите в виде его префикса имя курсора или курсорной переменной и символ %:
имя_курсора%имя_атрибута
В качестве имен неявных курсоров используется префикс SQL, например SQL%NOTFOUND. Ниже приведены краткие описания всех атрибутов курсоров.
Атрибут %FOUND
Атрибут %FOUND возвращает информацию о состоянии последней операции FETCH с курсором. Если последний вызов FETCH для курсора вернул строку, то возвращается значение TRUE, а если строка не была получена, возвращается FALSE.
Если курсор еще не был открыт, база данных инициирует исключение INVALID_CURS0R. В следующем примере я перебираю все строки курсора caller_cur, присваиваю все звонки, введенные до сегодняшнего дня для конкретного позвонившего, после чего перехожу к следующей записи. При достижении последней записи атрибут %FOUND явного курсора возвращает FALSE, и выполнение простого цикла прерывается. Атрибут %FOUND неявного курсора также проверяется после команды UPDATE:
FOR caller_rec IN caller_cur LOOP
UPDATE call
SET caller_id = caller_rec.caller_id WHERE call_timestamp < SYSDATE;
IF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE ('Calls updated for ' || caller_rec.caller_id);
END IF;
END LOOP;
Атрибут %NOTFOUND
Атрибут %NOTFOUND по смыслу противоположен %FOUND: он возвращает TRUE, если последняя операция FETCH с курсором не вернула строки (как правило, из-за того, что последняя строка уже была прочитана). Если курсор не может вернуть строку из-за ошибки, инициируется соответствующее исключение.
Если курсор еще не был открыт, база данных инициирует исключение INVALID_CURSOR. В каких случаях следует использовать %FOUND, а когда предпочтение отдается %NOTFOUND? Используйте ту формулировку, которая более естественно подходит для вашего кода. В предыдущем примере для выхода из цикла использовалась следующая команда:
EXIT WHEN NOT caller_cur%FOUND;
Альтернативная — и возможно, более понятная — формулировка могла бы использовать
%NOTFOUND:
EXIT WHEN caller_cur%NOTFOUND;
Атрибут %ROWCOUNT
Атрибут %ROWCOUNT возвращает количество записей, прочитанных из курсора к моменту запроса атрибута. При исходном открытии курсора атрибут %ROWCOUNT равен 0. При обращении к атрибуту %ROWCOUNT курсора, который еще не был открыт, инициируется исключение INVALID_CURSOR. После выборки каждой записи %ROWCOUNT увеличивается на единицу. Используйте атрибут %ROWCOUNT для проверки того, что программа прочитала (или обновила в случае DML) нужное количество строк, или для прерывания выполнения после заданного числа итераций. Пример:
BEGIN
UPDATE employees SET last_name = 'FEUERSTEIN';
DBMS_OUTPUT.PUT_LINE (SQL%ROWCOUNT);
END;
Атрибут %ISOPEN
Атрибут %ISOPEN возвращает TRUE, если курсор открыт; в противном случае возвращается FALSE.
Приведем типичный пример использования этого атрибута, который гарантирует, что курсор не остается открытым, если в программе произойдет что-то непредвиденное:
DECLARE
CURSOR happiness_cur IS SELECT simple_delights FROM ...;
BEGIN
OPEN happiness_cur;
IF happiness_cur%ISOPEN THEN ...
EXCEPTION
WHEN OTHERS THEN
IF happiness_cur%ISOPEN THEN close happiness_cur;
END IF;
END;
Атрибут %BULK_ROWCOUNT
Атрибут %BULK_ROWCOUNT, предназначенный для использования с командой FORALL, возвращает количество строк, обработанных при каждом выполнении DML. Этот атрибут обладает семантикой ассоциативного массива.
Атрибут %BULK_EXCEPTIONS
Атрибут %BULK_EXCEPTIONS, также предназначенный для использования с командой FORALL, возвращает информацию об исключении, которое может быть инициировано при каждом выполнении DML. Этот атрибут обладает семантикой ассоциативного массива записей.
На атрибуты курсоров можно ссылаться в коде PL/SQL, как показано в приведенных примерах, но вы не сможете напрямую обращаться к ним в команде SQL. Например, при попытке использовать атрибут %ROWCOUNT в секции WHERE команды SELECT:
SELECT caller_id, company_id FROM caller
WHERE company_id = company_cur%ROWCOUNT;
компилятор выдает ошибку PLS-00229: Attribute expression within SQL expression.
Ссылки на переменные PL/SQL в курсорах
Поскольку курсор должен быть связан с командой SELECT, в нем всегда присутствует хотя бы одна ссылка на таблицу базы данных; по ней (и по содержимому условия WHERE) Oracle определяет, какие строки будут возвращены в составе активного набора. Однако это не означает, что команда SELECT может возвращать информацию только из базы данных.
Список выражений, задаваемых между ключевыми словами SELECT и FROM, называется списком выборки. Во встроенном SQL список выборки может содержать столбцы и выражения (вызовы SQL-функций для этих столбцов, константы и т. д.). В PL/SQL список выборки обычно содержит переменные PL/SQL и сложные выражения.
На локальные данные программы PL/SQL (переменные и константы), а также на переменные привязки хост-среды можно ссылаться в предложениях WHERE, GROUP BY и HAVING команды SELECT курсора. Ссылки на переменные PL/SQL можно (и должно) уточнять именем ее области видимости (именем процедуры, именем пакета и т. д.), особенно в командах SQL.
Выбор между явным и неявным курсорами
Все последние годы знатоки Oracle (включая и авторов данной книги) убежденно доказывали, что для однострочной выборки данных никогда не следует использовать неявные курсоры. Это мотивировалось тем, что неявные курсоры, соответствуя стандарту ISO, всегда выполняют две выборки, из-за чего они уступают по эффективности явным курсорам.
Так утверждалось и в первых двух изданиях этой книги, но пришло время нарушить эту традицию (вместе со многими другими). Начиная с Oracle8, в результате целенаправленных оптимизаций неявные курсоры выполняются даже эффективнее эквивалентных явных курсоров.
Означает ли это, что теперь всегда лучше пользоваться неявными курсорами? Вовсе нет. В пользу применения явных курсоров существуют убедительные доводы.
- В некоторых случаях явные курсоры эффективнее неявных. Часто выполняемые критические запросы лучше протестировать в обеих формах, чтобы точно выяснить, как лучше выполнять каждый из них в каждом конкретном случае.
- Явными курсорами проще управлять из программы. Например, если строка не найдена, Oracle не инициирует исключение, а просто принудительно завершает выполняемый блок.
Поэтому вместо формулировки «явный или неявный?» лучше спросить: «инкапсулированный или открытый?» И ответ будет таким: всегда инкапсулируйте однострочные запросы, скрывая их за интерфейсом функции (желательно пакетной) и возвращая данные через RETURN.
Не жалейте времени на инкапсуляцию запросов в функциях, желательно пакетных. Это позволит вам и всем остальным разработчикам вашей группы просто вызвать функцию, когда появится необходимость в данных. Если Oracle изменит правила обработки запросов, а ваши предыдущие наработки станут бесполезными, достаточно будет изменить реализацию всего одной функции.
Вас заинтересует / Intresting for you:
ORA-01001: неправильный курсор
Причина:
Скорее всего программа основного языка вызвала указанный неправильный курсор, или значения параметров AREASIZE и MAXOPENCURSORS в команде прекомпилятора слишком малы. Все курсоры должны быть открыты (используя OOPEN вызов) перед обращением к остальным вызовам: SQL, DESCRIBE, NAME, DEFINE, BIND, EXEC, FETCH, и CLOSE. Logon Data Area (LDA) должна определяться использованием OLON или OLOGON. Если LDA не определена, это сообщение будет исходить из следующих вызовов: OPEN, COM, CON, ROL, и LOGOFF.
Действие:
Проверьте ошибки оператора вызова. Укажите точную область LDA или откройте курсор, где требуется. Если с курсором нет проблем, вам может быть нужно увеличить параметры AREASIZE, MAXOPENCURSORS перед прекомпиляцией.
May 7, 2021
I got ” ORA-01001: invalid cursor ” error in Oracle database.
ORA-01001: invalid cursor
Details of error are as follows.
ORA-01001 invalid cursor Cause: Either a host language program call specified an invalid cursor or the value of the MAXOPENCURSORS option in the precompiler command were too small. All cursors must be opened using the OOPEN call before being referenced in any of the following calls: SQL, DESCRIBE, NAME, DEFINE, BIND, EXEC, FETCH, and CLOSE. The Logon Data Area (LDA) must be defined by using OLON or OLOGON. If the LDA is not defined, this message is issued for the following calls: OPEN, COM, CON, ROL, and LOGOFF. Action: Check the erroneous call statement. Specify a correct LDA area or open the cursor as required. If there is no problem with the cursor, it may be necessary to increase the MAXOPENCURSORS option value before precompiling.
invalid cursor
This ORA-01001 error is related with the Either a host language program call specified an invalid cursor or the value of the MAXOPENCURSORS option in the precompiler command were too small. All cursors must be opened using the OOPEN call before being referenced in any of the following calls: SQL, DESCRIBE, NAME, DEFINE, BIND, EXEC, FETCH, and CLOSE. The Logon Data Area (LDA) must be defined by using OLON or OLOGON. If the LDA is not defined, this message is issued for the following calls: OPEN, COM, CON, ROL, and LOGOFF.
Check the erroneous call statement. Specify a correct LDA area or open the cursor as required. If there is no problem with the cursor, it may be necessary to increase the MAXOPENCURSORS option value before precompiling.
When trying to pass back a ref cursor from a stored procedure results in the errors:
ORA-01001 Invalid cursor
ORA-00604 recursive cursor error
Sql Code that Reproduces the problem:
DROP TABLE emp;
DROP PACKAGE emp_pkg;
CREATE TABLE emp
(empno VARCHAR2(10),
empname VARCHAR2(30),
deptno VARCHAR2(5),
salary NUMBER(10,2));
INSERT INTO emp VALUES ('A001','TESTA1','A', 1000);
INSERT INTO emp VALUES ('B001','TESTB1','B', 1000);
INSERT INTO emp VALUES ('C001','TESTC1','C', 1000);
INSERT INTO emp VALUES ('A002','TESTA2','A', 2000);
INSERT INTO emp VALUES ('B002','TESTB2','B', 2000);
INSERT INTO emp VALUES ('C002','TESTC2','C', 2000);
INSERT INTO emp VALUES ('A003','TESTA3','A', 3000);
INSERT INTO emp VALUES ('B003','TESTB3','B', 3000);
INSERT INTO emp VALUES ('C003','TESTC3','C', 3000);
COMMIT;
CREATE OR REPLACE PACKAGE emp_pkg AS TYPE Ref_Cursor IS REF CURSOR;
PROCEDURE get_empdata2(i_tid VARCHAR2, o_cur OUT ref_cursor);
PROCEDURE get_det(i_tid VARCHAR2, o_cur1 OUT ref_cursor);
END emp_pkg;
/
CREATE OR REPLACE PACKAGE BODY emp_pkg AS v_sql VARCHAR2(2000);
PROCEDURE get_empdata2(i_tid VARCHAR2, o_cur OUT ref_cursor)
IS
BEGIN
OPEN o_cur FOR
SELECT '' empno, '' empname, deptno, SUM(salary) salary
FROM (SELECT deptno, empno, empname, salary FROM emp WHERE empno LIKE '%1'
UNION ALL SELECT deptno, empno, empname, salary FROM emp WHERE empno LIKE '%2'
UNION ALL SELECT deptno, empno, empname, salary FROM emp WHERE empno LIKE '%3')
GROUP BY deptno;
END get_empdata2;
PROCEDURE get_det(i_tid VARCHAR2,
o_cur1 OUT ref_cursor)
IS
BEGIN
v_sql := 'BEGIN emp_pkg.get_empdata2(:tid, :o_cur); END;';
EXECUTE IMMEDIATE v_sql USING i_tid, OUT o_cur1;
END get_det;
END emp_pkg;
/
To reproduce the error execute the following in sqlplus:
SET SERVEROUTPUT ON SIZE 10000
DECLARE
TYPE Ref_Cursor IS REF CURSOR;
o_cur2 ref_cursor;
c_cur emp%ROWTYPE;
v_tid VARCHAR2(10);
BEGIN
EMP_PKG.get_det(v_tid, o_cur2);
FETCH o_cur2 INTO c_cur;
WHILE o_cur2%FOUND
LOOP
DBMS_OUTPUT.PUT_LINE(c_cur.deptno || ' * ' || c_cur.salary);
FETCH o_cur2 INTO c_cur;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error - ' || SQLERRM);
END;
/
Results seen in sqlplus:
DECLARE
*
ERROR at line 1:
ORA-01001: invalid cursor
ORA-06512: at line 9
Errors started after upgrading the Oracle Database to version 11.1.0.7.0 or 11.2.0.1.0.
They are experiencing Bug 9110335 “ORA-1001 WITH TYPED REF CURSOR AND EXECUTE IMMEDIATE AFTER 11107 UPGRADE”.
There are several coding workarounds to this issue:
1. Use a local ref cursor in the execute immediate statement and assign the value to the ref cursor that is being passed back.
Change the procedure get_det to the following, the code changes are in bold:
PROCEDURE get_det(i_tid VARCHAR2,o_cur1 OUT ref_cursor)
IS
v_cur1 Ref_Cursor;
BEGIN
v_sql := 'BEGIN emp_pkg.get_empdata2(:tid, :o_cur); END;';
EXECUTE IMMEDIATE v_sql USING i_tid, OUT v_cur1;
o_cur1 := v_cur1;
END get_det2;
2. Use SYS_REFCURSOR instead of ref cursor.
Note: This workaround did not resolve the error for the code used in this note. It did resolve the error for the code in Bug 9110335.
To solve this error, You should increase the MAXOPENCURSORS option value before precompiling.
Do you want to learn Oracle Database for Beginners, then read the following articles.
Oracle Tutorial | Oracle Database Tutorials for Beginners ( Junior Oracle DBA )
1,336 views last month, 1 views today
About Mehmet Salih Deveci
I am Founder of SysDBASoft IT and IT Tutorial and Certified Expert about Oracle & SQL Server database, Goldengate, Exadata Machine, Oracle Database Appliance administrator with 10+years experience.I have OCA, OCP, OCE RAC Expert Certificates I have worked 100+ Banking, Insurance, Finance, Telco and etc. clients as a Consultant, Insource or Outsource.I have done 200+ Operations in this clients such as Exadata Installation & PoC & Migration & Upgrade, Oracle & SQL Server Database Upgrade, Oracle RAC Installation, SQL Server AlwaysOn Installation, Database Migration, Disaster Recovery, Backup Restore, Performance Tuning, Periodic Healthchecks.I have done 2000+ Table replication with Goldengate or SQL Server Replication tool for DWH Databases in many clients.If you need Oracle DBA, SQL Server DBA, APPS DBA, Exadata, Goldengate, EBS Consultancy and Training you can send my email adress [email protected].- -Oracle DBA, SQL Server DBA, APPS DBA, Exadata, Goldengate, EBS ve linux Danışmanlık ve Eğitim için [email protected] a mail atabilirsiniz.
ORA-01001: invalid cursor
Oracle SQL Error: ORA-01001: invalid cursor
Cause:
Either a host language program call specified an invalid cursor or the value of the MAXOPENCURSORS option in the precompiler command were too small. All cursors must be opened using the OPEN call before being referenced in any of the following calls: SQL, DESCRIBE, NAME, DEFINE, BIND, EXEC, FETCH, and CLOSE.
Solution:
Check the error call statement. Specify a correct LDA area or open the cursor as required. If there is no problem with the cursor, it may be necessary to increase the MAXOPENCURSORS option value before precompiling.
Example:
DECLARE CURSOR c1 IS SELECT * FROM books; rec books%ROWTYPE; BEGIN LOOP FETCH c1 INTO rec; EXIT WHEN c1%NOTFOUND; DBMS_OUTPUT.PUT_LINE(rec.NAME); END LOOP; END;
Output:
ORA-01001: invalid cursor
ORA-06512: at line 6
Correct
DECLARE CURSOR c1 IS SELECT * FROM books; rec books%ROWTYPE; BEGIN OPEN c1; LOOP FETCH c1 INTO rec; EXIT WHEN c1%NOTFOUND; DBMS_OUTPUT.PUT_LINE(rec.NAME); END LOOP; CLOSE c1; END;
Output:
anonymous block completed


