Running local REXX queries
You can run REXX queries locally via the LOCALREXX option within the rules member.
To run the query as local REXX, the query member in the RULES dataset should contain the LOCALREXX keyword along with the REXX code to be run: LOCALREXX RexxCode
Local REXX queries are loaded from the ECIREXX DD statement.
You can pass up to eight arguments to the REXX query to be available when the local REXX query runs.
The following table describes available address environments:
Address space | Description |
---|---|
EC | Issues the EC command For example, (rc=ecexec('ExecSQL;.'sqlStatement'.'stem.') With this construct, you can run SQL in SPM to retrieve data from the live SPM database. The results are returned in the stem. stem variable. For security purposes, only SELECT operations are permitted. |
ECRACF | Issues a RACF command |
ECMVS | Issues an MVS command |
Each LOCALREXX rule needs the following code:
REXX code | Description | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
rc = ecentry() | Initializes and retrieves entry variables
| ||||||||||||||||||
rc=ecreturn() | LOCALREXX ends and returns control to SPM |
After the rule returns control to SPM, value of stem in the EC_fail.stem stem variable indicates the number of failures that are returned (for example, EC_fail.1 or EC_fail.2) and of the corresponding failure messages. EC_fail.0 indicates that no failures have occurred.
Because LOCALREXX does not run under TSO, you can use bpxwdyn to allocate a file, as shown in the following code sample. You must free the file with rc = bpxwdyn("free dd(ddname)") as soon as it is no longer required.
rc = bpxwdyn("alloc dd(ddName) da('data.set.name(member)') shr ")
say 'bpxwdyn RC='rc 'ddn='ddn
If errors occur during allocation, the error message is in REXX variable s99msg.1.
To read an allocated data set, use address MVS "EXECIO..." , as shown in the following code sample:
rc = bpxwdyn("free fi(temp1)")
Any say instructions go to SYSTSPRT.
You can query the SPM database as follows:
rc = ecexec("ExecSQL",'select * from config","results.")
The results of the query are in the results. stem variable. Only SELECT statements are permitted for security reasons.
If you expect to retrieve a lot of returned rows, check the results.returned and results.total variables:
- results.returned is the number of rows available in REXX stem variables.
- results.total is the number of rows returned from the query.
If more rows are available than returned, you can fetch additional data by running the query again by using the SQL OFFSET keyword to prevent overloading the REXX variable pool.
Sample LOCALREXX query
say '*******************************************************************'
rc=ecentry()
/* Display received variables */
say 'EC_Sysplex =' EC_Sysplex
say 'EC_Sysid =' EC_Sysid
say 'EC_Apptrace =' EC_Apptrace
say 'EC_Rexxtrace=' EC_Rexxtrace
say 'EC_Rule =' EC_Rule
say 'EC_Reference=' EC_Reference
say 'EC_Arg.0 =' EC_Arg.0
say ' '
/* Display arguments provided in the rule */
do i=1 to EC_Arg.0
say 'EC_Arg.'i' =' EC_Arg.i;say ' '
end
/* Use storage function */
numeric digits 16
say 'Sysid='stg(ptr(ptr(16)+196)+16,4) /* get sid from smca */
say 'Calling BPXWDYN to allocate a file'
rc = bpxwdyn("free dd(temp1) ")
rc = bpxwdyn("alloc dd(temp1) da('sys1.parmlib(ieasys00)') shr ")
say 'bpxwdyn allocate RC='rc; say ' '
rc = bpxwdyn("info fi(temp1) inrtdsn(dsnvar)")
say 'dsnvar='dsnvar
/* Call EXECIO and display first 2 lines */
address MVS "execio * diskr temp1 (stem data. FINIS"
say data.1
say data.2
rc = bpxwdyn("free fi(temp1)")
/* Retrieve data from SPM */
sql="select * from config where type='PASSWORD' and parm='INTERVAL' and value<>'30'";
address EC
rc = ecexec("ExecSQL",sql,"results.")
do i=1 to results.0
say 'results.'i '=' results.i;say ' '
end
/* Pass compliance results back to SPM */
EC_fail.0=results.0
EC_fail.1=results.1
say 'Failures='EC_Fail.0
/* Return to SPM */
rc = ecreturn()
exit
ptr: return c2d(storage(D2X(ARG(1)),4)) /* get address */
stg: return storage(d2x(arg(1)),arg(2)) /* get storage */