Informix Error -290
-290 Cursor not declared with FOR UPDATE clause.
This statement attempts to update with a cursor that was not declared for update. The database server does not allow this action, as both a security measure that is designed to prevent program errors and a performance feature. To use a cursor with the UPDATE or DELETE statements, you must declare it for update. Review the program logic to make sure that this statement uses the intended cursor.
In an ANSI-compliant database, any cursor can be used for updating; the FOR UPDATE clause is not required (and generates a warning).
Oninit® Troubleshooting Guidance
Reasons / Common Causes
-290 is a deliberate restriction, not just an oversight: UPDATE/DELETE WHERE CURRENT OF
requires the cursor to have been declared FOR UPDATE — both as a safety measure against
accidental updates through what was meant to be a read-only cursor, and as a performance feature
(the engine optimizes non-FOR UPDATE cursors differently).
- Attempting
UPDATE/DELETE WHERE CURRENT OFa cursor that wasn't declaredFOR UPDATE— the direct cause. - Using the wrong cursor — confusing a read-only cursor with an update-capable one when multiple cursors exist in the same program.
- A version- or mode-specific difference worth knowing about: in an ANSI-compliant database,
any cursor can be used for updating —
FOR UPDATEisn't required there at all, and including it anyway produces a warning (not an error).
Solutions / Resolution
- Declare the cursor
FOR UPDATEif it's meant to be used withUPDATE/DELETE WHERE CURRENT OF. - Review program logic to confirm the intended cursor is actually the one referenced in the failing statement.
- For ANSI-compliant databases, recognize that
FOR UPDATEisn't required — if writing code intended to be portable across both ANSI and non-ANSI databases, be aware of this difference (including it is harmless on ANSI databases beyond the warning, so it's usually safe to include for portability).
Examples
The disallowed update through a non-FOR-UPDATE cursor
DECLARE cur1 CURSOR FOR SELECT * FROM orders WHERE status = 'pending';
OPEN cur1;
FETCH cur1 INTO :rec;
UPDATE orders SET status = 'processing' WHERE CURRENT OF cur1;
-- -290: cur1 wasn't declared FOR UPDATE
Fix:
DECLARE cur1 CURSOR FOR SELECT * FROM orders WHERE status = 'pending' FOR UPDATE;
OPEN cur1;
FETCH cur1 INTO :rec;
UPDATE orders SET status = 'processing' WHERE CURRENT OF cur1;
The ANSI-database difference
-- On an ANSI-compliant database, this cursor can still be used
-- for updates even without FOR UPDATE — but including it anyway
-- for portability just produces a warning, not an error
DECLARE cur1 CURSOR FOR SELECT * FROM orders WHERE status = 'pending' FOR UPDATE;
Diagnostic Checks
- Review the cursor's
DECLAREstatement for the presence ofFOR UPDATE. - Confirm whether the database is ANSI-compliant, since behavior differs there.
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.
- -277 — "UPDATE table table-name is not the same as the cursor table." Another
WHERE CURRENT OF-related restriction, though about table matching rather than theFOR UPDATEdeclaration itself.
Add FOR UPDATE to the cursor's declaration — it's generally safe to include even on ANSI
databases where it isn't strictly required, so this is a reasonable default for portable code.