View previous topic :: View next topic |
Author |
Message |
gharisankar Beginner
Joined: 10 Jul 2004 Posts: 19 Topics: 3 Location: C/O Platform - Mainframe
|
Posted: Mon Dec 27, 2004 8:25 pm Post subject: To Get the File name in Eazytrieve Program |
|
|
I want to get my input file name in my Easytrieve program. For ex :
Code: |
//STEP0100 EXEC PGM=EZTPA00
//SYSPRINT DD SYSOUT=*
//PERSNL2 DD DSN=Input1,DISP=SHR
//PERSNL1 DD DSN=input2,DISP=SHR
//OUT1 DD SYSOUT=*
//SYSIN DD *
FILE PERSNL1 FB(131 27903)
DAY-1 48 03 A
YEAR-1 60 04 A
TIME-1 68 08 A
FILE PERSNL2 FB(131 27903)
DAY-2 48 03 A
YEAR-2 60 04 A
TIME-2 68 08 A
JOB INPUT (PERSNL1 KEY (day-1)+
(PERSNL2 KEY (day-2)))
IF MATCHED
"DISPLAY the Input filenames"
goto job
end-if
|
I hope, my question is clear.
I would like to display my Input datasets PERSNL1 , PERSNL2 .
How is it possible ? Kindly help me in this regard. _________________ Regards
Hari |
|
Back to top |
|
|
dtf Beginner
Joined: 10 Dec 2004 Posts: 110 Topics: 8 Location: Colorado USA
|
Posted: Mon Dec 27, 2004 10:02 pm Post subject: |
|
|
There are mechanisms for doing this in assembler language. I would think the best way would be for you to call an assembler routine from your Easytrieve. I have not been around this board enough to know if anyone has posted such a routine, but I suspect that they have, and that it could be found via search.
________
Taurus SHO
Last edited by dtf on Tue Feb 01, 2011 1:37 pm; edited 1 time in total |
|
Back to top |
|
|
Phantom Data Mgmt Moderator
Joined: 07 Jan 2003 Posts: 1056 Topics: 91 Location: The Blue Planet
|
Posted: Tue Dec 28, 2004 4:34 am Post subject: |
|
|
Hari,
As dtf said, you can get the DSNAME (given the DDNAME) either using Assembler / COBOL / REXX. But Eazytrieve does not have a facility to call REXX directly. And I don't know Assembler . The last to go is the Eazytrieve 'calling' COBOL solution. Here it is.
Eazytrieve --> COBOL
Part 1: Eazytrieve Code - Calling Program
Code: |
//R010 EXEC PGM=EZTPA00
//STEPLIB DD DSN=COBOL.LOAD.LIB,
// DISP=SHR
//SYSPRINT DD SYSOUT=*
//PERSNL2 DD DSN=Input1,DISP=SHR
//PERSNL1 DD DSN=input2,DISP=SHR
//OUT1 DD SYSOUT=*
//SYSIN DD *
PARM ENVIRONMENT COBOL
*
FILE PERSNL1 FB(131 27903)
DAY-1 48 03 A
YEAR-1 60 04 A
TIME-1 68 08 A
*
FILE PERSNL2 FB(131 27903)
DAY-2 48 03 A
YEAR-2 60 04 A
TIME-2 68 08 A
*
* WORK FIELDS
WS-FIRST-TIME W 01 A VALUE 'Y'
WS-PARMS W 104 A
WS-DDNAME-1 WS-PARMS 08 A VALUE 'PERSNL1'
WS-DDNAME-2 WS-PARMS +08 08 A VALUE 'PERSNL2'
WS-DSNAME-1 WS-PARMS +16 44 A
WS-DSNAME-2 WS-PARMS +60 44 A
*
JOB INPUT (PERSNL1 KEY (day-1)+
(PERSNL2 KEY (day-2)))
*
IF MATCHED
IF WS-FIRST-TIME = 'Y'
CALL GETDSN USING WS-PARMS
MOVE 'N' TO WS-FIRST-TIME
DISPLAY WS-DDNAME-1, WS-DSNAME-1
DISPLAY WS-DDNAME-2, WS-DSNAME-2
END-IF
END-IF
*
GOTO JOB
/*
|
Part 2: COBOL Code - Called Module
Code: |
IDENTIFICATION DIVISION.
PROGRAM-ID. GETDSN.
AUTHOR. PHANTOM.
DATE-WRITTEN. DEC, 2004
*
DATA DIVISION.
WORKING-STORAGE SECTION.
*
01 WS-WORK-FLAGS.
05 WS-IDX PIC S9(1).
05 WS-WORK PIC S9(9) COMP.
05 WS-RIGHT-HEX-DIGIT PIC S9(4) COMP.
05 WS-LENGTH-BINARY PIC S9(4) COMP.
05 WS-LENGTH-ALPHA REDEFINES
WS-LENGTH-BINARY.
10 WS-LENGTH-BIT-1 PIC X(01).
10 WS-LENGTH-BIT-2 PIC X(01).
05 WS-BINARY-DATA PIC S9(8) COMP.
05 WS-TEXT-DATA REDEFINES
WS-BINARY-DATA.
10 WS-TEXT-BIT-1 PIC X(01).
10 WS-TEXT-BITS-2-4 PIC X(03).
*
01 WS-TIOT-SEG-POINT.
05 WS-TIOT-SEG-POINTER USAGE IS POINTER.
05 WS-TIOT-SEG-PNT REDEFINES
WS-TIOT-SEG-POINTER PIC S9(9) COMP.
*
01 WS-JFCB-POINT.
05 WS-JFCB-POINTER USAGE IS POINTER.
05 WS-JFCB-PTR REDEFINES
WS-JFCB-POINTER PIC S9(9) COMP.
05 WS-JFCB-POINT-RED REDEFINES
WS-JFCB-PTR.
10 FILLER PIC X(01).
10 WS-JFCB-LOW-3 PIC X(03).
*
01 WS-POINT.
05 WS-POINTER USAGE IS POINTER.
05 WS-PTR REDEFINES
WS-POINTER PIC S9(9) COMP.
05 WS-POINT-RED REDEFINES
WS-PTR.
10 FILLER PIC X(01).
10 WS-LOW-3 PIC X(03).
*
01 WS-SWA-POINT.
05 WS-SWA-POINTER USAGE IS POINTER.
05 WS-SWA-PTR REDEFINES
WS-SWA-POINTER PIC S9(9) COMP.
05 WS-SWA-POINT-RED REDEFINES
WS-SWA-PTR.
10 FILLER PIC X(01).
10 WS-SWA-LOW-3 PIC X(03).
*
01 WS-QMAT-POINT.
05 WS-QMAT-POINTER USAGE IS POINTER.
05 WS-QMAT-PTR REDEFINES
WS-QMAT-POINTER PIC S9(9) COMP.
*
LINKAGE SECTION.
*---------------------------------------------------------------*
01 WS-EZTRIEVE-LINK-AREA.
05 WS-SEND-AREA.
10 WS-DDNAME-1 PIC X(08).
10 WS-DDNAME-2 PIC X(08).
05 WS-RETURN-AREA.
10 WS-DSNAME-1 PIC X(44).
10 WS-DSNAME-2 PIC X(44).
*---------------------------------------------------------------*
01 PSA.
05 FILLER PIC X(540).
05 TCB-PTR USAGE IS POINTER.
*---------------------------------------------------------------*
01 TCB.
05 FILLER PIC X(08).
05 DEB-ADDR USAGE IS POINTER.
05 TIOT-POINTER USAGE IS POINTER.
05 FILLER PIC X(164).
05 JSCB-POINTER USAGE IS POINTER.
*---------------------------------------------------------------*
01 TIOT-SEG.
05 TIO-LEN PIC X(01).
05 FILLER PIC X(03).
05 DD-NAME PIC X(08).
05 SWA-V-ADDR PIC X(03).
*---------------------------------------------------------------*
01 JFCB.
05 DS-NAME PIC X(44).
*---------------------------------------------------------------*
01 JSCB.
05 FILLER PIC X(244).
05 QMPL-POINTER USAGE IS POINTER.
*---------------------------------------------------------------*
01 QMPL.
05 FILLER PIC X(24).
05 QMAT-POINTER USAGE IS POINTER.
*---------------------------------------------------------------*
01 QMAT.
05 FILLER PIC X(12).
05 QMAT-NEXT-POINTER USAGE IS POINTER.
*---------------------------------------------------------------*
01 SWA.
05 JFCB-ADDR USAGE IS POINTER.
*---------------------------------------------------------------*
PROCEDURE DIVISION USING WS-EZTRIEVE-LINK-AREA.
*
PERFORM 1000-GET-DATASET-NAME-RTN THRU
1000-EXIT.
GOBACK.
*
*---------------------------------------------------------------
* FIND DDNAMES AND ASSOCIATED DSNAMES
* PSA + X'21C' -> TCB -> TIOT -> TIOT SEG -> SWAREQ(SVA) -> JFCB
*---------------------------------------------------------------
1000-GET-DATASET-NAME-RTN.
*
SET ADDRESS OF PSA TO NULL
SET ADDRESS OF TCB TO TCB-PTR.
SET WS-TIOT-SEG-POINTER TO TIOT-POINTER.
*
ADD 24 TO WS-TIOT-SEG-PNT.
SET ADDRESS OF TIOT-SEG TO WS-TIOT-SEG-POINTER.
PERFORM UNTIL TIO-LEN = LOW-VALUES
MOVE ALL LOW-VALUES TO WS-POINT
MOVE ALL LOW-VALUES TO WS-JFCB-POINT
MOVE ALL LOW-VALUES TO WS-SWA-POINT
MOVE SWA-V-ADDR TO WS-SWA-LOW-3
*
PERFORM 2000-SWAREQ-RTN THRU
2000-EXIT
*
SET ADDRESS OF JFCB TO WS-POINTER
EVALUATE TRUE
WHEN DD-NAME = WS-DDNAME-1
MOVE DS-NAME TO WS-DSNAME-1
WHEN DD-NAME = WS-DDNAME-2
MOVE DS-NAME TO WS-DSNAME-2
WHEN OTHER
CONTINUE
END-EVALUATE
*
MOVE ZEROES TO WS-LENGTH-BINARY
MOVE TIO-LEN TO WS-LENGTH-BIT-2
ADD WS-LENGTH-BINARY TO WS-TIOT-SEG-PNT
SET ADDRESS OF TIOT-SEG TO WS-TIOT-SEG-POINTER
END-PERFORM.
*
1000-EXIT.
EXIT.
*
2000-SWAREQ-RTN.
*
DIVIDE WS-SWA-PTR BY 16
GIVING WS-WORK
REMAINDER WS-RIGHT-HEX-DIGIT.
*
IF WS-RIGHT-HEX-DIGIT NOT = 15
COMPUTE WS-PTR = WS-SWA-PTR + 16
ELSE
SET ADDRESS OF JSCB TO JSCB-POINTER
SET ADDRESS OF QMPL TO QMPL-POINTER
SET ADDRESS OF QMAT TO QMAT-POINTER
SET WS-QMAT-POINTER TO QMAT-POINTER
*
PERFORM UNTIL WS-SWA-PTR <= 65536
SET WS-QMAT-POINTER TO QMAT-NEXT-POINTER
SET ADDRESS OF QMAT TO QMAT-NEXT-POINTER
COMPUTE WS-SWA-PTR = WS-SWA-PTR - 65536
END-PERFORM
*
COMPUTE WS-PTR = WS-SWA-PTR + WS-QMAT-PTR + 1
SET ADDRESS OF SWA TO WS-POINTER
SET WS-POINTER TO JFCB-ADDR
COMPUTE WS-PTR = WS-PTR + 16
END-IF.
*
2000-EXIT.
EXIT.
*
|
Here is a brief explanation of how the code works.
1. Eazytrieve program:
a. You have to code the 'ENVIRONMENT COBOL' option in the PARM so that Eazytrieve makes necessary arrangements to call a COBOL sub-program.
b. Use the CALL pgm-name USING identifier/literal to invoke a Sub-program and pass values to that. Similar to the CALL statement in COBOL. All you have to do is to pass the two DD names (PERSNL1 and PERSNL2) to COBOL. COBOL will return u the actually DSN Names for the DD names passed to it.
2. COBOL program:
It will be a bit difficult for you to understand the code. But here is the basic logic of what it does.
a. Whenever a JOB runs a TCB (Task Control Block) is created in memory (16 MB virtual).
b. The TCB contains all information about the job.
c. It also contains the address of TIOT (Task Input Ouput Table) which inturn points to something called JFCB (Job File Control Block) which contains the information of all the datasets used in the current step.
To get more information on the Data areas (TCB, TIOT, JFCB) go thru' the following IBM Manuals.
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IEA1D142/CCONTENTS?DT=20020129125552
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IEA1D242/CCONTENTS?DT=20020129125446
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IEA1D342/CCONTENTS?DT=20020129125558
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IEA1D442/CCONTENTS?DT=20020129130001
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IEA1D542/CCONTENTS?DT=20020129130344
Details regarding JFCB is available in the 3rd link and Information on TCB is available in the 4th link.
Hope this helps,
PS: Hari please do not refer my 'actual name' anywhere in this forum.
Thanks,
Phantom |
|
Back to top |
|
|
dtf Beginner
Joined: 10 Dec 2004 Posts: 110 Topics: 8 Location: Colorado USA
|
Posted: Tue Dec 28, 2004 9:29 am Post subject: |
|
|
Several years ago, I wrote an assembler program which followed control block chain and got to the JFCB to get the DSN. However at some point, this ceased to work when there was an upgrade to the operating system. The COBOL program above appears to bump through the control blocks in a similar manner, and so I am curious if it always works, and if it will continue to work.
To get my program to work, I had to modifiy it to issue a RDJFCB macro, and I am not positive of this, but I believe that this is the only reliable method of getting the JFCB.
Perhaps someone with more current knowledge of this can speak to the issue. I will try to dig up my program and post it if I can find it.
DTF
________
Ford Flex picture
Last edited by dtf on Tue Feb 01, 2011 1:37 pm; edited 1 time in total |
|
Back to top |
|
|
kolusu Site Admin
Joined: 26 Nov 2002 Posts: 12376 Topics: 75 Location: San Jose
|
|
Back to top |
|
|
Phantom Data Mgmt Moderator
Joined: 07 Jan 2003 Posts: 1056 Topics: 91 Location: The Blue Planet
|
Posted: Wed Dec 29, 2004 1:00 am Post subject: |
|
|
Kolusu,
Have any idea about the RDJFCB macro pointed out by 'dtf' ? Do I have to change my code to make it more generic ?
Thanks,
Phantom |
|
Back to top |
|
|
gharisankar Beginner
Joined: 10 Jul 2004 Posts: 19 Topics: 3 Location: C/O Platform - Mainframe
|
Posted: Wed Dec 29, 2004 12:52 pm Post subject: |
|
|
Thanks Phantom
I have learned some new things from here. Is it posible to achieve thru Easytrieve only.
If it is a COBOL , we can do it in another way. Just Pass the Input dsn thru the PARM and use the same dsn for INPUT.
Like :
// SET INDSN='INPUT.DSN1'
// SET INDSN1='INPUT.DSN2'
//RUN1 EXEC PGM=PRGO1,PARM='&INDSN.,&INDSN1.' _________________ Regards
Hari |
|
Back to top |
|
|
Phantom Data Mgmt Moderator
Joined: 07 Jan 2003 Posts: 1056 Topics: 91 Location: The Blue Planet
|
Posted: Thu Dec 30, 2004 4:51 am Post subject: |
|
|
Hari,
I don't think Eazytrieve has the capability to do this directly. (I'm not sure). As Kolusu said, you can probably use SAS. But that depends on your requirement.
And as you said, just to get the dataset name in COBOL you can use PARM. Gr8 idea.
Also keep in mind the limitation on the length of data passed via parm. Each dataset name can take a maximum of 44 chars. Since u can't pass more than 100 bytes via PARM, you can only pass two dataset names.
The code I gave u was part of the code that I wrote for my tool 'Sonic'. But that fetches the Dataset characteristics also, not only the dataset name. The moment I saw your question, I just pasted whatever I wrote. !!!
Thanks,
Phantom |
|
Back to top |
|
|
Ravi Beginner
Joined: 27 Jun 2005 Posts: 88 Topics: 2
|
Posted: Mon Jun 08, 2009 11:17 pm Post subject: |
|
|
Quote: |
As dtf said, you can get the DSNAME (given the DDNAME) either using Assembler / COBOL / REXX
|
How to do it thru REXX
Code: |
//STEP0001 EXEC PGM=IRXJCL,PARM='MYREXX'
//SYSPROC DD DISP=SHR,DSN=MY.REXX.PDS
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD DUMMY
//INFILE DD DISP=SHR,DSN=MY.GDG(0)
|
With this my INFILE is allocated. But from this can I get the actual GDG version fo the file? Like 'MY.GDG.G0042V00'
I know thru PL1 you can get it using FILEDDWORD
Any |
|
Back to top |
|
|
kolusu Site Admin
Joined: 26 Nov 2002 Posts: 12376 Topics: 75 Location: San Jose
|
|
Back to top |
|
|
Ravi Beginner
Joined: 27 Jun 2005 Posts: 88 Topics: 2
|
Posted: Tue Jun 09, 2009 12:15 am Post subject: |
|
|
Thanks Kolusu. I was trying with LISTDSI option earlier, but it will not accept my.gdg(0) as input. it was giving me an error. I have to give a full qualified name.
For my batch way of getting, I was able to get it..
Now with this INFILE option, I was able to pass the GDG name to the rexx program using IKJEFT01 program.
Code: |
JCL
~~~
//STEP10 EXEC PGM=IKJEFT01
//SYSEXEC DD DISP=SHR,DSN=MY.REXX.PDS
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSIN DD DUMMY
//SYSTSIN DD *
%MYREXX
//INFILE DD DISP=SHR,DSN=MY.GDG(0)
/*
REXX
~~~~
/*REXX*/
X - LISTDSI(INFILE FILE)
SAY SYSDSNAME
|
Note that IRXJCL didnot work for the same code and it might have stated in some messages of this forum "No TSO/E commands are allowed in IRXJCL". |
|
Back to top |
|
|
Ravi Beginner
Joined: 27 Jun 2005 Posts: 88 Topics: 2
|
Posted: Wed Jun 10, 2009 2:11 am Post subject: |
|
|
Now I am thinking how I can do it thru SAS.
I was unable to the file creation date, but got other attributes. Still digging.
Any appreciated.
Code: |
//THE FILE DD DSN=MY.GDG(0),DISP=SHR
//SYSIN DD *
%macro d3;
%let rc = %sysfunc(filename(theFile));
%let fid = %sysfunc(FOpen(&theFile));
%let OptNum = %sysfunc(FOptNum(&fid));
%do i = 1 %to &OptNum;
%let OptName = %sysfunc(FOptName(&fid, &i));
%let OptValue = %sysfunc(FInfo(&fid, &OptName));
%put Option # &i (&OptName) is &OptValue;
%end;
%let rc = %sysfunc(FClose(&fid));
%mend d3;
%d3;
RUN;
//*
Output
~~~~~
Option # 1 (Dsname) is MY.GDG.G0042V00
Option # 2 (Unit) is 3390
Option # 3 (Volume) is AB1234
Option # 4 (Disp) is SHR
Option # 5 (Blksize) is 8000
Option # 6 (Lrecl) is 80
Option # 7 (Recfm) is FB
|
Note This code is from Google Search SAS SYSFUNC MACRO D3 I was unable to open this pdf file, so tried the view in html optiob by google (http://www.lexjansen.com/pnwsug/2005/how/SysFunc.pdf) for reference |
|
Back to top |
|
|
kolusu Site Admin
Joined: 26 Nov 2002 Posts: 12376 Topics: 75 Location: San Jose
|
Posted: Wed Jun 10, 2009 2:27 am Post subject: |
|
|
Ravi,
I think you are jumping thru hoops to get the results. There is a smart DFSORT trick which list the creation date of all the GDG versions by reading the listcat info.
However if your interested only in sas then here is an untested code from my archives. The create date is in offset 81 for 3 bytes(YYDDD) in JFCB.
Code: |
DATA _NULL_;
LENGTH JFCBDATA $176; /*set the length of the jfcb var */
INFILE MVSFILE JFCB=JFCBDATA; /*get the jfcb data for the file */
OFFSET = 50X + 1; /*set the offset to 81 */
YY = SUBSTR(JFCBDATA,OFFSET,1); /*extract the year */
YEAR = INPUT(YY,IB1.); /*make a number */
DDDD = SUBSTR(JFCBDATA,OFFSET+1,2); /*extract the Julian date */
JDATE = INPUT(DDDD,IB2.); /*make a number */
CRTDATE = DATEJUL(YEAR*1000 + JDATE); /*make julian date a sasdate*/
PUT YEAR= JDATE= 4. CRTDATE= DATE.; /*show results */
STOP;
RUN;
|
kolusu |
|
Back to top |
|
|
Ravi Beginner
Joined: 27 Jun 2005 Posts: 88 Topics: 2
|
Posted: Wed Jun 10, 2009 4:02 am Post subject: |
|
|
Thanks Kolusu
This solved my requirement what I wanted. Wanted to have the YYDDD format thast it.
There is issue with DATEJUL conversion. The YEAR is returning 109 CYY JDATE 160 and the DATEJUL format is having CCYYDDD. where as what we are passing is 109160. It should have been 2009160 . |
|
Back to top |
|
|
|
|