Informix Error -259
-259 Cursor not open.
The current statement refers to a cursor that has not been opened. Review the logic of the program to see how it failed to execute the OPEN statement before it reached this point. Statements that end transactions (COMMIT WORK and ROLLBACK WORK) also close cursors unless the cursors are declared WITH HOLD.
Oninit® Troubleshooting Guidance
Reasons / Common Causes
-259 means a statement referenced a cursor that isn't open — and the official text calls out an
easy-to-miss detail behind one of the most common causes: COMMIT WORK and ROLLBACK WORK close
cursors automatically, unless the cursor was declared WITH HOLD.
FETCH/CLOSE(or similar) attempted beforeOPENwas ever called on the cursor — the direct, straightforward case.- A
COMMIT WORKorROLLBACK WORKexecuted mid-loop, betweenFETCHcalls, unintentionally closing the cursor. This is a very common, easy-to-miss gotcha, especially in code that commits periodically inside a fetch loop for batching purposes — the cursor doesn't survive that commit unless it was declared to. - Assuming a cursor stays open across a transaction boundary without declaring it
WITH HOLD. - An
OPENthat failed silently — its return value wasn't checked, and subsequent code assumes the cursor is open when it isn't.
Solutions / Resolution
- Review program logic for a missing
OPENbefore the cursor is used, per the official guidance. - If the code needs to commit or roll back while the cursor stays open across that boundary
— a common pattern for batch processing inside a fetch loop — declare the cursor
WITH HOLDexplicitly. - Check the return value of
OPENto confirm it actually succeeded before proceeding to use the cursor.
Examples
COMMIT WORK closing a cursor mid-loop
DECLARE cur1 CURSOR FOR SELECT * FROM orders WHERE status = 'pending';
OPEN cur1;
WHILE (fetch_succeeds) DO
FETCH cur1 INTO ...;
process_row();
IF (batch_size_reached) THEN
COMMIT WORK; -- closes cur1, since it wasn't declared WITH HOLD
END IF;
END WHILE;
-- -259 on the next FETCH after the periodic COMMIT WORK
Fix — declare the cursor WITH HOLD so it survives the periodic commits:
DECLARE cur1 CURSOR WITH HOLD FOR SELECT * FROM orders WHERE status = 'pending';
OPEN cur1;
WHILE (fetch_succeeds) DO
FETCH cur1 INTO ...;
process_row();
IF (batch_size_reached) THEN
COMMIT WORK; -- cur1 stays open
END IF;
END WHILE;
An unchecked OPEN failure
isopen_result = EXEC SQL OPEN cur1;
/* return value not checked */
EXEC SQL FETCH cur1 INTO :rec;
/* -259 if the OPEN actually failed for an unrelated reason */
Diagnostic Checks
- Review the call sequence for
OPENbefore the failing statement. - Check for a
COMMIT WORK/ROLLBACK WORKbetweenOPENand the failing statement, and whether the cursor was declaredWITH HOLD. - Check whether the original
OPENcall's return value was verified.
Related Errors / Related Topics
- -207 — "Cannot update cursor declared on more than one table. / Cannot declare a SELECT INTO statement FOR UPDATE." Another cursor-declaration restriction in the same general family.
- -255 — "Not in transaction." Related through the same transaction-boundary-affects-cursor- state theme.
If this happens right after a periodic COMMIT WORK inside a fetch loop, declare the cursor
WITH HOLD — that's almost always the fix.