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.