Back

Tip 9. Use Datastores Instead of Cursors

Since Powerbuilder 5 introduced datastores I have found myself using them instead of cursors.

Advantages

  • Datastores are easy to use for anyone who has used a datawindow.
  • Datastores are efficient at retrieving data.
  • You can preview the data for debugging.
  • The Powerscript code is slightly simpler
  • You can do grouping easier.
  • You can add advanced filters.
  • You don't always need variables for your data.
  • You can add computed fields to the datawindows and use the answers.
  • You can find the rows count without a separate select.
  • Usually faster (from my experience)

Disadvantages

  • You need the datawindow object.
  • You have to make sure you destroy your datastore to avoid memory problems.
For solutions to these disadvantages see A Dynamic Datawindow Function and A Datastore that Destroys Itself.
For me the ability to look at the data in development mode is far easier than single stepping through the debugger to see what values the cursor is returning.

Here is some sample code of a cursor

string ls_cust_code, ls_customer_name, ls_town

DECLARE lc_my_cursor CURSOR FOR
   SELECT customers.cust_code,
          customers.customer_name,
          customers.town
    FROM customers
    ORDER BY cust_code;

OPEN lc_my_cursor;

    // Fetch first row
FETCH lc_my_cursor INTO 
    :ls_cust_code,
    :ls_customer_name,
    :ls_town;

DO WHILE SQLCA.SQLCode = 0
    // Loop code
    // Fetch next row

   FETCH lc_my_cursor INTO
       :ls_cust_code,
       :ls_customer_name,
       :ls_town;
LOOP

CLOSE lc_my_cursor;

And the equivalent datastore code

string    ls_cust_code, ls_customer_name, ls_town
long      ll_row, ll_row_count
datastore lds_datastore

lds_datastore = CREATE datastore
lds_datastore.DataObject = "ds_customers"
lds_datastore.SetTransObject(SQLCA)
lds_datastore.Retrieve()

ll_row_count = lds_datastore.RowCount()

FOR ll_row = 1 TO ll_row_count
   ls_cust_code = lds_datastore.GetItemString(ll_row, "cust_code")
   ls_customer_name = lds_datastore.GetItemString(ll_row, "customer_name")
   ls_town = lds_datastore.GetItemString(ll_row, "town")

   // Loop code
NEXT

DESTROY lds_datastore
See Also A Datastore that Destroys Itself.
and Dynamic Datawindow Function

I still use an embedded select when I know they is only one row.

Added before 01 Jan 2000

Back