How to Show a Record Count Before Scrolling in Oracle Forms

Count the records of a query before it runs in Oracle Forms 14.1.2 and show users where they are, without waiting for the last row to be fetched.

After a query, the Oracle Forms status line shows Record: 1/? until the user scrolls to the last record, because Forms fetches rows only as they are needed. Users would rather see "Patient 1 of 15" straight away.

This guide shows how to count the records of a query before it runs in Oracle Forms 14.1.2, with COUNT_QUERY and QUERY_HITS, and how to show the current position in a counter item.

Sample Form for This Guide

The examples and screenshots use the sample form CH39_FIND from the Oracle Forms code repository on GitHub. Download it, open it in Forms Builder, and connect as CAREWELL to follow along.

FormFileWhat it shows
CH39_FINDforms/ch39/ch39_find.fmbThe Patient 1 of 15 counter

The forms run against the CareWell Clinic sample schema, which you install first.

Count Before the Query

COUNT_QUERY counts the rows that the block's next query would return, using the block's current WHERE clause, without fetching them. It leaves the number in the block property QUERY_HITS.

Put the count just before EXECUTE_QUERY, in the procedure that queries the block. These are the lines from the search procedure of the sample form.

Count the rows, then query:

  go_block('PATIENTS');
  :system.message_level := '25';         -- hide FRM-40355, the message of COUNT_QUERY (level 25)
  count_query;
  :system.message_level := '0';
  :ctl.total := get_block_property('PATIENTS', QUERY_HITS);
  execute_query;

The total goes into CTL.TOTAL, an item of the control block that sits on no canvas.

Hide the Count Message

COUNT_QUERY reports its result as a message.

Output:

FRM-40355: Query will retrieve 15 records

A counter makes that message redundant. FRM-40355 has severity level 25, so setting :SYSTEM.MESSAGE_LEVEL to 25 around the call hides it, and setting it back to 0 restores normal messages. In a test, a first version that set the level to 5 still showed the message: the level must be at least the message's own severity.

Message levels and other ways to manage messages are covered in how to handle errors in Oracle Forms using ON-ERROR.

Show the Position in Each Record

WHEN-NEW-RECORD-INSTANCE fires every time the cursor enters a record, which makes it the place to update the counter.

Example (WHEN-NEW-RECORD-INSTANCE trigger on block PATIENTS):

if :patients.patient_id is null then
  :ctl.counter := null;
else
  :ctl.counter := 'Patient ' || :system.cursor_record || ' of ' || :ctl.total;
end if;

:SYSTEM.CURSOR_RECORD is the number of the current record. An empty record, such as the one after the last, clears the counter.

Oracle Forms search form with a Patient 1 of 15 counter below the records while the status line shows Record 1/?
The counter shows the total at once, while the status line still shows Record: 1/?.

What the Count Costs

  • A second query. COUNT_QUERY runs SELECT COUNT(*) with the same WHERE clause. That is worth it for a search screen, but not for a block that users page through one record at a time.
  • A snapshot. The count is taken when the user searches, so rows added by other users afterwards are not counted until the next search.
  • No recount on sorting. Changing the order with ORDER_BY does not change the number of rows, so the counter stays right without counting again.

Conclusion

To show a record count before the user scrolls, call COUNT_QUERY just before EXECUTE_QUERY, read the total from QUERY_HITS, and hide FRM-40355 by raising :SYSTEM.MESSAGE_LEVEL to 25 around the call. Update the counter in WHEN-NEW-RECORD-INSTANCE from :SYSTEM.CURSOR_RECORD. The price is one extra COUNT(*) query per search.

Vinish Kapoor
Vinish Kapoor

An Oracle ACE and software veteran with 25+ years of experience, passionate about AI and IT innovation.

guest

0 Comments
Oldest
Newest Most Voted
00