table.QUERY_CREATE Function


<INDEX> as P = Query_Create([C flags[,C Filter_expression[,C Order_Expression[,args as SQL::Arguments]]]])



Optional. Default = the current value of Query.options. Specifies if Alpha Anywhere should use an index, a new query list, or an existing query list to satisfy a query. This string can contain one or more of the following codes:

If flags is not specified, you can provide instructions using the QUERY.options variable.
Alpha Anywhere does not clear the prior values of QUERY.options, QUERY.Filter, or QUERY.Order when you do a new query. See below for more information about the QUERY object.

This flag does two things. The first behavior is to force Alpha Anywhere to build a query list rather than use an index (should an existing index that matches the query definition be available). The second behavior is to prevent Alpha Anywhere from setting this query list as the "last used query". (When you open a Form or Browse, if you do not explicitly define a query for the layout, Alpha Anywhere will use the "last used query" for the table or set on which the layout is based. )


The descending order option puts the records in descending alphabetical order or, for a numeric field, from highest to lowest value.


This is a "Temporary Query". Temporary queries are automatically deleted when there are no query slots available when creating a new query. The maximum number of query slots is 16.


The unique option includes only unique records in the query list.


Instructs Alpha Anywhere not to check to see if an existing query list could be used. Alpha Anywhere will build a new query list, even if there was an existing query list that matched the query definition.


Use an index even if an existing query exists (which Alpha Anywhere would otherwise have used in preference to the index).


The I flag is obsolete. It was previously used to indicate that the index should be case-insensitive. All indexes are case-insensitive in Alpha Anywhere. It is listed here because in some situations, the Script Recorder will show Xbasic code that includes the "I" flag.


Forces a query on an active-link table to be performed locally (i.e. client-side), even if the query optimizer determines that the query could have been performed on the server.


Executes a query on an active-link table on the server if the query optimizer determines that the query can be performed on the server. This is the default for queries on active-link tables.


Default = the current value of Query.Filter. An expression that evaluates to a logical value for each record in the table. If you leave both the filter_expression and order_expression blank, you must define the Query.Filter or Query.Order.


Optional. Default = the current value of Query.Order. An expression that evaluates to a character value and references one or more fields in the table. If you leave both the filter_expression and order_expression blank, you must define the Query.Filter or Query.Order.


A SQL::Arguments object that contains arguments used in the filter expression. For example:

dim args as sql::arguments
p = t.query_create("","bill_city = :whatcity","",args)



Returns an object pointer. <INDEX> will reference one of the following:

  • a previously created query list that satisfies the query definition
  • an index with the same definition as the query
  • a new query list


Creates a new query.


The QUERY_CREATE() method orders and selects data from the table referenced by a table object. If the optional order and filter expressions are specified, then QUERY.Order and QUERY.Filter will be ignored. Note that QUERY.Order and QUERY.Filter are deprecated and that you should prefer to use the filter_expression and order_expression parameters to specify a filter and order for the query.

The query for the QUERY_CREATE method is defined in the QUERY object. Query can contain the following:


Type "C". The name of the query.


DEPRECATED: Use Order_Expression argument

Optional. Default = "" (record number order). A character expression that includes a reference to at least one field in the table.


DEPRECATED: Use Filter_Expression argument

Optional. Default = ".T." (all records). A character filter expression that evaluates to a logical value and selects the records to retrieve.


DEPRECATED: Use Flags argument.

Optional. Default = Record order, ascending, not unique. Controls whether Alpha Anywhere uses an index, a new query list, or an existing query list to satisfy a query. See flags above for more information.

Alpha Anywhere will only select a previously created query list if the query list is still up to date. It will be out of date if the table was edited after the query list was built.

If Alpha Anywhere selects a previously created query list, or an existing index, the result is returned instantaneously. If a new query list must be built, the time taken to build the query list is a function of the size of the table, and whether Alpha Anywhere can use Lightning Query Optimization.

fitler_expression is the filter expression (a character string). It can be any valid Alpha Anywhere expression that returns a result of .T. (TRUE) or .F. (FALSE). For example, the following are valid filter expressions:

"Lastname = \"smith\" .and. state = \"CA\""
"Lastname = 'smith' .and. state = 'CA'"
".not. (Company = \"\")"
"(lastname = \"smith\" .or. lastname = \"jones\") .and. state = \"ca\""
"(lastname = 'smith' .or. lastname = 'jones') .and. state = 'ca'"
The format for defining a filter expression applies to QUERY.Filter as well.

The filter and order expressions cannot include references to the table pointer.

