The Query program
The Query program consists of two modules. The custmain.4gl module must be linked with the custquery.4gl module in order for the program to be run.
The line numbers shown in the code are for reference only, and are not a part of the code.
Example: Module custmain.4gl
This module contains the MAIN
program block for the query program,
and the MENU
that drives the query actions.
01 MAIN
02
03 DEFER INTERRUPT
04
05 CONNECT TO "custdemo"
06 CLOSE WINDOW SCREEN
07 OPEN WINDOW w1 WITH FORM "custform"
08
09 MENU "Customer"
10 ON ACTION query
11 CALL query_cust()
12 ON ACTION next
13 CALL fetch_rel_cust(1)
14 ON ACTION previous
15 CALL fetch_rel_cust(-1)
16 ON ACTION exit
17 EXIT MENU
18 END MENU
19
20 CLOSE WINDOW w1
21
22 DISCONNECT CURRENT
23
24 END MAIN
- Line
01
Beginning of theMAIN
block. TheSCHEMA
statement is not needed since this module does not define any program variables in terms of a database table. - Line
03
uses theDEFER INTERRUPT
statement to prevent the user from terminating the program prematurely by pressing the INTERRUPT key. - Line
07
opens a window with the same form that was used in the Chapter 3 example. - Lines
09
thru18
contains theMENU
for the query program. Four actions -query
,next
,previous
, andquit
- will be displayed as buttons on the form. The predefined actionsaccept
(OK button) andcancel
will automatically be displayed as buttons when theCONSTRUCT
statement is executed. - Line
11
calls the functionquery_cust
in the cust_query.4gl module. - Line
13
calls the functionfetch_rel_cust
in the cust.query.4gl module. The literal value 1 is passed to the function, indicating that the cursor should move forward to the next row. - Line
15
calls the functionfetch_rel_cust
also, but passes the literal value -1, indicating that the cursor should move backwards to retrieve the previous row in the results set. - Line
17
exits theMENU
statement. - Line
20
closes the window that was opened. - Line
22
disconnects from the database.
There are no further statements so the Query program terminates.
Example: Module custquery.4gl
This module of the Query program contains the logic for querying the database and displaying the data retrieved.
The function query_cust
is called by the "query" option of the
MENU
in
custmain.4gl.
query_cust
):01 -- custquery.4gl
02
03 SCHEMA custdemo
04
05 DEFINE mr_custrec RECORD
06 store_num LIKE customer.store_num,
07 store_name LIKE customer.store_name,
08 addr LIKE customer.addr,
09 addr2 LIKE customer.addr2,
10 city LIKE customer.city,
11 state LIKE customer.state,
12 zip_code LIKE customer.zip_code,
13 contact_name LIKE customer.contact_name,
14 phone LIKE customer.phone
15 END RECORD
16
17 FUNCTION query_cust()
18 DEFINE cont_ok SMALLINT,
19 cust_cnt SMALLINT,
20 where_clause STRING
21 MESSAGE "Enter search criteria"
22 LET cont_ok = FALSE
23
24 LET INT_FLAG = FALSE
25 CONSTRUCT BY NAME where_clause
26 ON customer.store_num,
27 customer.store_name,
28 customer.city,
29 customer.state,
30 customer.zip_code,
31 customer.contact_name,
32 customer.phone
33
34 IF (INT_FLAG = TRUE) THEN
35 LET INT_FLAG = FALSE
36 CLEAR FORM
37 LET cont_ok = FALSE
38 MESSAGE "Canceled by user."
39 ELSE
40 CALL get_cust_cnt(where_clause)
41 RETURNING cust_cnt
42 IF (cust_cnt > 0) THEN
43 MESSAGE cust_cnt USING "<<<<",
44 " rows found."
45 CALL cust_select(where_clause)
46 RETURNING cont_ok
47 ELSE
48 MESSAGE "No rows found."
49 LET cont_ok = FALSE
50 END IF
51 END IF
52
53 IF (cont_ok = TRUE) THEN
54 CALL display_cust()
55 END IF
56
57 END FUNCTION
- Line
03
is required to identify the database schema file to be used when compiling the module. - Lines
05
thru15
define aRECORD
,mr_custrec
, that is modular in scope, since it is at the top of the module and outside any function. The values of this record will be available to, and can be set by, any function in this module. - Line
17
: Functionquery_cust
. This is the beginning of the functionquery_cust
. - Line
18
definescont_ok
, a local variable of data typeSMALLINT
, to be used as a flag to indicate whether the query should be continued. The keywordsTRUE
andFALSE
are used to set the value of the variable (0=FALSE
, <> 0=TRUE
). - Line
19
defines another localSMALLINT
variable,cust_cnt
, to hold the number of rows returned by theSELECT
statement. - Line
20
defineswhere_clause
as a localSTRING
variable to hold the boolean condition resulting from theCONSTRUCT
statement. - Line
21
displays a message to the user that will remain until it is replaced by anotherMESSAGE
statement. - Line
22
setscont_ok
toFALSE
, prior to executing the statements of the function. - Line
24
setsINT_FLAG
toFALSE
. It is common to set this global flag toFALSE
immediately prior to the execution of an interactive dialog, so your program can test whether the user attempted to cancel the dialog. - Lines
25
thru32
: TheCONSTRUCT
statement lists the database columns for which the user may enter search criteria. The program does not permit the user to enter search criteria for the address columns. TheBY NAME
syntax matches the database columns to form fields having the same name. - Line
34
is the beginning of anIF
statement testing the value ofINT_FLAG
. This test appears immediately after theCONSTRUCT
statement, to test whether the user terminated theCONSTRUCT
statement (INT_FLAG
would be set by the runtime system toTRUE
). - Lines
35
thru38
are executed only if the value ofINT_FLAG
isTRUE
. TheINT_FLAG
is immediately reset toFALSE
, since it is a global variable which other parts of your program will test. The form is cleared of any criteria that the user has entered, thecont_ok
flag is set toFALSE
, and a message is displayed to the user. The program will continue with the statements after theEND IF
on line49
. - Lines
40
thru50
: contain the logic to be executed ifINT_FLAG
was not set toTRUE
(the user did not cancel the query).- In lines
40
and41
, theget_cust_cnt
function is called, to retrieve the number of rows that would be returned by the query criteria. Thewhere_clause
variable is passed to the function, and the value returned will be stored in thecust_cnt
variable. - Lines
42
is the beginning of a nestedIF
statement, testing the value ofcust_cnt
. - Lines
43
thru46
are executed if the value ofcust_cnt
is greater than zero; a message with the number of rows returned is displayed to the user, and the functioncust_select
is called. Thewhere_clause
is passed to this function, and the returned value is stored incont_ok
. Execution continues with the statement after theEND IF
on line51
. -
Lines
48
and49
are executed if the value is zero (no rows found); a message is displayed to the user, andcont_ok
is set toFALSE
. Execution continues after theEND IF
on line51
.
- In lines
- Line
49
is the end of theIF
statement beginning on line33
. - Lines
53
thru55
test the value ofcont_ok
, which will have been set during the precedingIF
statements and in the functioncust_select
. Ifcont_ok
isTRUE
, the functiondisplay_cust
is called. - Line
57
is the end of thequery_cust
function.
Example: custquery.4gl (Function get_cust_cnt)
This function is called by the function query_cust
to return
the count of rows that would be retrieved by the SELECT
statement. The criteria previously entered by the user and stored
in the variable where_clause
is used.
get_cust_cnt
:01 FUNCTION get_cust_cnt(p_where_clause)
02 DEFINE p_where_clause STRING,
03 sql_text STRING,
04 cust_cnt SMALLINT
05
06 LET sql_text =
07 "SELECT COUNT(*) FROM customer" ||
08 " WHERE " || p_where_clause
09
10 PREPARE cust_cnt_stmt FROM sql_text
11 EXECUTE cust_cnt_stmt INTO cust_cnt
12 FREE cust_cnt_stmt
13
14 RETURN cust_cnt
15
16 END FUNCTION
- Line
01
The function accepts as a parameter the value ofwhere_clause
, stored in the local variablep_where_clause
defined on Line60
. - Line
02
defines a local string variable,sql_txt
, to hold the complete text of the SQLSELECT
statement. - Line
04
defines a local variablecust_cnt
to hold the count returned by theSELECT
statement. - Lines
06
thru08
create the string containing the complete SQLSELECT
statement, concatenatingp_where_clause
at the end using the || operator. Notice that the wordWHERE
must be provided in the string. - Line
10
uses thePREPARE
statement to convert the string into an executable SQL statement, parsing the statement and storing it in memory. The prepared statement is modular in scope. The prepared statement has the identifiercust_cnt_stmt
, which does not have to be defined. - Line
11
executes the SQLSELECT
statement contained incust_cnt_stmt
, using theEXECUTE ... INTO
syntax to store the value returned by the statement in the variablecust_cnt
. This syntax can be used if the SQL statement returns a single row of values. - Line
12
TheFREE
statement releases the memory associated with thePREPARE
d statement, since this statement is no longer needed. - Line
14
returns the value ofcust_cnt
to the calling function,query_cust
. - Line
16
is the end of theget_cust_cnt
function.