Summary:
See also: Flow Control, Dynamic SQL, Result Sets
Query By Example enables a user to query a database by specifying values (or ranges of values) for screen fields that correspond to the database. The runtime system converts the search filters entered by the user into a Boolean SQL condition that can appear in the WHERE clause of a prepared SELECT statement.
The CONSTRUCT instruction handles Query By Example input in the current open form and generates the SQL condition in a string variable. You can then use Dynamic SQL instructions to execute the SQL statement to produce a result set:
The following table lists all relational operators that can be used during a Query By Example input:
Symbol | Meaning | Data Type Domain | Pattern |
= | Is Null | All Simple SQL types | = |
= or == | Equal to | All Simple SQL types | ==x, =x |
> | Greater than | All Simple SQL types | >x |
< | Less than | All Simple SQL types | <x |
>= | Not less than | All Simple SQL types | >=x |
<= | Not greater than | All Simple SQL types | <=x |
<> or != | Not equal to | All Simple SQL types | !=x, <>x |
: or .. | Range | All Simple SQL types | x:y, x..y |
* | Wildcard for any string | CHAR, VARCHAR | *x, x*, *x* |
? | Single-character wildcard | CHAR, VARCHAR | ?x, x?, ?x?, x?? |
| | Logical OR | All Simple SQL types | a | b |
[c] | A set of characters | CHAR, VARCHAR | [a-z]*, [xy]? |
The CONSTRUCT instruction handles Query By Example input.
CONSTRUCT BY NAME
variable ON column-list
[ ATTRIBUTE ( { display-attribute |
control-attribute } [,...] ) ]
[ HELP help-number
]
[ dialog-control-block
[...]
END CONSTRUCT ]
CONSTRUCT
variable ON column-list FROM field-list
[ ATTRIBUTE ( { display-attribute |
control-attribute } [,...] ) ]
[ HELP
help-number ]
[ dialog-control-block
[...]
END CONSTRUCT ]
where column-list is :
{ column-name
| table-name.*
|
table-name.column-name
} [,...]
where field-list is :
{ field-name
| table-name.*
|
table-name.field-name
|
screen-array[line].*
|
screen-array[line].field-name
|
screen-record.*
|
screen-record.field-name
} [,...]
where dialog-control-block is one of:
{ BEFORE CONSTRUCT
dialog-statement
[...]
| AFTER CONSTRUCT
dialog-statement
[...]
| BEFORE FIELD field-name
[,...]
dialog-statement
[...]
| AFTER FIELD field-name
[,...]
dialog-statement
[...]
| ON IDLE idle-seconds
dialog-statement
[...]
| ON ACTION action-name
dialog-statement
[...]
| ON KEY ( key-name [,...]
)
dialog-statement
[...]
}
where dialog-statement is one of :
{
statement
| NEXT FIELD { NEXT |
PREVIOUS | field-name }
| CONTINUE
CONSTRUCT
| EXIT CONSTRUCT
}
The following table shows the display-attributes supported by the CONSTRUCT statement:
Attribute | Description |
BLACK, BLUE, CYAN, GREEN, MAGENTA, RED, WHITE,
YELLOW Console Only! |
The color of the entered text. |
BOLD, DIM, INVISIBLE, NORMAL Console Only! |
The font attribute of the entered text. |
REVERSE, BLINK, UNDERLINE Console Only! |
The video attribute of the entered text. |
The following table shows the control-attributes supported by the CONSTRUCT statement:
Attribute | Description |
HELP = help-number | Defines the help number when help is invoked by the user, where help-number is an integer literal or a program variable. |
FIELD ORDER FORM | Indicates that the tabbing order of fields is defined by the TABINDEX attribute of form fields. |
CANCEL = bool | Indicates if the default action 'cancel' should be added to the dialog. If not specified, the action is registered. |
ACCEPT = bool | Indicates if the default action 'accept' should be added to the dialog. If not specified, the action is registered. |
The CONSTRUCT statement stores, in a character variable, an SQL expression corresponding to query by example criteria that a user specifies. You can use this variable in the WHERE clause of a SELECT statement.
To use the CONSTRUCT statement, you must do the following:
The CONSTRUCT statement activates the current form. This is the form most recently displayed or, if you are using more than one window, the form currently displayed in the current window. You can specify the current window by using the CURRENT WINDOW statement. When the CONSTRUCT statement completes execution, the form is cleared and deactivated.
Screen field tabbing order is defined by the order of the field names in the FROM clause; by default this is the list of column names in the ON clause when no FROM clause is specified.To complete the search functionality of your program, you must implement the following steps after the CONSTRUCT instruction:
If no criteria were entered, the string ' 1=1'
is assigned to variable. This is a Boolean SQL expression that always
evaluates to TRUE so that all rows are returned.
After executing the CONSTRUCT instruction, the runtime system sets the INT_FLAG variable to TRUE if the input was canceled by the user.
When the CONSTRUCT statement completes execution, the form is cleared.
The ATTRIBUTE clause specifications override all default attributes and temporarily override any display attributes that the OPTIONS or the OPEN WINDOW statement specified for these fields. While the CONSTRUCT statement is executing, the runtime system ignores the INVISIBLE attribute.
Using the FIELD ORDER FORM attribute: By default, the tabbing order is defined by the column list in the instruction description. You can control the tabbing order by using the FIELD ORDER FORM attribute: When this attribute is used, the tabbing order is defined by the TABINDEX attribute of the form fields.
The HELP clause specifies the number of a help message to display if the user invokes the help while the focus is in any field used by the instruction. The predefined 'help' action is automatically created by the runtime system. You can bind action views to the 'help' action.
When an CONSTRUCT instruction executes, the runtime system creates a set of default actions. See the control block execution order to understand what control blocks are executed when a specific action is fired.
The following table lists the default actions created for this dialog:
Default action | Control Block execution order |
accept | Validates the CONSTRUCT dialog (validates field criterias) Creation can be avoided with ACCEPT attribute. |
cancel | Cancels the CONSTRUCT dialog (no validation, int_flag is set) Creation can be avoided with CANCEL attribute. |
close | By default, cancels the CONSTRUCT dialog (no validation, int_flag is set) Default action view is hidden. See Windows closed by the user. |
help | Shows the help topic defined by the HELP clause. Only created when a HELP clause is defined. |
The accept and cancel default actions can be avoided with the ACCEPT and CANCEL dialog control attributes:
01
CONSTRUCT BY NAME cond ON field1 ATTRIBUTES( CANCEL=FALSE )02
...
Use a BEFORE CONSTRUCT block to execute instructions before the runtime system gives control to the user for criteria input.
Use an AFTER CONSTRUCT block to execute instructions after the user has finished criteria input.
Use a BEFORE FIELD field-name block to execute instructions before the field-name field is made current.
Use an AFTER FIELD field-name block to execute instructions when the user moves to another field.
The ON IDLE idle-seconds clause defines a set of instructions that must be executed after idle-seconds of inactivity. This can be used, for example, to quit the dialog after the user has not interacted with the program for a specified period of time. The parameter idle-seconds must be an integer expression. If it evaluates to zero, the timeout is disabled.
01
...02
ON IDLE 1003
IF ask_question("Do you want to leave the dialog?") THEN04
EXIT CONSTRUCT05
END IF06
...
You can use ON ACTION blocks to execute a sequence of instructions when the user raises a specific action. This is the preferred solution compared to ON KEY blocks, because ON ACTION blocks use abstract names to control user interaction.
01
...02
ON ACTION zoom03
CALL zoom_customers() RETURNING st, cust_id, cust_name04
...
For backward compatibility, you can use ON KEY blocks to execute a sequence of instructions when the user presses a specific key. The following key names are accepted by the compiler:
Key Name | Description |
ACCEPT | The validation key. |
INTERRUPT | The interruption key. |
ESC or ESCAPE | The ESC key (not recommended, use ACCEPT instead). |
TAB | The TAB key (not recommended). |
Control-char | A control key where char can be any character except A, D, H, I, J, K, L, M, R, or X. |
F1 through F255 | A function key. |
DELETE | The key used to delete a new row in an array. |
INSERT | The key used to insert a new row in an array. |
HELP | The help key. |
LEFT | The left arrow key. |
RIGHT | The right arrow key. |
DOWN | The down arrow key. |
UP | The up arrow key. |
PREVIOUS or PREVPAGE | The previous page key. |
NEXT or NEXTPAGE | The next page key. |
The following table shows the order in which the runtime system executes the control blocks in the CONSTRUCT instruction, according to the user action:
User action | Control Block execution order |
Entering the dialog |
|
Moving from field A to field B |
|
Validating the dialog |
|
Canceling the dialog |
|
The NEXT FIELD field-name instruction gives the focus to the specified field. You typically use this instruction to control field input dynamically, in BEFORE FIELD or AFTER FIELD blocks. Abstract field identification is supported with the CURRENT, NEXT and PREVIOUS keywords. These keywords represent respectively the current, next and previous fields, corresponding to variables as defined in the input binding list (with the FROM or BY NAME clause).
CONTINUE CONSTRUCT skips all subsequent statements in the current control block. The focus returns to the most recently occupied field in the current form, giving the user another chance to enter data in that field.
EXIT CONSTRUCT terminates the CONSTRUCT instruction without executing any other statement.
Inside the dialog instruction, the predefined keyword DIALOG represents the current dialog object. It can be used to execute methods provided in the dialog built-in class.
For example, you can enable or disable an action with the setActionAction() dialog method, or you can also hide and show the default action view with setActionHidden():
01
...02
BEFORE CONSTRUCT03
CALL DIALOG.setActionActive("refresh",FALSE)04
AFTER FIELD field105
CALL DIALOG.setActionHidden("refresh",1)
The language provides several built-in functions and operators to use in an CONSTRUCT statement. You can access the field buffers and keystroke buffers with: FIELD_TOUCHED(), GET_FLDBUF(), INFIELD(), FGL_DIALOG_GETFIELDNAME(), FGL_DIALOG_GETBUFFER(), FGL_DIALOG_SETBUFFER().
Form definition in the const.per file:
01
DATABASE formonly02
03
LAYOUT04
GRID05
{06
FirstName [f001 ]07
LastName [f002 ]08
e-Mail [f003 ]09
}10
END11
END12
13
ATTRIBUTES14
f001 = formonly.field1 TYPE CHAR;15
f002 = formonly.field2 TYPE CHAR;16
f003 = formonly.field3 TYPE CHAR;17
END
Program:
01
MAIN02
03
DEFINE condition CHAR(100)04
15
DATABASE stores09
05
OPEN WINDOW w1 WITH FORM "const"06
07
CONSTRUCT condition08
ON first_name, last_name, mail09
FROM field1, field2, field310
11
CLOSE WINDOW w112
13
DISPLAY condition14
15
END MAIN
Form definition in the const.per file:
01
DATABASE stores02
03
LAYOUT04
GRID05
{06
FirstName [f001 ]07
LastName [f002 ]08
}09
END10
END11
12
TABLES13
customer14
END15
16
ATTRIBUTES17
f001 = customer.first_name;18
f002 = customer.last_name;19
END
Program :
01
MAIN02
03
DEFINE condition VARCHAR(100)04
DEFINE statement VARCHAR(200)05
DEFINE cust RECORD06
first_name CHAR(30),07
last_name CHAR(30)08
END RECORD09
10
DATABASE stores11
12
OPEN WINDOW w1 WITH FORM "const"13
14
CONSTRUCT BY NAME condition ON first_name, last_name15
BEFORE CONSTRUCT16
DISPLAY "A*" TO first_name17
DISPLAY "B*" TO last_name18
END CONSTRUCT19
20
LET statement =21
"SELECT first_name, last_name FROM customer WHERE " || condition22
DISPLAY "SQL : " || statement23
24
PREPARE s1 FROM statement25
DECLARE c1 CURSOR FOR s126
FOREACH c1 INTO cust.*27
DISPLAY cust.*28
END FOREACH29
30
CLOSE WINDOW w131
32
END MAIN