WITH HOLD and FOR UPDATE
Hold cursors and not portable.
IBM® Informix® supports WITH HOLD
cursors using the FOR UPDATE
clause. Such cursors
can remain open across transactions (when using FOR
UPDATE
, locks are released at the end of a transaction,
but the WITH HOLD
cursor is not closed). This kind
of cursor is IBM Informix-specific
and not portable. The SQL standards recommend closing FOR
UPDATE
cursors and release locks at the end of a transaction.
Most database servers close FOR UPDATE
cursors when
a COMMIT WORK
or ROLLBACK WORK
is
done. All database servers release locks when a transaction
ends.
Database Server Type | WITH HOLD FOR UPDATE support |
---|---|
IBM DB2® LUW | No, see details |
IBM Informix | Yes, native SQL feature |
IBM Netezza | No, see details |
Microsoft™ SQL Server | No, see details |
Oracle® MySQL | No, see details |
Oracle Database Server | No, see details |
PostgreSQL | No, see details |
SAP® ASE | No, see details |
SAP HANA® | No, see details |
SQLite | No, see details |
It is mandatory to review code using WITH HOLD
cursors
with a SELECT
statement having the FOR
UPDATE
clause.
FOR UPDATE
cursor
outside the transaction and open the cursor inside the
transaction:DECLARE c1 CURSOR FOR SELECT ... FOR UPDATE
BEGIN WORK
OPEN c1
FETCH c1 INTO ...
UPDATE ...
COMMIT WORK
SELECT FOR UPDATE
, then for all rows in the array, start a
transaction and perform the UPDATE WHERE CURRENT OF
for the current master
record and the UPDATE
for detail rows, then commit the transaction and
continue with the next master
record:DEFINE x, mkeys DYNAMIC ARRAY OF INTEGER
DECLARE c1 CURSOR FOR SELECT key FROM master ...
FOREACH c1 INTO x
LET mkeys[mkeys.getLength()+1] = x
END FOREACH
DECLARE c2 CURSOR FOR SELECT * FROM master WHERE key=? FOR UPDATE
FOR x = 1 TO mkeys.getLength()
BEGIN WORK
OPEN c2 USING mkeys[x]
FETCH c2 INTO mrec.*
IF STATUS==NOTFOUND THEN
ROLLBACK WORK
CONTINUE FOR
END IF
UPDATE master SET ... WHERE CURRENT OF c2
UPDATE detail SET ... WHERE master_key=mkeys[x]
COMMIT WORK
END FOR