Executing a DFSORT using REXX - mainframe

I would like to know,is it possible to invoke DFSORT through REXX?
I have used the below code,but the result is not as expected.
/*REXX*/
QUEUE "//ISDNNNN JOB XXX,XX"
QUEUE"//STEP003 EXEC PGM=SORT"
"FREE FI(SYSOUT SORTIN SORTOUT)"
"ALLOC FI(SYSOUT) DA(*)"
"ALLOC FI(SORTIN) DA('XXX.XXX.XXX') REUSE'
"ALLOC FI(SORTOUT) DA('XXX.XXX.XXX.OUT') REUSE'
QUEUE"//SYSIN DD*"
" SORT FIELDS = COPY"
" INCLUDE COND = (1,2,CH,EQ,C'AR')"
QUEUE"/*"
QUEUE"//SYSPRINT DD SYSOUT=*"
QUEUE"$$"
"SUBMIT * END($$)"

Yes it is possible.
Basically You can:
If running under ISPF, you can ISPF File Tailoring. Here is a sample File Tailoring skelton
You can call SORT directly
write a file and submit it, like you are trying to do. What is happening and what did you expect ???. I do not have a mainframe to test your code.
I would suggest learning the ISPF services i.e.
Rexx:
ADDRESS TSO "ALLOC DD(OUTSKEL) DS('"OUTSKPDS"') SHR"
'FTOPEN'
'FTINCL SAMPSKEL'
'FTCLOSE LIBRARY(OUTSKEL) NAME('WORKMEM')'
Sample ISPF Skelton:
//ASM EXEC PGM=IFOX00,REGION=128K
// PARM=(&ASMPARMS)
//SYSIN DD DSN=&ASMIN(&MEMBER),DISP=SHR
//SYSLIB DD DSN=SYS1.MACLIB,DISP=SHR
)SEL &ASMMAC1 ¬= &Z
// DD DSN=&ASMMAC1,DISP=SHR
)SEL &ASMMAC2 ¬= &Z
// DD DSN=&ASMMAC2,DISP=SHR
)ENDSEL
)ENDSEL
//SYSUT1 DD UNIT=SYSDA,SPACE=(CYL,(5,2))
//SYSUT2 DD UNIT=SYSDA,SPACE=(CYL,(2,1))
//SYSUT3 DD UNIT=SYSDA,SPACE=(CYL,(2,1))
//SYSPRINT DD SYSOUT=(&ASMPRT)
)CM IF USER SPECIFIED "GO," WRITE OUTPUT IN TEMP DATA SET
)CM THEN IMBED "LINK AND GO" SKELETON
)IF &GOSTEP = YES THEN )DO
//SYSGO DD DSN=&&&&OBJSET,UNIT=SYSDA,SPACE=(CYL,(2,1)),
// DISP=(MOD,PASS)
)IM LINKGO
)ENDDO
)CM ELSE (NOGO), WRITE OUTPUT TO USER DATA SET
)ELSE )DO
//SYSGO DD DSN=&ASMOUT(&MEMBER),DISP=OLD
)ENDDO

you can alloc the necessary files under address tso
for example "alloc f(sortin) da(....) shr "
the call sort under address ispling:
address ispling
" sort "
Be aware to put control cfards in the sysin file

Related

Remove audit trail from a RLIST command issued via ADDRESS TSO

I'm trying to write a script that would query specific resource profiles in a RACF class and later do a bit of logic to match a few things - not relevant.
The problem is that when I issue the command below I get the AUDIT TRAIL on the terminal. The script is meant to just return a 1 or a 0. All the logic works as it should but when I run the script I get the whole AUDIT TRAIL from RACF and at the bottom the result.
y = outtrap('resourceAccess.')
address tso 'RLIST CLASSX CLASSX.RESOURCE.LIST'
y = outtrap('off')
I already tried to create another outtrap after the one above with no success.
Is there a way to remove that AUDIT TRAIL bit?
It's possible that those lines of text are being issued in such a way that they cannot be trapped using outtrap and are instead being placed on the external data queue (EDQ) and then echoed to the terminal when the REXX exits. ACF2 does this with all output, making trapping command responses a bit tricky.
Try this:
/* Trap command response*/
y = outtrap('temp.')
address tso 'RLIST CLASSX CLASSX.RESOURCE.LIST'
y = outtrap('off')
/* Display anything put onto the EDQ */
do queued()
pull line
say line
end
Old answer:
If the output you are getting matches what's in the IBM docs you linked to (https://www.ibm.com/docs/en/szs/2.2?topic=effects-command-audit-trail), then what you need to do is after to have trapped the output, simply discard the first 2 lines, (which should be):
Command Audit Trail for USER IBMUSER
(one line of text and a blank line).
You could do this as follows:
y = outtrap('temp.')
address tso 'RLIST CLASSX CLASSX.RESOURCE.LIST'
y = outtrap('off')
/* Copy from the 3rd command response line into our 'real' response var */
do tempIndex = 3 to temp.0
desiredIndex = tempIndex - 2
resourceAccess.desiredIndex = temp.tempIndex
end
resourceAccess.0 = temp.0 - 2 /* Set number of lines */

Using Rexx to find members in a PDS matching a given string

