27
REXX procs (procedures with logic) in QMF for TSO This document is for the QMF for TSO component only. You can create two types of QMF procedures: linear procedures or procedures with logic. Linear procedures are the most commonly used procedures. Linear procedures, as the name implies, execute commands one at a time in sequence. If any command fails, the procedure ends and the rest of the commands are not executed. Procedures with logic can run both QMF and REXX commands. These procedures are sometimes called REXX procedures or REXX procs for short. REXX procs allow for the full power of REXX and its logic to be executed from within QMF. This document will supply step by step instructions for converting a QMF linear proc to a QMF REXX proc. TSO REXX documentation can be found in the IBM Knowledge Center in the z/OS library. The link for REXX provided with z/OS 2.1 can be found here: z/OS TSO/E REXX Reference: https://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v 2r1.ikja300/toc.htm z/OS TSO/E REXX User’s Guide: https://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/ com.ibm.zos.v2r1.ikjc300/toc.htm User scenario A query may or may not get a result set depending on the value supplied for the prompt. If the query does not produce a result set, we wish to show a report explaining the situation and send email to an

€¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

Embed Size (px)

Citation preview

Page 1: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

REXX procs (procedures with logic) in QMF for TSO

This document is for the QMF for TSO component only.

You can create two types of QMF procedures: linear procedures or procedures with logic. Linear procedures are the most commonly used procedures. Linear procedures, as the name implies, execute commands one at a time in sequence. If any command fails, the procedure ends and the rest of the commands are not executed. Procedures with logic can run both QMF and REXX commands. These procedures are sometimes called REXX procedures or REXX procs for short. REXX procs allow for the full power of REXX and its logic to be executed from within QMF. This document will supply step by step instructions for converting a QMF linear proc to a QMF REXX proc.

TSO REXX documentation can be found in the IBM Knowledge Center in the z/OS library. The link for REXX provided with z/OS 2.1 can be found here:

z/OS TSO/E REXX Reference: https://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.ikja300/toc.htm

z/OS TSO/E REXX User’s Guide:

https://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.ikjc300/toc.htm

User scenario

A query may or may not get a result set depending on the value supplied for the prompt. If the query does not produce a result set, we wish to show a report explaining the situation and send email to an administrator. If the query does produce a report, we will show the user the formatted report.

Setup

This query may or may not produce a result set, depending on the value supplied for the &DEPT prompt.

Here are two reports. One for the case with a result set and on for the case with no result set.

Page 2: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

And

The Proc :

Prompts for a DEPT value and places it in a GLOBAL VARIABLE so that it will be available when the Query that needs it is run.

Prompts for an EMAIL address and places it in a GLOBAL VARIABLE so that it may be used to email the report (if needed).

Next it runs the query.

Then it displays the form that makes the report that is good for the case when there are results.

Then it displays the form that makes the report that is good for the case when there are NO results.

You would not apply both forms for the same result. Below we will add a condition to choose one of these reports.

Finally, it sends me a warning email that the report has failed. Again, I only want this to happen IF the report fails.

There is no provided methodology to email from within QMF for TSO. We will develop a way to do this via Simple Mail Transfer Protocol or SMTP in this document.

Page 3: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

We will break this up into 2 parts, first choosing the form to format the report and then adding methodology to email the failed report via SMTP.

Adding IF-then REXX logic to a linear proc

Here is the text of a starting linear proc if you want to copy and paste it into your QMF session:

