By default, a query against database tables uses SHARE-LOCK, so that other users can see the same records but not update them. A query is not scrollable by default. That is, the query does not have the ability to move backward as well as forward in the query. When you associate a browse with a query (by way of the DEFINE BROWSE statement), the ABL Virtual Machine (AVM) automatically changes the query to use the NO-LOCK and SCROLLABLE options. You can also associate a query with a browse at run time. In this case, you should make the query SCROLLABLE when you define it. Since it is important for you to begin to separate user interface procedures from database access procedures even in these first exercises, this section extends the temp-table-based OrderLine browse from Define and Use Temp-tables so that you think in terms of browsing temp-tables in a client procedure that might be in a separate session from where the database is located. In this case, locking the temp-table records is not an issue since those records are always used only within your local session.

Once you define the query, define the browse, and open the query, the browse and the query become tightly bound. The currently selected row and the result list cursor are in sync and remain so. When the user manipulates the browse, the user is also performing the same manipulation on the cursor of the result list. Many programmatic actions performed on the result list or the browse automatically update the other, although this is not universally true. You could say that learning all the subtleties of the browse involves learning what occurs by default, what you have to manage, and what behaviors you can override.

As a rule, a query associated with a browse should be used exclusively by that browse. While you can use GET statements on the query to manipulate the query’s cursor, the result list, and the associated buffers, you run the risk of putting the browse out of sync with the query. If you do mix browse widgets and GET statements with the same query, you must use the REPOSITION statement to manually keep the browse in sync with the query.

Plan for the size of the result set

The number of records in your result list can have a serious impact on the performance of your browse, especially when you consider that you typically have to load those records into a temp-table and ship them across a network connection before they are seen in the browse. You might want to optimize your query definition to take advantage of features that work well with small and large sets of data, and design your user interface to encourage or require users to provide selection criteria to reduce the number of records that need to go into the data they are browsing.