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 
01Beginning of theMAINblock. TheSCHEMAstatement is not needed since this module does not define any program variables in terms of a database table. - Line 
03uses theDEFER INTERRUPTstatement to prevent the user from terminating the program prematurely by pressing the INTERRUPT key. - Line 
07opens a window with the same form that was used in the Chapter 3 example. - Lines 
09thru18contains theMENUfor the query program. Four actions -query,next,previous, andquit- will be displayed as buttons on the form. The predefined actionsaccept(OK button) andcancelwill automatically be displayed as buttons when theCONSTRUCTstatement is executed. - Line 
11calls the functionquery_custin the cust_query.4gl module. - Line 
13calls the functionfetch_rel_custin 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 
15calls the functionfetch_rel_custalso, but passes the literal value -1, indicating that the cursor should move backwards to retrieve the previous row in the results set. - Line 
17exits theMENUstatement. - Line 
20closes the window that was opened. - Line 
22disconnects 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 
03is required to identify the database schema file to be used when compiling the module. - Lines 
05thru15define 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 
18definescont_ok, a local variable of data typeSMALLINT, to be used as a flag to indicate whether the query should be continued. The keywordsTRUEandFALSEare used to set the value of the variable (0=FALSE, <> 0=TRUE). - Line 
19defines another localSMALLINTvariable,cust_cnt, to hold the number of rows returned by theSELECTstatement. - Line 
20defineswhere_clauseas a localSTRINGvariable to hold the boolean condition resulting from theCONSTRUCTstatement. - Line 
21displays a message to the user that will remain until it is replaced by anotherMESSAGEstatement. - Line 
22setscont_oktoFALSE, prior to executing the statements of the function. - Line 
24setsINT_FLAGtoFALSE. It is common to set this global flag toFALSEimmediately prior to the execution of an interactive dialog, so your program can test whether the user attempted to cancel the dialog. - Lines 
25thru32: TheCONSTRUCTstatement 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 NAMEsyntax matches the database columns to form fields having the same name. - Line 
34is the beginning of anIFstatement testing the value ofINT_FLAG. This test appears immediately after theCONSTRUCTstatement, to test whether the user terminated theCONSTRUCTstatement (INT_FLAGwould be set by the runtime system toTRUE). - Lines 
35thru38are executed only if the value ofINT_FLAGisTRUE. TheINT_FLAGis 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_okflag is set toFALSE, and a message is displayed to the user. The program will continue with the statements after theEND IFon line49. - Lines 
40thru50: contain the logic to be executed ifINT_FLAGwas not set toTRUE(the user did not cancel the query).-  In lines 
40and41, theget_cust_cntfunction is called, to retrieve the number of rows that would be returned by the query criteria. Thewhere_clausevariable is passed to the function, and the value returned will be stored in thecust_cntvariable. -  Lines 
42is the beginning of a nestedIFstatement, testing the value ofcust_cnt. -  Lines 
43thru46are executed if the value ofcust_cntis greater than zero; a message with the number of rows returned is displayed to the user, and the functioncust_selectis called. Thewhere_clauseis passed to this function, and the returned value is stored incont_ok. Execution continues with the statement after theEND IFon line51. - 
                                                  
Lines
48and49are executed if the value is zero (no rows found); a message is displayed to the user, andcont_okis set toFALSE. Execution continues after theEND IFon line51. 
 -  In lines 
 - Line 
49is the end of theIFstatement beginning on line33. - Lines 
53thru55test the value ofcont_ok, which will have been set during the precedingIFstatements and in the functioncust_select. Ifcont_okisTRUE, the functiondisplay_custis called. - Line 
57is the end of thequery_custfunction. 
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 
01The function accepts as a parameter the value ofwhere_clause, stored in the local variablep_where_clausedefined on Line60. - Line 
02defines a local string variable,sql_txt, to hold the complete text of the SQLSELECTstatement. - Line 
04defines a local variablecust_cntto hold the count returned by theSELECTstatement. - Lines 
06thru08create the string containing the complete SQLSELECTstatement, concatenatingp_where_clauseat the end using the || operator. Notice that the wordWHEREmust be provided in the string. - Line 
10uses thePREPAREstatement 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 
11executes the SQLSELECTstatement contained incust_cnt_stmt, using theEXECUTE ... INTOsyntax 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 
12TheFREEstatement releases the memory associated with thePREPAREd statement, since this statement is no longer needed. - Line 
14returns the value ofcust_cntto the calling function,query_cust. - Line 
16is the end of theget_cust_cntfunction.