order_expression is the order expression (a character string). It can be any valid expression that references one or more fields. If you want to perform a multi-level sort on character fields, (i.e. sort by Lastname, and within Lastname, sort by firstname ), you simply create an expression on your sort fields, starting with the outer level sort. For example to sort by Lastname, and then by firstname, you would use this order expression:

Lastname + firstname
The format for defining an order expression applies to QUERY.Order as well.

If your sort expression concatenates fields of a different type, (e.g. a character field and a date field), you should convert all of the fields to character. For example:

Lastname + cdate(donation_date) ' a character field and a date
Str(score) + Lastname ' a numeric field and a character field

You can set an option in query.options to control whether Alpha Anywhere uses an index, a new query list, or an existing query list to satisfy a query.

You should reset query.filter, query.order, and query.options to NULL ("") after you finish using them. Since they are global variables, this prevents other scripts from accidentally using inappropriate values.

You can determine whether a reference to an index or a query list was returned by using the <INDEX>.TYPE_GET() method. It returns 2 for an index and 6 for a query list.

A query list is like an index in that it does not contain the records themselves. It just contains the key values of the selected records, and pointers to the actual records in the underlying table. Therefore, if you modify a record value when a query list is active, you are modifying the actual data in the table.

The query list files are stored in the private path, which is set using the View > Settings command from the Control Panel. The query list file names match this pattern: $$*.MPX. The View > Settings command has an option that allows you to specify that the $$*.MPX files (i.e. the temporary query files) for a table should be automatically deleted when Alpha Anywhere is exited. Otherwise, Alpha Anywhere will retain the last four queries for each table.

As with indexes, you can use the <TBL>.FETCH_FIND() method with query lists to find records by key value. In most ways, query list behave the same as indexes. The table below summarizes the differences.


Query Lists

All users who share a table have the same indexes.

Each user creates their own query lists.

Exclusive access to the table is required to add an index.

Exclusive access to the table is not required to build a query list.

Indexes are dynamic. They are updated when records are edited. Key values are always correctly sorted and records that do not satisfy index filters are removed from the index immediately.

Queries are static. They are not updated when records are edited. After it is edited, a record that no longer satisfies the query filter remains in the query list. New records are added to the end of the query list.

Can use the <TBL>.FETCH_FIND() method to find records by key value.

Can use the <TBL>.FETCH_FIND() method to find records by key value.

The optional query.description assigns a name to the query. The query name can be up to 24 characters long. If Alpha Anywhere selects an existing query, or index, rather than running building a new query list, the query.description is not used.

The order expression is used to designate which field or expression sets the primary order of the query. To query a subset of records, you can specify a filter expression. To be included in the query list, a record must satisfy this filter.

If the filter expression is undefined, the filter is assumed to be .T. (TRUE). This means that every record in the table will be selected. If the Order expression is undefined, the order is assumed to be record number order.

If you leave both the filter_expression and order_expression blank, you must define the Query.Filter or Query.Order.. If you wish to select all records in the table, you should specify:

query.filter = ".T."

In the case where <TBL> references a table that is the parent table of a set, the filter expression can reference fields in the sets primary table, and any child tables linked to the parent table with a one-to-one link. Fields from child tables linked to the parent with a one-to-many link cannot be used in the filter expression, unless the FLATTENQUERY()or CROSSLEVEL() function is used (See below).

Use the <INDEX>.RECORDS_GET() method to find out how many records were selected by a query.

When you create a query for a table using the <TBL>.QUERY_CREATE() method, then next time a form or browse that is based on the same table is opened, the last created query will be automatically selected, unless the form or browse specifies its own filter and order properties.

Each table has four slots for query lists. If you create more that four queries for a table (without using the <INDEX>.DROP(), or <TBL>.QUERY_DETACH_ALL() method to delete previously built queries), the new queries will take up one of the four slot positions, pushing one of the older queries off the list of open query lists.

Responding to a Query with No Records 

dim tbl as P
dim qry as P
dim nrecs as N
tbl = table.current()
query.description = "Time Sheet"
query_order = "NAME"
query_filter = "NAME = VAR->Name .and. DATE = {" + VAR->Date + "}"
query_flags = ""
qry = tbl.query_create(query_flags, query_filter, query_order)
nrecs = qry.records_get()
IF (nrecs = 0) then
    ui_msg_box("Null Query","There are no records in the Query" ,UI_INFORMATION_SYMBOL)
    query.order = ""
    query.filter = ""
end if

Active-Link Tables 

When a query is run on an active-link table, Alpha Anywhere will analyze the query expression and determine if any part of the query can be run on the server. If possible, then the portion of the query that can be run on the server, and any remaining portion of the query will be run on the client. If you want to disable the query analyzer and force the query to run on the client, use the "L" query flag.


DBF Tables Only

See Also