I am looking for help with my REXX script. Which should open an existing Member and search for a specific string.
Here is my script:
/* REXX */
"ALLOC FILE(input) DA('.....(MEMBER)') SHR REUSE"
"EXECIO * DISKR "input" (STEM input. FINIS"
"FREE FILE(input)"
/* Parmlib werden ausgelesen */
do i =1 to input.0
if POS('met,', input.i) > 0 Then
/* Code if string is found */
say Zeile gefunden
else
/* Code if string is not found */
say Zeile nicht gefunden
end
As cschneid stated this looks like something you would just use SuperC for. ISPF Option 3.14 or 3.15 will search for a string and show results. Also you can issue SRCHFOR from a member list and have only the found members then filtered in the member list. Additionally ISPF LM services can be used to go thru members of a PDS and then run an Edit macro to do the find. EXEXIO could be used to write the results to an output file. Note that SuperC will already do this using 3.15
Under ISPF, edit macros seem like a good fit. You can set up an ISPF stack if you're not running one already, works in batch too.
If I'm reading your requirement correctly, maybe something like this might work:
/* REXX-ISPF V/E macro */
Address ISREDIT
"MACRO (needle,dest)"
"CURSOR = 1 0"
lastHit = 0
i = 0
"SEEK "needle
Do While RC=0
"(l#) = CURSOR"
/* Conditional for multiple hits on same line */
If l# > lastHit Then Do /* do */
"(this) = LINE "l#
i=i+1; out.i = this
lastHit = l#
End
"SEEK "needle
End
out.0=i
Address TSO
"ALLOCATE F(OUT) DA("dest"') OLD"
"EXECIO "out.0" DISKW OUT (FINIS STEM out."
Exit 0
You can do this with much fewer lines with more ISPF services in a Macro (X ALL -> F ALL needle -> DEL ALL X -> CREATE dest). Or through intermittent use of ISPF E clipboard. That has some risks, so not going into that.
Good thing about ISPF E/V Macros is that thy use almost the same command you'd normally use in ISPF E/V. Find is quick. It needs to fit the whole dataset in the Region which might be an issue sometimes.
You could also call ISRSUPC from Rexx. There was a nifty Rexx exec published in MVS Update long ago. It searches for a string across all members of a PDS and presents the "hit list" on an ISPF panel, so you can edit or view the members.
I still use it (a descendant of it anyway) on my systems. I found the MVS Update article, here it is :
https://manualzz.com/doc/10913425/mvs0207

Storing query result in a variable with bash script

I have a query say :
"select .... " > $my_result
This will store in the my_result but as a file. How to store in a my_result variable itself if that query gives only one row without creating a file.
Simplest way would be:
my_result=$(select ...)
And when you want to print it:
echo $my_result

Declare cursor is not executing

I have converted one RPGLE program to SQLRPGLE, i did that many times. strange issues i am facing this time.
(1) SQLCODE setting up to 077952576 as soon as program executing, not sure why.
(2) when i am running in debug Declare cursor statement is not getting executed, nut other following sql statement getting hit.
Exec Sql
DECLARE My_cursor CURSOR for
select * FROM File1 where FLAG <> 'Y'
Order by Field1, Field2, Field3, Field4, Field5;
Please advise, Thanks
DECLARE CURSOR is not an executable statement. It's a compile time statement.
You shouldn't be checking SQLCODE/SQLSTATE after it...
Take a look at this program...
**FREE
ctl-opt main(mymain);
ctl-opt option(*srcstmt);
ctl-opt datfmt(*ISO) timfmt(*ISO);
ctl-opt cvtopt(*NODATETIME);
dcl-proc MyMain;
dcl-s company char(3);
dcl-s part char(25);
dcl-s desc char(30);
dcl-s msg char(50);
dcl-s selComp char(3);
dcl-s myTimestamp timestamp;
exec sql
set option
datfmt=*ISO, timfmt=*ISO;
selComp = 'A06';
exsr OpenCursor;
exsr FetchData;
exec SQL close C1;
selComp = 'A15';
exsr OpenCursor;
exsr FetchData;
exec SQL close C1;
*INLR = *ON;
return;
begsr DeclareCursor;
exec SQL
declare C1 cursor for
select pmco#, pmpart, pmdesc
from pdpmast
where pmco# = :selComp;
endsr;
begsr OpenCursor;
exec SQL open C1;
endsr;
begsr FetchData;
exec sql fetch next from C1 into :company, :part, :desc;
msg = company + ':' + part + ':' + desc;
dsply msg;
endsr;
end-proc;
Note that this is a working (example) program. But the DeclareCursor subroutine is never actually called! It doesn't need to be, even though a host variable is used in the WHERE clause.
The value of the host variable is use when the OPEN is executed.
Also note that in embedded SQL as shown above, SET OPTION is a compile time statement. In fact, there can only be a single SET OPTION statement in the entire source member and it must be the first SQL statement that the pre-compiler sees.

Recording non-convergence in SAS NLIN

I have a question about SAS-proc nlin.
I'm performing the procedure for 10000 simulations. Lots of them do not converge and give me wrong results.
I would like to add a binary variable to my output table that says that this itteration did not converge.
Does anyone know how to do that ?
Many thanks,
Perry
You need to use ODS to pull the ConvergenceStatus output from PROC NLIN. Add it to your procedure code like this:
PROC NLIN data = ...;
...;
ods output ConvergenceStatus = conv;
RUN;
That gives you a data set with two variables:
Status (0 means convergence, otherwise 1, 2, or 3 are described here: https://support.sas.com/documentation/cdl/en/statug/63033/HTML/default/viewer.htm#statug_nlin_sect031.htm).
Reason (description of the convergence issue).
So attach the results of that data set to each simulation round, and create a binary indicator for whether status > 0, and you should be all set.

Resources