Oracle Forms中执行set_record_property设置QUERY_STATUS后ON-LOCK触发器与LOCK_RECORD失效问题排查
Great question—this is one of those nuanced Forms behaviors that trips up even experienced developers because it involves internal state tracking that's not immediately obvious from basic record status properties.
Let me break down what's happening here and where Forms stores that "record already locked" flag:
First, Why Your ON-LOCK Stopped Firing
When you run:
set_record_property(get_block_property('my_block', current_record),'my_block',status, QUERY_STATUS);
You're forcing the record into a query-only state, which tells Forms "this record hasn't been modified, so no need to lock it." But Forms doesn't just rely on the STATUS property to track locks—it maintains a separate internal flag for whether it believes the record is already locked at the Forms level. Since your ON-LOCK trigger only has debug messages (so it doesn't actually issue a database lock), Forms still thinks the record was locked before you changed the status, so it skips triggering ON-LOCK again.
The Hidden Lock Property You're Looking For
Yes, Oracle Forms stores a record-specific lock status in the RECORD_LOCKED property. This is a read-only boolean property that tracks whether Forms has marked the record as locked (either via an automatic lock trigger firing or a manual LOCK_RECORD call).
To check it, use this code:
DECLARE l_is_locked BOOLEAN; BEGIN l_is_locked := get_record_property( get_block_property('my_block', current_record), 'my_block', RECORD_LOCKED ); IF l_is_locked THEN message('Record is marked as locked in Forms'); ELSE message('Record is not marked as locked in Forms'); END IF; END;
This property exists independently of the record's STATUS (like QUERY_STATUS or CHANGED_STATUS) and doesn't directly reflect the actual database lock status—which aligns with your note that we can exclude database checks here.
What This Means for Your Scenario
After you set the record to QUERY_STATUS, Forms still sees RECORD_LOCKED as TRUE (from your initial lock trigger firing). So when you try to edit the record or call LOCK_RECORD again, Forms skips triggering ON-LOCK because it thinks the lock is already in place.
If you need to reset this state to get ON-LOCK to fire again, you'll need to clear Forms' internal lock flag. Since RECORD_LOCKED is read-only, the most reliable way is to either:
- Re-query the record (e.g.,
EXECUTE_QUERYfor the block, orFETCH_RECORDif you're working with a single record) - Use
CLEAR_RECORDfollowed by reloading the record data programmatically
Bonus: Block-Level Lock Tracking
If you ever need to check lock status for an entire block, you can use the BLOCK_LOCKED block property:
IF get_block_property('my_block', BLOCK_LOCKED) THEN message('At least one record in the block is marked as locked'); END IF;
But this is a broader check and won't help with individual record lock tracking like RECORD_LOCKED does.
内容的提问来源于stack exchange,提问作者Mārtiņš Paukšte