SET GLOBAL (DEPT = &ENTER_DEPT_VALUE , EMAILID = &ENTER_EMAIL_IDRUN QUERY TS5519.RXQ_STAFF DISPLAY FORM TS5519.RXF_STAFF1 DISPLAY FORM TS5519.RXF_STAFF2 SHOW REPORT

Let’s turn the linear proc into a REXX proc by adding the /* REXX */ comment identifier, quoting the commands and using the QMF global variable DSQAO_NUM_FETCHED to determine if a result set was generated from the query. If DSQAO_NUM_FETCHED indicates more than 0 rows were fetched, we have a report and will format the report using FORM RXF_STAFF1. If DSQAO_NUM_FETCHED indicates 0 rows were fetched, that would mean there are no rows in the report and we will format the report using FORM RXF_STAFF2.

/* REXX */ "SET GLOBAL (DEPT = &ENTER_DEPT_VALUE , EMAILID = &ENTER_EMAIL_ID""RUN QUERY TS5519.RXQ_STAFF" "GET GLOBAL ("NUMF"=DSQAO_NUM_FETCHED" IF NUMF > 0 THEN "DISPLAY FORM TS5519.RXF_STAFF1" ELSE "DISPLAY FORM TS5519.RXF_STAFF2" "SHOW REPORT"

Methodology to generate email from a QMF procedure

To generate SMTP email of a QMF report from QMF for TSO will require 3 items:

1. A data set containing the QMF report in HTML format2. A data set with SMTP control statements 3. A data set containing JCL which will be submitted in batch to generate the email

Item 1 -

To generate the data set containing the QMF report in HTML format, we will use the EXPORT REPORT command, specifying the keyword option DATAFORMAT=HTML.

We will use QMF FORMs to generate items 2 and 3 on our list.

Page 4: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

Item 2 -

To generate a data set with SMTP control statements, we will run a dummy query and then use FORM.COLUMNS, FORM.PAGE and FORM.OPTIONS processing to produce a report that contains the control statement information.

The dummy query, called, RXQ_DUMMY, looks like this:

The modified parts of form RXF_SMTPCTL are as follows:

FORM.COLUMNS

Here we use the OMIT usage code so that we can completely override the contents of the report.

FORM.OPTIONS

Here we specify Column heading = NO so that we do not get a line for column headings.

FORM.PAGE

Page 5: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

On FORM.PAGE, we put the content of our ‘report’ which is SMTP control statements. Be sure to specify 0 for ‘Blank Lines After Heading’ and ‘Blank Lines Before Footing’. As you can see, some QMF global variables are used in the RXF_SMTPCTL FORM.PAGE contents.

The value of &TSOID will be retrieved in our REXX proc using a REXX call. This can be seen in the complete REXX proc following the example forms.

As seen earlier, the REXX proc prompts the user for the value of &EMAILID. &DATE and &TIME are QMF supplied default form variables.

The SMTP control statements should conform to your z/OS system requirements.

Item 3 –

Now we generate the JCL to run IEBGENER in batch using the same tactics as item 2.

Page 6: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

Using the same query RXQ_DUMMY:

The modified parts of form RXF_JCL2EMAIL are as follows:

FORM.COLUMNS

Here we use the OMIT usage code so that we can completely override the contents of the report.

FORM.OPTIONS

Here we specify Column heading = NO so that we do not get a line for column headings.

FORM.PAGE

On FORM.PAGE, we put the content of our ‘report’ which are JCL statements. Be sure to specify 0 for ‘Blank Lines After Heading’ and ‘Blank Lines Before Footing’. This form is going to use 2 additional QMF global variables, that we will define in our finished REXX proc seen below.

Page 7: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

The final procedure – Email failing reports

Now we will use the RXQ_DUMMY query and forms RXF_SMTPCTL and RXF_JCL2EMAIL to complete the requirements for the user scenario stated above.

Page 8: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

The final REXX proc looks like this:

/* REXX */ /* This statement prompts the user for DEPT and EMAILID values. */"SET GLOBAL (DEPT = &ENTER_DEPT_VALUE , EMAILID = &ENTER_EMAIL_ID""RUN QUERY TS5519.RXQ_STAFF" /* This statement determines if there is a result set or not. */ "GET GLOBAL ("NUMF"=DSQAO_NUM_FETCHED" IF NUMF > 0 THEN DO /* If NUMF is greater than 0, there is a result set so format */ /* the report using form RXF_STAFF1. */ "DISPLAY FORM TS5519.RXF_STAFF1" END ELSE DO /* There is no result set,format the report using RXF_STAFF2 */ "DISPLAY FORM TS5519.RXF_STAFF2" END "SHOW REPORT" IF NUMF = 0 THEN DO /* Retrieve the user entered value to a REXX variable. */ "GET GLOBAL ("BADDEPT"=DEPT" /* Display a helpful message to the user. */ MSGTXT = 'No rows found for DEPT '||BADDEPT||'. Press PF3 to', ' continue.' "MESSAGE (TEXT='"||MSGTXT||"'" /* This will show the report for no result set. */ "INTERACT" /* Cleanup work to delete previous versions of the data sets. */ "TSO DELETE RXSTAFF.REPORT" "TSO DELETE RXTEMP.REPORT" "TSO DELETE RXSMTPCT.REPORT" "TSO FREE FI(DSQPRINT)" /* This statement retrieves the user TSO id to variable TSOID. */ /* Variable TSOID is used in form RXF_SMPTCTL and for data set */ /* naming in this proc. */ "SET GLOBAL (TSOID="SYSVAR(SYSUID) /* This is the user QMF report generated above. */ "EXPORT REPORT TO RXSTAFF (DATAF=HTML CONFIRM NO" /* The exported report data set name. Used in RXF_JCL2EMAIL form. */ "SET GLOBAL (REPORTDSNAME=(&TSOID.RXSTAFF.REPORT))" /* This generates the SMTP control statements. */ "RUN TS5519.RXQ_DUMMY (FORM=TS5519.RXF_SMTPCTL" "EXPORT REPORT TO RXSMTPCT (DATAF=TEXT CONFIRM NO" /* The SMTP cntl stmt data set name. Used in RXF_JCL2EMAIL form.*/ "SET GLOBAL (SMTPCTLDSNAME=(&TSOID.RXSMTPCT.REPORT))" /* Allocate the JCL printed report data set. Must be FB80 */ "TSO ALLOC DSNAME(RXTEMP.REPORT) UNIT(SYSDA) NEW SPACE(5,2) TRACKS", " RECFM(F B ) LRECL(80) BLKSIZE(23440) FI(DSQPRINT)" /* Generate the JCL. */

Page 9: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

"RUN TS5519.RXQ_DUMMY (FORM=TS5519.RXF_JCL2EMAIL" "PRINT REPORT (PR=' ' CC=NO" "TSO FREE FI(DSQPRINT)" DS1=RXTEMP.REPORT /* Submit the generated JCL. */ "TSO SUBMIT "DS1 /* Clear the report panel. */ "RESET DATA" END EXIT

Transferring a result set from one query to another

The next example addresses a long-standing question in QMF.

A user has a query Q2 that is parameterized with a substitution variable. At run time the user does not know what value to supply. The value can only be attained by running another query Q1. So, the user runs Q1 to get the value, then runs Q2 and fills in the value from Q1. If the user could get the result of Q1 fed directly to Q2 the process could be automated.

Here is query Q2 (XFER_GETINFO_Q), which requires a particular department number:

Here is Q1 (XFER_GETID_Q), it gets the department number with the person having the smallest SALARY (of course it could be any other KPI):

Here is a REXX proc that solves the problem:

Page 10: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

After running the XFER_GETID_Q query, the command:

"EXPORT DATA TO XFER1 (DATAFORMAT CSV CONFIRM NO HEADER NO"

generates this TSO data set which contains the DEPT id of the person with the smallest salary:

The command:

"EXECIO * DISKR REPORT1 (STEM CELL. FINIS"

Reads the single value into a REXX stem variable called CELL. Just in case anything else were on the line, we PARSE the value into a REXX variable DEPTRX:

PARSE VAR CELL.1 DEPTRX .

This command passes the value of DEPTRX to the QMF query XFER_GETINFO_Q:

ADDRESS QRW "RUN QUERY TS5519.XFER_GETINFO_Q (&&DEPT="DEPTRX

Here are the text strings for these queries and procs if you would like to try them.

You need the QMF sample tables Q.STAFF and Q.ORG.

Page 11: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

XFER_GETINFO_Q

SELECT * FROM Q.ORG

WHERE DEPTNUMB=&DEPT

XFER_GETID_Q

SELECT DEPT

FROM Q.STAFF

WHERE SALARY = (SELECT MIN(SALARY) FROM Q.STAFF).

The procedure is as follows:

/* REXX */ /* RUN THE QUERY TO GET THE DEPT FOR THE PERSON WITH SMALLEST SALARY */"RUN QUERY TS5519.XFER_GETID_Q" /* CLEANUP */ "TSO DELETE XFER1.DATA" /* EXPORT THE DATA SO IT CAN BE READ INTO REXX VARS. */ "EXPORT DATA TO XFER1 (DATAFORMAT CSV CONFIRM NO HEADER NO" ADDRESS TSO DROP CELL. /* THIS IS THE EXPORTED DATA */ "ALLOC FI(REPORT1) DSN(XFER1.DATA) SHR" /* READ THE INFORMATION INTO A REXX VARIABLE.*/ "EXECIO * DISKR REPORT1 (STEM CELL. FINIS" "FREE FI(REPORT1)" /* PUT THE DEPT VALUE INTO A REXX VAR CALLED DEPTRX */ PARSE VAR CELL.1 DEPTRX . /* YOU COULD SET A GLOBAL VARIABLE */ /*ADDRESS QRW "SET GLOBAL (DEPT="DEPTRX*/ /* OR JUST CALL THE NEXT QUERY AND PASS IN THE DEPT VALUE */ ADDRESS QRW "RUN QUERY TS5519.XFER_GETINFO_Q (&&DEPT="DEPTRX EXIT

In the case above the value of the variable DEPT is good only for the life of this proc. If you need it to be preserved for other procs or queries you can put it in the global parameter list. Note that this command is a combination of QMF command appended with the value of the REXX variable DEPTRX.

ADDRESS QRW "SET GLOBAL (DEPT="DEPTRX

And alter the RUN QUERY command to look like:

ADDRESS QRW "RUN QUERY TS5519.XFER_GETINFO_Q”

Page 12: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

In the example above, the first query was crafted to bring back a single value. This made retrieving the single value DEPTRX easy with a single PARSE statement. What if the first query had been like this:

SELECT * FROM Q.STAFF

ORDER BY SALARY DESC

Now the department number needed is in the third column of the last row.

This version of the proc will do the job. All rows are retrieved into the REXX stem variable CELL. We know we want the third column of the last row. We parse by the template delimited by the ‘,’ (comma) to get the third column of the last row. We do not care about column values after the third value so we PARSE with the template and use the ‘.’ (period) to ignore the rest.

/* REXX */ "RUN QUERY TS5519.XFER_GETID3_Q" "TSO DELETE XFER2.DATA" "EXPORT DATA TO XFER2 (DATAFORMAT CSV CONFIRM NO HEADER NO" ADDRESS TSO DROP CELL. "ALLOC FI(REPORT2) DSN(XFER2.DATA) OLD" /* MAKE SURE THE DATA SET IS CLOSED. */ "EXECIO 0 DISKR REPORT2 (FINIS" "EXECIO * DISKR REPORT2 (STEM CELL. FINIS" "FREE FI(REPORT2)" /* CELL.0 GIVES THE NUMBER OF ITEMS IN THE STEM VARIABLE. */ LASTROW = CELL.0 /* PARSE THE LAST ROW OF DATA TO GET THE VALUE NEEDED */ PARSE VAR CELL.LASTROW ID ',' NAME ',' DEPTID ',' . ADDRESS QRW "SET GLOBAL (DEPT="DEPTID ADDRESS QRW "RUN QUERY TS5519.XFER_GETINFO_Q"

Page 13: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

Iteration

Often you may need to run the same query a number of times with different inputs. This proc does a simple version of this iteration.

/* REXX */ DROP DEPT. DEPT.1 = 10 DEPT.2 = 38 DEPT.3 = 85 DEPT.0 = 3 DO I = 1 TO DEPT.0 DROP NUMROWS "RUN QUERY XFER_GETINFO_Q (&&DEPT="DEPT.I "BOTTOM" "GET GLOBAL ("NUMROWS"=DSQAO_NUM_FETCHED" NUMROWS = STRIP(NUMROWS) MSGTXT = 'THE NUMBER OF ROWS FOR DEPT '||DEPT.I||' IS '||NUMROWS||'.', 'PRESS PF3 TO CONTINUE.' "MESSAGE (TEXT='"||MSGTXT||"'" "INTERACT" "RESET DATA" END EXIT

First, we establish a stem variable called DEPT with a fixed list of three values 10, 38 and 85.

Typically, the 0th element of a STEM variable would have the number of elements, so this is initialized to 3.

The DO loop iterates through the DEPT values until it is complete. The query XFER_GETINFO_Q is run using the stem elements, the BOTTOM command makes sure the whole result set is fetched from the data base. The DSQAO_NUM_FETCHED global variable is referenced to determine the number of rows in the result set. A message is issued to let the user knows how many rows were in the DEPT. The INTERACT command stops the procedure processing so the user may see the message. RESET DATA clears the data object.

The user would see this:

Page 14: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only
Page 15: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

Of course, instead of a message, each loop could create a CSV file, send an email or do a SAVE DATA to create a table.

The next step in iteration would be to use a query result instead of a hard-coded list for the array.

Here is the query ITER_GETID4_Q

SELECT * FROM Q.ORG

Here is the query ITER_GETINFO3_Q

SELECT * FROM Q.STAFF WHERE DEPT=&DEPT

Here is the REXX proc:

/* REXX */ "RUN QUERY TS5519.ITER_GETID4_Q" X = SYSDSN(ITER1.DATA) IF X = 'OK' THEN "TSO DELETE ITER1.DATA" "EXPORT DATA TO ITER1 (DATAFORMAT CSV CONFIRM NO HEADER NO" ADDRESS TSO DROP CELL. DROP DEPTS. "ALLOC FI(REPORT1) DSN(ITER1.DATA) SHR"

Page 16: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

/* MAKE SURE THE DATA SET IS CLOSED. */ "EXECIO 0 DISKR REPORT1 (FINIS" "EXECIO * DISKR REPORT1 (STEM CELL. FINIS" "FREE FI(REPORT1)" ADDRESS QRW DO I = 1 TO CELL.0 PARSE VAR CELL.I DEPTS.I ',' . "RUN QUERY TS5519.ITER_GETINFO3_Q (&&DEPT="DEPTS.I X = SYSDSN(DEPT||DEPTS.I||.DATA) IF X = 'OK' THEN "TSO DELETE DEPT"DEPTS.I".DATA" "EXPORT DATA TO DEPT"DEPTS.I" (DATAFORMAT CSV CONFIRM NO HEADER NO" "RESET DATA" END

This is the output:

The exported data could have been exported to USS as XML files as well using:

"EXPORT DATA TO /u/TS5519/Department"DEPTS.I" (DATAFORMAT XML CONFIRM NO"

And then the output would be available under USS:

Page 17: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

Taking the REXX proc one line at a time, we run the following query to get the seed values:

"RUN QUERY TS5519.ITER_GETID4_Q"

This line reads the exported csv data file:

"EXECIO * DISKR REPORT1 (STEM CELL. FINIS"

And by looking in variable CELL.0, we know the number of rows in the result set. CELL.0 was automatically updated by doing the EXECIO READ command using the STEM CELL. Keyword.

We loop through the rows of the result set starting with row 1.

We know that the DEPTNUMB seed values are in position 1 of the CSV file. This line:

PARSE VAR CELL.I DEPTS.I ',' .

Places the current row DEPTNUMB into a variable DEPTS.I. We run the next query using that value:

"RUN QUERY TS5519.ITER_GETINFO3_Q (&&DEPT="DEPTS.I

And then we EXPORT the rows from the new result set:

"EXPORT DATA TO DEPT"DEPTS.I" (DATAFORMAT CSV CONFIRM NO HEADER NO”

What if the second query needed more than one input? The next section deals with this case.

Here is the query ITER_GETID4_Q

SELECT * FROM Q.ORG

Here is the query ITER_GETINFO4_Q

SELECT * FROM Q.ORG WHERE DEPTNUMB=&DEPT AND DIVISION=&Q&DIV&Q

Here the DIVISION prompt is surrounded by the user set global variable &Q which supplies a single quote. This is needed for character and date/time data. Later we will look at a different approach to quoting character and date values.

Here is the REXX proc, it is similar to the previous proc except DIVISION information is collected and input to ITER_GETINFO4_Q in parallel to DEPT.

/* REXX */ "RUN QUERY TS5519.ITER_GETID4_Q" /* CLEANUP */ X = SYSDSN(ITER2.DATA)

Page 18: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

IF X = 'OK' THEN "TSO DELETE ITER2.DATA" /* EXPORT THE RESULTS FROM ITER_GETID4_Q TO A DATA SET */ "EXPORT DATA TO ITER2 (DATAFORMAT CSV CONFIRM NO HEADER NO" ADDRESS TSO DROP CELL. DROP DEPTS. DROP DIVS. "ALLOC FI(REPORT1) DSN(ITER2.DATA) SHR" /* MAKE SURE THE DATA SET IS CLOSED. */ "EXECIO 0 DISKR REPORT1 (FINIS" /* READ THE RESULT SET JUST EXPORTED INTO A DATA SET TO THE CELL VAR */"EXECIO * DISKR REPORT1 (STEM CELL. FINIS" "FREE FI(REPORT1)" ADDRESS QRW /* SET A GLOBAL VARIABLE TO HAVE A SINGLE QUOTE IN IT */ "SET GLOBAL (Q='" DO I = 1 TO CELL.0 /* PARSE THE REQUIRED INFORMATION INTO STEM VARIABLES */ PARSE VAR CELL.I DEPTS.I ',' . ',' . ',' DIVS.I ',' . /* RUN THE QUERY SUPPLYING THE VALUES JUST READ */ "RUN QUERY TS5519.ITER_GETINFO4_Q (&&DEPT="DEPTS.I",&&DIV="DIVS.I X = SYSDSN(DEPT||DEPTS.I||.DATA) IF X = 'OK' THEN "TSO DELETE DEPT"DEPTS.I".DATA" /* WRITE OUT THE DATA TO DATA SETS */ "EXPORT DATA TO DEPT"DEPTS.I" (DATAFORMAT CSV CONFIRM NO HEADER NO" "RESET DATA" END EXIT

A challenge come up if the input value for a query is character or date and requires single quotes and contain spaces. In this case, the quotes MUST be in place in the PROC or QMF will not be able to parse the Proc..

For example ITER_GETID4_Q

SELECT *

FROM Q.ORG

Page 19: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

Gets this result

LOCATION is in column 5.

The Query GETINFO6_Q,

SELECT * FROM Q.ORG

WHERE LOCATION =&LOC and DEPTNUMB=&DEPT

,needs LOCATION values fed to it. The problem is that the SQL needs single quotes around the input value in even the regular REXX proc.

RUN QUERY GETINFO6_Q (&&LOC= 'NEW YORK' &&DEPT = 10

However, the query result does not have the single quotes. They must be supplied by the user keying in the values. During an automated run, we need a way to automatically add the single quotes or the array values will not have single quotes and so the Proc and Query will fail.

Single quotes can be added in the REXX call to RUN QUERY like this:

"RUN QUERY TS5519.ITER_GETINFO6_Q (&&LOC='"LOCS.I"',&&DEPT="DEPTS.I

Page 20: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

Making the new working REXX proc:

/* REXX */ "RUN QUERY TS5519.ITER_GETID4_Q" /* CLEANUP */ X = SYSDSN(ITER2.DATA) IF X = 'OK' THEN "TSO DELETE ITER2.DATA" /* EXPORT THE RESULTS FROM ITER_GETID4_Q TO A DATA SET */ "EXPORT DATA TO ITER2 (DATAFORMAT CSV CONFIRM NO HEADER NO" ADDRESS TSO DROP CELL. DROP DEPTS. DROP LOCS. "ALLOC FI(REPORT1) DSN(ITER2.DATA) SHR" /* MAKE SURE THE DATA SET IS CLOSED. */ "EXECIO 0 DISKR REPORT1 (FINIS" /* READ THE RESULT SET JUST EXPORTED INTO A DATA SET TO THE CELL VAR */"EXECIO * DISKR REPORT1 (STEM CELL. FINIS" "FREE FI(REPORT1)" ADDRESS QRW DO I = 1 TO CELL.0 /* PARSE THE REQUIRED INFORMATION INTO STEM VARIABLES */ PARSE VAR CELL.I DEPTS.I ',' . ',' . ',' . ',' LOCS.I /* RUN THE QUERY SUPPLYING THE VALUES JUST READ */ /* SINGLE QUOTE THE LOCS.I VALUES. */ "RUN QUERY TS5519.ITER_GETINFO6_Q (&&LOC='"LOCS.I"',&&DEPT="DEPTS.I X = SYSDSN(DEPT||DEPTS.I||.DATA) IF X = 'OK' THEN "TSO DELETE DEPT"DEPTS.I".DATA" /* WRITE OUT THE DATA TO DATA SETS */ "EXPORT DATA TO DEPT"DEPTS.I" (DATAFORMAT CSV CONFIRM NO HEADER NO" "RESET DATA" END EXIT

Scheduling

REXX procs could be helpful in scheduling procs that need to be run routinely. Using a z/OS automated job scheduler, a single master REXX proc could be scheduled to run daily. The master REXX proc could handle the running of the appropriate procs on the appropriate days and dates.

REXX functions such as DATE, TIME and any logic component available can be used to control which procs are run. Using the methodology explained above, additional batch jobs can be spawned as well.

An example of a simple master scheduling REXX proc is shown below. This proc could be scheduled to run in batch every night but only the appropriate procs for the day and date would be executed.

Page 21: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

/* REXX */ CALL SETUP_DATE_VARS SAY DAY MON DOM LDOM /* PROCS THAT RUN EVERY DAY */ "RUN PROC MASTER_BATCH_DAILY_PROCS" /* PROCS RUN ON A SPECIFIC DAY OF THE WEEK */ /* MUST HAVE ALL 7 MASTER_BATCH_"||DAY||"_PROCS DEFINED. */ "RUN PROC MASTER_BATCH_"||DAY||"_PROCS" /* PROCS RUN ON THE LAST DAY OF THE MONTH FOR CERTAIN MONTHS */SELECT WHEN (DOM=LDOM & MON='APRIL') THEN DO "RUN MASTER_BATCH_"||MON||"_PROCS" END WHEN (DOM=LDOM & MON='DECEMBER') THEN DO "RUN MASTER_BATCH_"||MON||"_PROCS" "RUN MASTER_BATCH_EOY_PROCS" END OTHERWISE; END EXIT SETUP_DATE_VARS: DAY = DATE('W') UPPER DAY MON = DATE('M') UPPER MON DOM = WORD(DATE(),1) YYYY = WORD(DATE(),3) USADATE = DATE('U') PARSE VAR USADATE MM '/' DD '/' YY /* DETERMINE IF THIS IS A LEAP YEAR. */ /* LY=1 MEANS YES IT IS A LEAP YEAR AND FEBRUARY HAS 29 DAYS. */ /* LY=0 MEANS NO IT IS NOT A LEAP YEAR AND FEBRUARY HAS 28 DAYS. */ QLY = YYYY//4 IF QLY = 0 THEN

Page 22: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

LY=1 ELSE LY=0 /* ROUTINE TO DETERMINE THE LAST DAY OF THE MONTH. */ DO MM= 01 TO 12 IF MM <> 2 THEN LDOM = (30 + ((MM>7) <> (MM - ((MM%2)*2)) - ((2-LY)) * (MM=2))) ELSE DO IF LY=0 THEN LDOM = 28 ELSE LDOM = 29 END END RETURN;

If the proc were named MASTER_BATCHP, a job like this could be run:

//QC1MSTR JOB (ACCT),ROBINZ,REGION=600K, // CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),NOTIFY=&SYSUID //RUNIT EXEC PGM=IKJEFT01, // TIME=1440 //STEPLIB DD DISP=SHR,DSN=QMFCOM.QMF1210.SDSQLOAD // DD DISP=SHR,DSN=DSN.VB10.SDSNLOAD // DD DISP=SHR,DSN=DVS.CQD.V1210.SCQDCLOD // DD DISP=SHR,DSN=DVS.CQD.V1210.SCQDLOAD //ISPMLIB DD DISP=SHR,DSN=ISP.SISPMENU // DD DISP=SHR,DSN=QMFCOM.QMF1210.SDSQMLBE //ISPPLIB DD DISP=SHR,DSN=ISP.SISPPENU // DD DISP=SHR,DSN=QMFCOM.QMF1210.SDSQPLBE //ISPSLIB DD DISP=SHR,DSN=ISP.SISPSLIB // DD DISP=SHR,DSN=QMFCOM.QMF1210.SDSQSLBE //ISPTLIB DD DISP=SHR,DSN=ISP.SISPTENU // DD DISP=SHR,DSN=QMFCOM.QMF1210.SDSQTLBE //ISPPROF DD DISP=SHR,DSN=TS5519.ISPF.PROFILE //SYSPRINT DD SYSOUT=* //SYSTSPRT DD SYSOUT=* //SYSTERM DD SYSOUT=* //SYSPUNCH DD SYSOUT=* //SYSEXEC DD DISP=SHR,DSN=QMFCOM.QMF1210.SDSQEXCE //ADMGGMAP DD DISP=SHR,DSN=QMFCOM.QMF1210.SDSQMAPE //DSQPNLE DD DISP=SHR,DSN=QMFCOM.QMF1210.DSQPNLE //ADMDEFS DD DISP=SHR,DSN=TS5519.PROFILE.ADMDEFE //DSQDEBUG DD SYSOUT=* //DSQUDUMP DD SYSOUT=* //DSQPRINT DD SYSOUT=* //SYSTSIN DD *

Page 23: €¦ · Web viewREXX procs (procedures with logic) in QMF for TSO. This document is for the QMF for TSO component only

ISPSTART PGM(DSQQMFE) NEWAPPL(DSQE) PARM(S=DB1A,M=B,MR=YES,+ I=TS5519.MASTER_BATCHP,L=YES,ST=64BIT)