Re: read backwards?

From: David Hermann <dhe_at_phcs.phcs.com>
Date: 1995/08/02
Message-ID: <3volo4$n3v_at_palm.phcs.com>#1/1


In article <3vljdh$pi9_at_calweb.calweb.com>, rdugaue_at_web1.calweb.com (Robert Du Gaue) writes:
|> We have a database with appoximately 500,000 rows. One query allows users
|> to bring up a list of names so that they can narrow down to a specific
|> data record. When the list is up, we want them to have the ability to
|> page forward and backward. The forward works fine, however the backward query
|> using a 'where name < first_displayed_name' type of query goes back to
|> the begining of the table and basically reads 1,000s of rows.
|>
|> Is there a way to read backwards from a certian point and return say the
|> next 25 names before a specific key and not have ORacle start from the
|> begining of the table?

There's a way to simulate this kind of behavior, but it's tricky. Here's a sketch. I assume a base table and block called PEOPLE with a single key field NAME, and a control block called CONTROL.


    <<< block PEOPLE trigger KEY-PRVREC >>>     BEGIN
    if :system.cursor_record = '1' then

  • we're at the first record of the latest data set
  • retrieved, but the user wants to move to the
  • record "before" this one
  • function GET_PREV_NAME takes a NAME and uses some
  • method to pick a NAME that would be earlier than
  • the current NAME
  • it could be as simple as taking SMITH and returning
  • RMITH (decrementing the initial), or as precise as
  • opening a cursor of { NAME < the current NAME }
  • with "order by NAME desc", and finding the particular
  • NAME that is, say, 25 rows earlier than the current NAME
  • however the function works, put the current and
  • "previous" name into control fields :control.curr_name := :people.name; :control.prev_name := get_prev_name( :people.name ); if :control.prev_name = :control.curr_name then
  • if the most "previous" NAME the function could find
  • was the current NAME, then we're at the first row of
  • the entire table and can't back up any more :control.prev_name := null; message( 'At first record.' ); raise form_trigger_failure; end if;
  • (handle pending updates, etc., here) ...
  • (see <<< block PEOPLE trigger PRE-QUERY >>> below) execute_query; chk_package_failure;
  • move from the first record of this new data set down
  • to the first record of the last data set loop if :people.name = :control.curr_name then
  • we're back to the database row where we started, but
  • :system.cursor_record is now '26' or '99' or something exit; elsif :system.last_record = 'TRUE' then message( 'Error: can''t find "'||:control.curr_name||'"' ); raise form_trigger_failure; else next_record; end if; end loop;
  • [else] we're not at record #1 end if; previous record; END;
    <<< block PEOPLE trigger PRE-QUERY >>> BEGIN if :control.prev_name is not null then
  • block PEOPLE trigger KEY-PRVREC gave us a criterion
  • for the current query copy( '#>='''||:control.prev_name||'''', 'people.name' ); :control.prev_name := null; end if; END;
    If your NAME key is not unique, you might have to throw in consideration of ROWIDs. You could also tweak this if your key was actually ( LAST_NAME , FIRST_NAME ) or something more complex.

By the way, once I demonstrated the admittedly jerky behavior of this method, my supervisors decided they didn't need this kind of functionality after all, and would just make users re-query with different criteria. But it can be done.

Good luck. Received on Wed Aug 02 1995 - 00:00:00 CEST

Original text of this message