OPEN QUERY statement
- Last Updated: January 18, 2024
- 7 minute read
- OpenEdge
- Version 12.8
- Documentation
Opens a query, which might have been previously defined in a DEFINE
QUERY statement. Opening a query makes it available for use within a
GET statement, or in a browse widget.
Syntax
|
- query
- The query to open. The query name may have been defined previously in
a
DEFINE QUERYstatement. Otherwise, theOPEN QUERYstatement implicitly defines the query. - { FOR | PRESELECT } EACH record-phrase
- Specifies the first buffer of the query.
The following is the syntax for record-phrase:
record [ [ LEFT ] ] [ OF table ] [ WHERE expression ] [ TENANT-WHERE expression [ SKIP-GROUP-DUPLICATES ]] [ USING [ FRAME frame ] field [ AND [ FRAME frame ] field ] ... ] [ USE-INDEX index ] [ SHARE-LOCK | EXCLUSIVE-LOCK | NO-LOCK ] [ NO-PREFETCH ]If the query was previously defined, the buffers referenced by the record-phrase must be the same buffers referenced in the
DEFINE QUERYstatement and in the same order. For more information, see the Record phrase reference entry.Note that the first buffer must be qualified with
EACHrather than theFIRSToption. That is, theOPEN QUERYstatement implies the possibility of a multi-row result, whether or not only one row is returned.If you specify
PRESELECTrather thanFOR, then the AVM preselects the records for the query. During the preselect process, the AVM applies whatever locking is specified in theOPEN QUERYstatement or, if none is specified,SHARE-LOCK. It then reads theROWIDfor each record into the result list. (If you do not specifyPRESELECT, the AVM might pass through the records anyway to presort them. In this case, the AVM appliesNO-LOCKto each record during this pass.) - { EACH | FIRST | LAST }record-phrase
- Specifies subsequent buffers in the query. Each subsequent buffer
specifies a join with the previous buffer(s) according to the record-phrase. If the query was previously defined, the buffers referenced
by the record-phrase must be the same buffers
referenced in the
DEFINE QUERYstatement and in the same order. For more information on specifying joins in Record phrases, see the Record phrase reference entry. - query-tuning-phrase
- Allows programmatic control over the execution of a DataServer query.
Following is the syntax for the query-tuning-phrase:
QUERY-TUNING ( [ LOOKAHEAD [ CACHE-SIZE integer]| NO-LOOKAHEAD ] [ DEBUG { SQL | EXTENDED }| NO-DEBUG ] [ SEPARATE-CONNECTION | NO-SEPARATE-CONNECTION ] [ JOIN-BY-SQLDB | NO-JOIN-BY-SQLDB ] [ BIND-WHERE | NO-BIND-WHERE ] [ INDEX-HINT | NO-INDEX-HINT ] )For more information, see your OpenEdge DataServer Guides (Use the Microsoft SQL Data Server and Use the Oracle Data Server).
- BREAK
- Over a series of query iterations, you might want to do some work
based on whether the value of a certain field changes. This field defines a break group.
For example, you might be accumulating some value, such as a total. You use the
BREAKoption to define customer.state as the break group, as shown:OPEN QUERY q-order FOR EACH customer BREAK BY customer.state NO-LOCK.When using the
BREAKoption you must also use theBYoption to name a sort field.To test whether a break group has changed, you can use the FIRST-OF( ) method and LAST-OF( ) method of the query object handle.
- BY expression[ DESCENDING ]
- Specifies the order in which records are to be returned. If an index
is defined with the right leading keys to satisfy the
BYclause, the AVM uses that index to sort the records. Otherwise, the AVM must presort the records before the first fetch when you specifyBY. TheDESCENDINGoption sorts the records in descending order (not in the default ascending order). - COLLATE ( string , strength[ , collation] ) [ DESCENDING ]
- Generates the collation value of a string after applying a particular
strength, and optionally, a particular collation. The
DESCENDINGoption sorts the records in descending order (not in default ascending order).- string
- A CHARACTER expression that evaluates to the string whose collation value you want to generate.
- strength
- A CHARACTER expression that evaluates to an ABL comparison
strength or an International Components for Unicode (ICU) comparison strength.
The ABL comparison strengths include:
- RAW — Generates a collation value for the string based on its binary value.
- CASE-SENSITIVE — Generates a case-sensitive collation value for the string based on a particular collation. If you specify this strength with an ICU collation, the AVM applies the ICU TERTIARY strength.
- CASE-INSENSITIVE — Generates a case-insensitive collation value for the string based on a particular collation. If you specify this strength with an ICU collation, the AVM applies the ICU SECONDARY strength.
- CAPS — Generates a collation value
for the string based on its binary value after converting any lowercase
letters in the string to uppercase letters, based on the settings of the
Internal Code Page (
-cpinternal) and Case Table (-cpcase) startup parameters.
The ICU comparison strengths include:
- PRIMARY — Generates a collation value for the base characters in the string.
- SECONDARY — Generates a collation value for the base characters and any diacritical marks in the string.
- TERTIARY — Generates a case-sensitive collation value for the base characters and any diacritical marks in the string.
- QUATERNARY — Generates a case-sensitive collation value for the base characters and any diacritical marks in the string, and distinguishes words with and without punctuation. ICU uses this strength to distinguish between Hiragana and Katakana when applied with the ICU-JA (Japanese) collation. Otherwise, it is the same as TERTIARY.
Note: Use ICU comparison strengths only with ICU collations. - collation
- A CHARACTER expression that evaluates to the name of an ABL
collation table or ICU collation. If collation
does not appear, COLLATE uses the collation table of the client.
- The AVM reports an error and stops execution if one of the
following occurs:
- strength does not evaluate to a valid value.
- collation does not evaluate to a collation table residing in the convmap.cp file.
- collation evaluates
to a collation table that is not defined for the code page corresponding
to the
-cpinternalstartup parameter.
- The AVM reports an error and stops execution if one of the
following occurs:
- INDEXED-REPOSITION
- If you specify this option, the AVM attempts to optimize subsequent
REPOSITION TO ROWIDoperations on the query. This can improve the performance ofREPOSITIONoperations that must jump over many records in a simple query. Optimization is not possible if the database is not an OpenEdge database, or sorting or preselection is performed. In these cases, theINDEXED-REPOSITIONoption is ignored and no error is reported.The optimization has some side effects. When you perform a
REPOSITION TO ROWIDwith this optimization, the AVM discards the original result list and begins a new one. Therefore, scrolling forward or backward in the list might return different records from before. Also, the values of theNUM-RESULTSandCURRENT-RESULT-ROWbecome invalid. If the query has an associated browse, any selections in that browse are also lost. Lastly, the vertical scrollbar thumb is disabled. Because of these side-effects, use this option selectively. - MAX-ROWS num-results
- Specifies the maximum number of records to be returned by the query.
Any other records satisfying the query are ignored and no error
is raised. The limit is imposed before any sorting occurs; the AVM
retrieves records up to the number specified and then sorts those
records.
This option is valid for scrolling queries only. You can use it to prevent a long delay that might occur if a query returns many more records than you expect.
Example
The following example opens a query on the Customer,
Order, OrderLine, and Item tables:
r-opqury.p
|
Note the use of field lists in the DEFINE QUERY
statement. This can improve the performance of remote database queries significantly.
Notes
- If the query you reference in an
OPEN QUERYstatement is already open, then that query is closed and a new query is opened. - If you use the
USE-INDEXoption of the Record phrase, the AVM uses only that index. Records are returned in index order. - The locking options of the
OPEN QUERYstatement define the default locking for records fetched by the query. You can override the default by using a locking option in theGETstatement. Note, however, that in theOPEN QUERYstatement you can specify a separate lock type for each buffer; in theGETstatement you can specify only one lock type that applies to all buffers in a join. - The record locking behavior specified for a query in the
DEFINE BROWSEstatement overrides the record locking behavior specified with theOPEN QUERYstatement. The default record locking behavior of a browse widget isNO-LOCK. The default record locking behavior of a query defined with theOPEN QUERYstatement isSHARE-LOCK. If you define a query and a browse widget for the query without explicitly defining record locking behavior, the query will have theNO-LOCKbehavior. - Each time you open a query associated with a browse widget, the data in the browse is refreshed.
- If you reopen a query to refresh the data displayed in a browse widget,
a selected row might not reflect the database's most current data. To view the latest data
in a selected row, add a
FIND CURRENTstatement before theOPEN QUERYstatement. This additional code allows the AVM to put the current record into memory before executing theOPEN QUERYstatement. - You cannot use the
CAN-FINDfunction in aWHEREclause. Doing so generates a compiler error. - If you open a query that has already been defined with multiple
buffers, you must specify the buffers in the same order in the
OPEN QUERYas they were specified in theDEFINE QUERYstatement. - Once the query has been opened, you cannot change the buffers that it
references, even if the query is closed and re-opened. For example, a buffer, buff1, is
created for the customer table in a
DEFINE QUERYorOPEN QUERYfor the query,qry1. The query is run and closed. You cannot nowDEFINEorOPEN qry1withbuff1for theitemtable. You can reuse buffers withCREATE QUERY, but you must re-runQUERY-PREPARE. - A ProDataSet data-relation defined with
REPOSITIONorSELECTIONis overridden if a query is defined for a child relation data-source. Normally, ifREPOSITIONis not specified, the child query selects the children of the parent. But coding a query for the child data-source overrides whether or not aSELECTIONorREPOSITIONrelation mode was defined. - For sorting and indexing purposes, the Unknown value (
?) sorts high. This means that fields with the Unknown value (?) are sorted after all other values, so when you display all records of a table, the records with the Unknown value (?) in the field(s) used for ordering the record appear last. However, if the query does a range match on that field, the rules in Table 1 still apply. That is, a query with aWHEREclause with"field < ?"does not return any records due to the rules described in Table 1. That also impacts a query with theINDEXED-REPOSITIONoption and a range match where the runtime needs to validate that the record is part of the query's result-set. For that reason, it is recommended that theWHEREphrase of such queries use theEQorNEoperator with the Unknown value (?) to define if they should be included or not, if that field could have the Unknown value (?).
See also
CLOSE QUERY statement, CREATE QUERY statement, CURRENT-RESULT-ROW function, DEFINE BROWSE statement, DEFINE DATASET statement, DEFINE QUERY statement, GET statement, NUM-RESULTS function, QUERY-OFF-END function, QUERY-PREPARE( ) method, REPOSITION statement