340 likes | 351 Views
Tutorial – Advanced Use. 07 January 2020. Nick Jones Jim Evans. Compute (Bridgend) Ltd 8 Merthyr Mawr Road BRIDGEND CF31 3NH +44 (0)1656 652222 http://www.cbl.com. Advanced SELCOPY. Dynamic Allocation @pointers VSAM Processing DB2 Processing IMS/DL1 Processing The SLC program.
E N D
Tutorial – Advanced Use 07 January 2020 Nick Jones Jim Evans Compute(Bridgend) Ltd 8 Merthyr Mawr Road BRIDGEND CF31 3NH +44 (0)1656 652222 http://www.cbl.com
Advanced SELCOPY • Dynamic Allocation • @pointers • VSAM Processing • DB2 Processing • IMS/DL1 Processing • The SLC program Compute(Bridgend) Ltd
Dynamic Allocation • Allocates a DSN to the specified fname . • DEFAULTF used if fname is not specified. • Any PS, PO, VSAM, GDG DSN or library DSN + member. • DISP=SHR default for input/output dataset allocation. • DISP=MOD for output dataset with APPEND parameter. • DSN="dsname" allocate and open at statement analysis. • DSN=field is supported (e.g. DSN=44 at 1) • Variable dataset name which may change during SELCOPY processing. • Defers allocation and open until I/O operation executed at selection time. • Once allocated, changes to field value ignored until CLOSE/OPEN executed. Compute(Bridgend) Ltd
Dynamic Allocation Sample 1 EQU INDSN 1 * Input DSN(+member) area. EQU INDSN_L 54 * Input DSN(+member) max length. EQU INREC INDSN+INDSN_L * Input data record area. EQU INREC_L 1024 * Input data record max length. OPTION WORKLEN=INREC+INREC_L DATAWIDTH=80 NORDW READ CARD INTO INDSN * Input DSN read from SYSIN. @DSNL = LRECL * Length of DSN. PRINT FROM INDSN * Print the input dataset name. ==LOOP== READ DDIN DSN=@DSNL AT INDSN INTO INREC * Dynamic alloc. IF EOF DDIN * If end-of-file. OR INCOUNT DDIN >= 10 * or record count exceeds 10. THEN CLOSE DDIN * Close the current data set. * Dynamic Alloc and Open will occur next time READ is executed. THEN GOTO LOOP_END * Exit the loop. POS INREC+LRECL, INREC+INREC_L-1 = " " * Clear residue. PRINT FROM INREC LENGTH=80 * Print first 80 bytes. GOTO LOOP * Get the next data record. ==LOOP_END== SPACE 2 * Skip to SYSPRINT lines. END ** Input dataset names follow ** NBJ.DATASET.BASIC01.KSDS NBJ.FSU.TEST.GDG(0) APE.TXT(ZOPCODES) Print first 10 records of datasets whose DSNs are supplied as input. Compute(Bridgend) Ltd
@Pointers • Numeric value variables. • May used in position and length specification. • POSUXATPTR contains the 4-byte, binary storage address pointed to by the default pointer “@”. IF POS 1, 1000 <> ‘ ’ * Default pointer (@) --> first non-blank. AND POS @+1, 1000 = ‘ ‘ ptr=@end * Pointer @end --> next blank. THEN @end = @end-1 * @end --> non-blank character before. THEN PRINT FROM POS @, @end * Print variable length word data. THEN @len = @end-@+1 * @len = length of word data. THEN MOVE @len AT @ TO 1001 * Copy word text to position 1001. Compute(Bridgend) Ltd
@Pointer Sample 1 EQU IN1 'CBL.SSC.CTL' * 1st Input PDS. EQU IN2 'CBL.SSC.CTL.F80' * 2nd Input PDS. EQU MARR 1 * Array of member names built from pds1 EQU MARRE 10 * Array element length (member name = 8 bytes). EQU MARRL 20800 * Max length of array (1080 array elements) EQU PDSIN MARR+MARRL * PDS input. EQU PDSINL 256 * PDS input maximum lrecl. OPTION WORKLEN=PDSIN+PDSINL DO ARRAY_RTN STOPAFT=1 READ PDS2 DSN=IN2 DIR INTO PDSIN * Dir records only. IF POS MARR, @ARR+MARRE-1 = 8 AT PDSIN STEP=MARRE THEN DUMMY * Member name found in array. ELSE PRINT FROM PDSIN LENGTH 8 * Log mismatching member name. GOTO GET * Get next record. ==ARRAY_RTN== @ARR = MARR =ARRAY_LOOP== * Loop to build array of member names. READ PDS1 DSN=IN1 DIR INTO @ARR * Directory records only. POS @ARR+8, @ARR+LRECL-1 = ' ' * Blank rest of record following member. IF EOF PDS1 THEN GOTO ARRAY_LOOP_END @ARR = @ARR+MARRE * Next input position. GOTO ARRAY_LOOP =ARRAY_LOOP_END= =RETURN= Use @pointers to build and scan an array of field values. Compute(Bridgend) Ltd
@Pointer Sample 2 //SQ11793 JOB ,'TEST DATA',CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1), // NOTIFY=&SYSUID //* Obtain Programmer's name from JOBCARD. (i.e. "TEST DATA".) //* //STEP1 EXEC PGM=SELCOPY //SYSPRINT DD DISP=SHR,DSN=NBJ.SYSPRINT(SSPTR01) //SYSIN DD * OPT WORKLEN=100 DO GETJOBPGMNAME PRINT FROM @ LENGTH 20 GOTO GET ==GETJOBPGMNAME== ** Sub-routine ** * On return @ --> Programmer Name from JOB card. POS UXATPTR = X'0000,0010' * @ --> A(CVT) POS UXATPTR = 4 AT @ * @ --> CVT (Communications Vector Table) POS UXATPTR = 4 AT @ * @ --> TCB pointers POS UXATPTR = 4 AT @+4 * @ --> Current TCB (Task Control Block) IF POS @+256 <> 'TCB' * Verify @ --> TCB THEN PRINT FROM @ LENGTH 512 TYPE=D THEN CANCEL POS UXATPTR = 4 AT @+180 * @ --> JSCB (Job Step) POS UXATPTR = 4 AT @+260 * @ --> JCT-x'10‘ (Job Control Table) POS UXATPTR = X'00' * High order byte must be zero. POS UXATPTR = 4 AT @+55 * @ --> 1st ACT (Account Control Table) POS UXATPTR = X'00' * High order byte must be zero. @ = @+24 * @ --> JOB Card Programmer Name. =return= /* Use UXATPTR field to navigate MVS control blocks. Compute(Bridgend) Ltd
VSAM (1/2) • KSDS, ESDS, RRDS (VRRDS) parameters on READ. • Sequential • Direct by key, record number or relative byte. (KEY=,KGE=,REC=,RBA=) • Variable value supported by KEY=,KGE=,REC=,RBA= as field. • Direct then sequential. (STARTKEY=,STARTKGE=,STARTREC=,STARTRBA=) • Input Record Sequence • First to last - FWD (default) • Last to first - BWD • Combine with direct then sequential input. • KSDS multiple changes in direction. (e.g. FWDBWDFWD) • READ PATH for KSDS input via alternate index key. • Supports KEY=,KGE=,STARTKEY=,STARTKGE= READ INKSDS KSDS STARTKEY=‘DDDX’ READ INKSDS KSDS STARTKGE=‘DDDX’ BWD Compute(Bridgend) Ltd
VSAM (2/2) • READUPDATE to input then update, delete, insert records. • UPDATE and DELETE operations affect last input record read. • INSERT operation for KSDS will insert by key. • Input position lost following KSDS insert – would require a direct read. • INSERT for KSDS record inserts in any sequence. • Prior READ is not required. • WRITE to load KSDS records in key sequence. • More efficient than INSERT. • SELCOPY positions - VSAM areas (last VSAM call). • POS RPL (VSAM Request Parameter List) • POS RETVSAM+1 (VSAM Return, Component and Error Codes) Compute(Bridgend) Ltd
VSAM Sample 1 1SELCOPY REL 3.30 AT CBL - Bridgend UK (Internal Only) 2016/06/30 18:28 PAGE 1 ----------------------------------------------------- ---------------- -------- OPTION DATAWIDTH=50 1. READ INRRDS DSN="NBJ.SSDEMO.RRDS" RRDS STARTREC=381 * Read the RRDS from record 381. 2. PRINT LENGTH 50 * Print the input record. INPUT SEL SEL RECORD RECNO TOT ID. 1 2 3 4 5 LENGTH ----- --- --- ....,....0....,....0....,....0....,....0....,....0 ------ 1 1 2 381 WINWSYSI 020 20060803 1056 000BCB08 100 2 2 2 382 WINWVOLS 016 20041125 1229 000BD208 100 3 3 2 383 WINWWINL 012 20050412 0959 000BE008 100 4 4 2 384 WINYLGON 007 20040407 1320 000BE708 100 5 5 2 385 WINYOPEN 031 20041103 1049 000BEB08 100 6 6 2 386 WINYSAVE 002 20040407 1321 000BF808 100 7 7 2 387 PWRLMAIN 015 20050629 1044 000BF908 100 8 8 2 388 PWRFOBJ0 100 20041215 1622 000BFC08 100 9 9 2 389 PWRWLIST 045 20051213 1403 000C1A08 100 ....,....1....,....2....,....3....,....4....,....5 SUMMARY.. SEL-ID SELTOT FILE BLKSIZE LRECL FSIZE CI DSN ------ ------ ---- ------- ----- ----- -- --- 1 9 READ INRRDS 100 100 U 389 4096 NBJ.SSDEMO.RRDS 2 9 ** SELCOPY IS LICENSED BY COMPUTE (BRIDGEND) LTD +44 (1656) 652222 & 656466 ** ** EXPIRY DATE -- 2017/07/13 ** Read and print RRDS records starting at record 381. Compute(Bridgend) Ltd
VSAM Sample 2 EQU INKEY 1 * Input KSDS key position. EQU INKEY_L 7 * Input KSDS key length. EQU INREC INKEY+INKEY_L * Input data record area. EQU INREC_L 4096 * Input data record max length. OPTION WORKLEN=INREC+INREC_L DATAWIDTH=80 READ CARD INTO INKEY * Get the key value. READ INKSDS DSN="NBJ.DATASET.BASIC01.KSDS" \ KEY=INKEY_L AT INKEY KSDS UPD \ INTO INREC * Keyed input with update. IF POS INREC = "--- KEY/REC NOT FOUND ---" * No matching record. THEN SPACE * Skip a line. THEN PRINT FROM INKEY LENGTH=INKEY_L * Print the key. THEN PRINT FROM INREC * Print "not found". THEN SPACE * Skip a line IF POS ANY = 'CBLxxx' * Scan for "CBLxxx". THEN PRINT FROM POS INREC LENGTH=80 * Print 1st 80 characters. THEN POS @ = 'CBLM05' * Update with "CBLM05". THEN UPDATE INKSDS FROM INREC * Update the input record. END 0000030 0000010 000000A 0000022 0000045 0000031 Read KSDS directly using variable key value and update-in-place. Compute(Bridgend) Ltd
VSAM Sample 3 EQU KSREC 1 * KSDS Input/Output record. EQU KEYO 0 !EQU KEYL 7 * KSDS key offset+length (char). EQU DATO 8 * KSDS data (excl. key) EQU KSREC_L 322 * KSDS Input/Output record max len. EQU PDKEY KSREC+KSREC_L * Next VSAM key (as packed numeric) EQU PDKEY_L 4 * Next VSAM key packed length 4. OPTION WORKLEN=PDKEY+PDKEY_L * Work area. DO LASTKEY_RTN STOPAFT=1 READ CARD INTO KSREC+DATO * Input card to KSDS. ADD 5 TO PDKEY_L AT PDKEY TYPE=P * Increment key value by 5. CVPC PDKEY_L AT PDKEY TO KEYL AT KSREC+KEYO * Unpack the key value. LRECL = LRECL+KEYL * Output rec length (key+data). WRITE OUTKSDS DSN="NBJ.DATASET.BASIC01.KSDS" \ FROM KSREC DEFER * Load KSDS the record. GOTO GET ==LASTKEY_RTN== ** Get the highest key value. READ INKSDS DSN="NBJ.DATASET.BASIC01.KSDS" \ INTO KSREC KSDS BWD * Read backwards. * Convert the character numeric key to packed decimal. CVCP KEYL AT KSREC+KEYO TO PDKEY_L AT PDKEY CLOSE INKSDS * Close input. =RETURN= END NBJ.SSDEMO.OUT PS VB 100 59 CBLM14 2016/06/20 2016/06/20 NBJ.SSDEMO.RRDS 0 0 NBJ.SSDEMO.RRDS.DATA VS U 0 59 CBLM05 2016/06/30 2016/06/30 NBJ.SSDEMO03.OUT PS VB 100 882 CBLM06 2016/06/21 2016/06/21 NBJ.SSDEMO07.KSDS 0 0 NBJ.SSDEMO07.KSDS.DATA VS U 0 59 CBLM09 2016/06/21 2016/06/21 Read KSDS backwards for highest key value, then load new records. Compute(Bridgend) Ltd
DB2 (1/2) • SELCOPY DB2 PLAN BIND to DB2 sub-systems. • Dynamic SQL prepared during SELCOPY execution. • READ (SQL SELECT query with FETCH) • WRITE/INSERT (Prepared INSERT) • UPDATE (Current input row) • DELETE (Current input row) • DB2 SQL= (General SQL statement execution) • DB2 load module libraries in search path. (CAF modules) • Operations subject to usual DB2 authorisation. • SQLID associated with the SELCOPY execution (usually ACF user id). • SELCOPY positions - DB2 areas (last SQL statement). • POS RPL (SELCOPQL Request Parameter List) • POS SQLCA (SQL Communications Area) • POS SQLDA (SQL Descriptor Area with SQLVA chain) • POS SQLMA (SQL Message Area) Compute(Bridgend) Ltd
DB2 (2/2) • SELCOPY SELCOPQL Request Parameter List, POS RPL. Compute(Bridgend) Ltd
DB2 Sample 1 1SELCOPY REL 3.30 AT CBL - Bridgend UK (Internal Only) 2016/06/28 15:42 PAGE 1 ----------------------------------------------------- ---------------- -------- OPTION DATAWIDTH=50 PAGEWIDTH=80 OPTION SSN=CBLA * Override default DB2 sub-system. READ INDB2 SQL=" \ SELECT TRACK_NUM,NAME FROM NBJ.SELCTRN_TRACK \ WHERE ALBUM_ID=10 \ ORDER BY TRACK_NUM \ 1. " CHAR SEP * As Character with separators. 2. PRINT LENGTH=50 STOPAFT=5 INPUT SEL SEL RECORD RECNO TOT ID. 1 2 3 4 5 LENGTH ----- --- --- ....,....0....,....0....,....0....,....0....,....0 ------ 1 1 2 1|Rolling In the Deep 572 2 2 2 2|Rumour Has It 572 3 3 2 3|Turning Tables 572 4 4 2 4|Don't You Remember 572 5 5 2 5|Set Fire to the Rain 572 ....,....1....,....2....,....3....,....4....,....5 SUMMARY.. SEL-ID SELTOT FILE BLKSIZE LRECL FSIZE CI DSN ------ ------ ---- ------- ----- ----- -- --- 1 5 READ INDB2 572 U 5 *EOF*NOT*REACHED* 2 5 ***WARNING*** 4 = RETURN CODE FROM SELCOPY ** SELCOPY IS LICENSED BY COMPUTE (BRIDGEND) LTD +44 (1656) 652222 & 656466 ** ** EXPIRY DATE -- 2017/07/13 ** Read as printable character. Compute(Bridgend) Ltd
DB2 Sample 2 1SELCOPY REL 3.30 AT CBL - Bridgend UK (Internal Only) 2016/06/29 10:49 PAGE 1 ----------------------------------------------------- ---------------- -------- OPTION DATAWIDTH=50 PAGEWIDTH=90 OPTION SSN=CBLA * Override default DB2 sub-system. READ INDB2 SQL=" \ SELECT NAME FROM NBJ.SELCTRN_TRACK \ WHERE ALBUM_ID=10 \ FOR UPDATE OF NAME \ 1. " VLEN * Read rows from this result table. IF EOF INDB2 * If no more rows. 2. THEN DB2 "COMMIT" * Commit changes. IF POS ANY = "Deep" PTR=@HIT * Scan for "Deep" in track name. 3. THEN PRINT LENGTH=50 * Print before update. 4. THEN POS @HIT = "Sand" * Replace "Deep" with "Sand" 5. THEN PRINT LENGTH=50 * Print after update. 6. THEN UPD INDB2 * Update the DB2 table row. INPUT SEL SEL RECORD RECNO TOT ID. 1 2 3 4 5 LENGTH ----- --- --- ....,....0....,....0....,....0....,....0....,....0 ------ 1 1 3 Rolling In the Deep 21 1 1 5 Rolling In the Sand 21 ....,....1....,....2....,....3....,....4....,....5 SUMMARY.. SEL-ID SELTOT FILE BLKSIZE LRECL FSIZE CI DSN ------ ------ ---- ------- ----- ----- -- --- 1 13 READ INDB2 39 U 13 2 1 DB2 3----5 1 6 1 UPD INDB2 39 U 13 Read, update then commit changes. Compute(Bridgend) Ltd
DB2 Sample 2 – Log Output 1 *** CBL Dynamic SQL Interface Version 3.30 AT *** ----------------------------------------- CBLS010I 10:49:05 CBL Dynamic SQL Interface is started. Date: 2016-06-29 CBLS000I 10:49:05 (Sel 1) Connected to DB2 Version 9.1.0 Subsystem:CBLA Plan:ZZI34000 User:NBJ Current SQLID:NBJ CBLS004I 10:49:05 (Sel 1) OPEN SELECT cursor INDB2 SELECT NAME FROM NBJ.SELCTRN_TRACK WHERE ALBUM_ID=10 FOR UPDATE OF NAME CBLS013I 10:49:05 (Sel 6) UPDATE statement generated: UPDATE NBJ.SELCTRN_TRACK SET NAME=? WHERE CURRENT OF C1 CBLS005I 10:49:05 (Sel 1) End Of File on SELECT cursor INDB2 CBLS006I 10:49:05 (Sel 1) CLOSE SELECT cursor INDB2 Prepare and OPEN DB2 CPU= 000000.001044 seconds. Rows Fetched=13 DB2 CPU= 000000.008299 seconds. Rows Updated=1 DB2 CPU= 000000.000893 seconds. Update Prepares=1 DB2 CPU= 000000.009470 seconds. Total DB2 CPU= 000000.019706 seconds. CBLS007I 10:49:05 (Sel 2) EXECUTE COMMIT SQL Code=0 DB2 CPU= 000000.001570 seconds. CBLS001I 10:49:05 (Sel 1) Disconnected from DB2 Subsystem CBLA Total connection DB2 CPU= 000000.022399 seconds. CBLS009I 10:49:05 CBL Dynamic SQL Interface is stopped GETMAINs issued=11 Storage=13824 HWM=13792 FREEMAINs issued=11 Storage=13824 Total Interface CPU= 000000.055653 seconds. --- End --- Compute(Bridgend) Ltd
DB2 Sample 3 1SELCOPY REL 3.30 AT CBL - Bridgend UK (Internal Only) 2016/06/29 11:14 PAGE 1 ----------------------------------------------------- ---------------- -------- OPTION DATAWIDTH=50 PAGEWIDTH=133 OPTION SSN=CBLA * Override default DB2 sub-system. 1. READ INTAB TAB="NBJ.SELCTRN_TRACK" PFX 2. WRITE OUTTAB TAB="NBJ.SELCTRN_TRACK_COPY" PFX 3. PRINT TYPE=D STOPAFT=1 INPUT SEL SEL RECNO TOT ID. ----- --- --- 1 1 3 352 0000 000A0001 0013D996 93938995 8740C995 40A38885 40C48585 97404040 40404040 *......Rolling In the Deep * 0020 40404040 40404040 40404040 40404040 40404040 40404040 40404040 40404040 * * 0040 40404040 40404040 40404040 40404040 40404040 40404040 40404040 40404040 * * 0060 40404040 40404040 40404040 40404040 40404040 40404040 40404040 40400823 * ..* 0080 C3C2F1F2 C4C4F7F1 F4C4F5F1 F8F2F8C3 00000003 7AFD0000 00000000 007AD876 *CB12DD714D51828C....:........:Q.* 00A0 00000000 01000000 44100C00 0007DB00 0005151C 00000001 00000005 C1848593 *............................Adel* 00C0 85404040 40404040 40404040 40404040 40404040 40404040 40404040 40404040 *e * 00E0 40404040 40404040 40404040 40404040 40404040 40404040 40404040 40404040 * * 0100 40404040 40404040 40404040 0000F2F0 F1F160F0 F160F2F1 60F0F84B F0F04BF0 * ..2011-01-21-08.00.0* 0120 F04BF0F0 F0F0F0F0 0000F2F0 F1F260F0 F860F0F2 60F1F14B F3F04BF3 F64BF0F0 *0.000000..2012-08-02-11.30.36.00* 0140 F0F0F0F0 0000F2F0 F1F160F0 F860F1F9 60F1F24B F2F94BF1 F74BF0F0 F0F0F0F0 *0000..2011-08-19-12.29.17.000000* SUMMARY.. SEL-ID SELTOT FILE BLKSIZE LRECL FSIZE CI DSN ------ ------ ---- ------- ----- ----- -- --- 1 1,070 READ INTAB 352 U 1,070 2 1,070 INS OUTTAB 0 U 0 3 1 ** ** ** ** ** ** ** SELCOPY IS LICENSED BY COMPUTE (BRIDGEND) LTD +44 (1656) 652222 & 656466 ** ** ** ** ** ** * ** EXPIRY DATE -- 2017/07/13 ** Copy table rows to an identical, test version of the table. Compute(Bridgend) Ltd
DB2 Sample 3 – Log Output 1 *** CBL Dynamic SQL Interface Version 3.30 AT *** ----------------------------------------- CBLS010I 11:14:10 CBL Dynamic SQL Interface is started. Date: 2016-06-29 CBLS000I 11:14:10 (Sel 1) Connected to DB2 Version 9.1.0 Subsystem:CBLA Plan:ZZI34000 User:NBJ Current SQLID:NBJ CBLS004I 11:14:10 (Sel 1) OPEN SELECT cursor INTAB SELECT * FROM NBJ.SELCTRN_TRACK CBLS004I 11:14:10 (Sel 2) OPEN INSERT cursor OUTTAB INSERT INTO NBJ.SELCTRN_TRACK_COPY (ALBUM_ID,TRACK_NUM,NAME,TRACK_ID, PERSISTENT_ID,TOTAL_TIME,FILE_SIZE,BIT_RATE,SAMPLE_RATE,YEAR, NORMALIZATION,DISC_NUMBER,ALBUM_ARTIST,RELEASE_DATE,DATE_ADDED, DATE_MODIFIED) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) CBLS005I 11:14:11 (Sel 1) End Of File on SELECT cursor INTAB CBLS006I 11:14:11 (Sel 1) CLOSE SELECT cursor INTAB Prepare and OPEN DB2 CPU= 000000.001476 seconds. Rows Fetched=1070 DB2 CPU= 000000.213096 seconds. Total DB2 CPU= 000000.214572 seconds. CBLS006I 11:14:11 (Sel 2) CLOSE INSERT cursor OUTTAB Rows Inserted=1070 DB2 CPU= 000000.691061 seconds. Insert Prepares=1 DB2 CPU= 000000.010436 seconds. Total DB2 CPU= 000000.701497 seconds. CBLS001I 11:14:11 (Sel 1) Disconnected from DB2 Subsystem CBLA Total connection DB2 CPU= 000000.917084 seconds. CBLS009I 11:14:11 CBL Dynamic SQL Interface is stopped GETMAINs issued=14 Storage=16696 HWM=16280 FREEMAINs issued=14 Storage=16696 Total Interface CPU= 000000.991470 seconds. --- End --- Compute(Bridgend) Ltd
IMS/DL1 (1/2) • SELCOPY called by region controller (DFSRRC00). • PSB with PCB required to process database segments. • PROCOPT • SENSEG • SELCOPY I/O operations (GN, GHN, GHU, ISRT, REPL, etc.) • PCB identified by #n (i.e. nth non-I/O PCB in the PSB) • PCB identified by dbdname #n (i.e. nth PCB to reference dbdname ) • I/O operations support SSA via the SSA= parameter. STOKSTAT(STOCKEY GT0025500000000000) CYCCOUNT(CYCLKEY GT62*CYCLKEY LT93) BACKORDR*C(02250236-001 0025900326 30PR265943) • SSA= references RSA for GSAM on GN, GU, ISRT. Compute(Bridgend) Ltd
IMS/DL1 (2/2) • SELCOPY references last PCB processed as POSPCB. Compute(Bridgend) Ltd
IMS/DL1 Sample 1 //NBJJOB JOB ,,CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1),NOTIFY=&SYSUID // JCLLIB ORDER=IMS1210.PROCLIB //STEP001 EXEC DLIBATCH,PSB=DFHSAM04,DBRC=N,IRLM=N,MBR=SELCOPY //G.IEFRDER DD DUMMY,UNIT=SYSDA //G.DFSVSAMP DD DISP=SHR,DSN=NBJ.SELCOPY.IMS.DFSVSAMP(DEFAULT) //SYSPRINT DD DISP=SHR,DSN=NBJ.SYSPRINT(SSIMS05) //SYSIN DD * OPTION PAGEDEPTH=99999 PAGEWIDTH=90 DATAWIDTH=80 OPTION WORKLEN=2100 * ....,....1....,....2....,....3....,....4....,....5....,. POS 2001 = \ " SSIMS05: Error.. Get segment failed with status code: " STOPAFT=1 GN DI21PART #1 IMS SEG='PARTROOT' * 1st PCB to ref DI21PART. * PARTROOT segments only. IF POS STATUS <> ' ' THEN POS 2056 = POS STATUS LENGTH=2 THEN PLOG ' *#*' TYPE=S THEN PLOG FROM 2001, 2060 TYPE=S THEN PLOG ' *#*' TYPE=S THEN RC = 1024 THEN EOJ PRINT /* Input named segments sequentially. Compute(Bridgend) Ltd
IMS/DL1 Sample 2 ...JCL as for IMS/DL1 Sample 1 //OUTSSA DD DISP=SHR,DSN=NBJ.SELCOPY.IMS.KEYS(DI21PART) //SYSIN DD * EQU INSEG 1 * Input segment. EQU INSEG_L 5000 * Maximum expected segment size. EQU SSAKY INSEG+INSEG_L * SSA string for GU on restart. EQU SEGN 0 !EQU SEGN_L 8 * Segment Name Off/Len. EQU CMDC SEGN+SEGN_L !EQU CMDC_L 2 * Command Code Off/Len. '*C' EQU QUAL CMDC+CMDC_L !EQU QUAL_L 1 * Qualifier Off/Len. '(' EQU CKEY QUAL+QUAL_L !EQU CKEY_L 2048 * Concat Key Off/Len. '..)' EQU SSAKY_L 11+2048 * SSA string max length. * (keylen max=2048) OPTION WORKLEN=SSAKY+SSAKY_L GN DI21PART #1 IMS INTO INSEG IF POS STATUS = ' ' !OR POS STATUS = 'G' * If acceptable status. THEN DO BUILD_SSA * Build an SSA. ELSE CANCEL * Unexpected status. GOTO GET * Get the next segment. ==BUILD_SSA== ** Build a concatenated key SSA. ** MOVE SEGN_L AT POS PCB+20 TO SSAKY+SEGN * Segment name. (POS SEG) POS SSAKY+CMDC = '*C(' * Cat Key cmd code. @KEYL = 4 AT POS PCB+28 TYPE=B * Length of key. MOVE @KEYL AT POS PCB+36 TO SSAKY+CKEY, SSAKY+CKEY+CKEY_L-1 @SSAL = @KEYL+CKEY+1 * Fixed portion + key length + bracket. POS SSAKY+@SSAL-1 = ')' * Closing bracket. WRITE OUTSSA FROM SSAKY, SSAKY+@SSAL-1 * Output the SSA. =RETURN= /* Write concatenated key value for each segment to sequential data set: Compute(Bridgend) Ltd
IMS/DL1 Sample 3 ...JCL as for IMS/DL1 Sample 1 OPTION PAGEDEPTH=99999 PAGEWIDTH=90 DATAWIDTH=80 OPTION WORKLEN=2100 READ CARD INTO 1001 * Input SSA. SPACE 2 !PRINT "### New Root Segment ###" * Print eye-catcher. GU DI21PART #1 IMS INTO 11 SSA=1001 * Get parent seg by key. IF POS STATUS='GE' * "Not found" status? THEN PRINT \ "## Segment not found for the following concatenated key:" THEN PRINT FROM 1001 LENGTH=80 * Print failing key value. THEN GOTO GET * Get the next key. DO PRINT_SEG * Print the input segment. ==LOOP== GNP DI21PART #1 IMS INTO 11 * Get next sequential seg in parent. IF POS STATUS=' ' !OR POS STATUS='GA' !OR POS STATUS='GK' THEN DO PRINT_SEG * Print the input segment. THEN GOTO LOOP * Get the next segment. IF POS STATUS <> 'G' * A status other than no more segs in parent? THEN CANCEL * Cancel all further operation. ELSE GOTO GET ==PRINT_SEG== MOVE 8 FROM POS SEG TO POS 1 * SEGNAME MOD POS 9 = ':' * : MOD POS 11+LRECL, 1000 = ' ' * Blank residue. PRINT FROM 1 LENGTH=80 * 1st 80 bytes. =RETURN= END PARTROOT*C(02RC07GF273J ) PARTROOT*C(02CK05CW181XXX ) PARTROOT*C(02CK05CW181K ) /* Print 80 chars of segment selected by concatenated key, and all its children: Compute (Bridgend) Ltd
IMS/DL1 Checkpoint (1/2) • Basic CHKP supported using SELCOPY CHKP operation. • Checkpoint ID identified as 8 characters at POS 1 • Extended CHKP/XRST possible via CALL ASMTDLI. • Save/restore the work area buffer. • CHKP requires PSB generated with CMPAT=Y. • XRST DL1 call required once only at start of program. • Extended (symbolic) CHKP calls can occur after XRST. • CHKP calls loses current position in all data bases (except GSAM). • Re-position using GU/GHU with SSA= and a saved concatenated key. • IEFRDER required for CHKP checkpoint log records. Compute(Bridgend) Ltd
IMS/DL1 Checkpoint (2/2) • XRST DL1 call... • Establishes environment for extended CHKP calls. • CKPTID value specified as parameter DFSRRC00... • Normal program start if no CKPTID specified. • Restart program if CKPTID specified and checkpoint log record exists. • Restart repositions pointers within data bases as recorded by the nominated checkpoint log record id. • On restart, input QSAM/VSAM data sets require re-positioning logic. • IMSLOGR containing checkpoint records required for XRST restart. • BMC AR/CTL check point pacing. • Returns status code “SK” for suppressed check point. • May be forced using CALL ASMTARC instead of CALL ASMTDLI. Note: ASMTARC has a slightly different parameter list to ASMTDLI. Compute(Bridgend) Ltd
IMS/DL1 Sample 4 //NBJJOB JOB ,,CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1),NOTIFY=&SYSUID // JCLLIB ORDER=IMS1210.PROCLIB //STEP001 EXEC PGM=SELCOPY //IEFRDER DD DISP=SHR,DSN=NBJ.SELCOPY.IMS.LOG //IMSLOGR DD DISP=SHR,DSN=NBJ.SELCOPY.IMS.LOG.RESTART //SYSPRINT DD SYSOUT=* //SYSIN DD * READ IEFRDER !WRITE IMSLOGR /* //STEP002 EXEC DLIBATCH,PSB=DFSSAM09,MBR=SELCOPY, CKPTID=SELC0001 // DBRC=N,IRLM=N //G.IEFRDER DD DISP=SHR,DSN=*.STEP001.IEFRDER //G.IMSLOGR DD DISP=SHR,DSN=*.STEP001.IMSLOGR //G.DFSVSAMP DD DISP=SHR,DSN=NBJ.SELCOPY.IMS.DFSVSAMP(DEFAULT) //SYSPRINT DD DISP=SHR,DSN=NBJ.SYSPRINT(SSIMS09) //SYSIN DD * * ### SELCOPY control statements follow. ### Update (REPL) specific named segments with program restart possibility: continued... Compute(Bridgend) Ltd
IMS/DL1 Sample 4 EQU INSEG 1 * Input segment. EQU PKEY 0 * Part Key Offset. EQU PNAM 26 * Part Name Offset. EQU INSEG_L 5000 * Maximum expected segment size. EQU SSAKY INSEG+INSEG_L * SSA string for GU on restart. EQU SEGN 0 !EQU SEGN_L 8 * Segment Name Off/Len.Len. EQU CMDC SEGN+SEGN_L !EQU CMDC_L 2 * Command Code Off/Len. '*C' EQU QUAL CMDC+CMDC_L !EQU QUAL_L 1 * Qualifier Off/Len. '(' EQU CKEY QUAL+QUAL_L !EQU CKEY_L 2048 * Concat Key Off/Len. '..)' EQU SSAKY_L 11+2048 * SSA string max length. EQU NPARM SSAKY+SSAKY_L * DL1 function call #parms. (BIN) EQU NPARM_L 4 * DL1 function call #parms. (4-bytes) EQU ICALL NPARM+NPARM_L * DL1 function name. (CHKP or XRST) EQU ICALL_L 4 * DL1 function name length. EQU CHKID ICALL+ICALL_L * Checkpoint id. EQU CHKID_L 14 * Checkpoint id area length. EQU CHKNO CHKID+CHKID_L * Checkpoint number. (BIN) EQU CHKNO_L 4 * Checkpoint number length. (4-bytes) OPT WORKLEN=CHKNO+CHKNO_L PAGEDEPTH=9999 DO XRST_RTN STOPAFT=1 * Execute XRST (once only). GHN DI21PART #1 IMS INTO INSEG SSA="PARTROOT " IF POS INSEG+PNAM = "RESISTOR " AND POS INSEG+PKEY+3 = "5" THEN POS INSEG+PNAM = "RESISTOR (5-OHM)" THEN DO BUILD_SSA * SSA for current segment. THEN REPL DI21PART #1 IMS FROM INSEG * Update current segment. THEN DO CHKP_RTN * Checkpoint. THEN GHU DI21PART #1 IMS INTO INSEG SSA=SSAKY * Reposition. GOTO GET * Get the next segment. *** Sub-routines follow *** ...continued continued...
IMS/DL1 Sample 4 ==BUILD_SSA== ** Build a concatenated key SSA. ** MOVE SEGN_L AT POS PCB+20 TO SSAKY+SEGN * Segment name. POS SSAKY+CMDC = '*C(' * Cat Key cmd code. @KEYL = 4 AT POS PCB+28 TYPE=B * Length of key. MOVE @KEYL AT POS PCB+36 TO SSAKY+CKEY, SSAKY+CKEY+CKEY_L-1 @SSAL = @KEYL+CKEY+1 * Fixed portion + key length + bracket. POS SSAKY+@SSAL-1 = ')' * Closing bracket. =RETURN= ==XRST_RTN== ** Extended restart - (Normal start if chkpid is blank). POS ICALL = 'XRST' * DL1 function. POS NPARM = X'0000,0006' * #parms. CALL ASMTDLI NPARM ICALL PARM-2 CHKID_L CHKID UXLRECL-8 1 IF POS CHKID, CHKID+CHKID_L-1 = ' ' FILL=' ' * If not restart. THEN POS CHKID = 'SELC ' * Init CHKP id. THEN POS CHKNO = X'0000,0000' * Init CHKP count. =RETURN= ==CHKP_RTN== ** Extended check point. POS ICALL = 'CHKP' * DL1 function. ADD 1 TO CHKNO_L AT CHKNO TYPE=B * CHKP id + 1 CVBC CHKNO_L AT CHKNO TO CHKID+4 FMT=9999 * Char format. CALL ASMTDLI NPARM ICALL PARM-2 CHKID_L CHKID UXLRECL-8 1 =RETURN= /* ...continued Compute(Bridgend) Ltd
IMS/DL1 Sample 5 ...JCL similar to IMS/DL1 Sample 4 EQU INREC 1 * Input key GSAM record area. EQU PSEG 0 * Insert segment name Offset. EQU PDAT 8 * Insert data Offset. EQU INREC_L 256 * Input key GSAM record max length. EQU XXSSA INREC+INREC_L * Build SSA area. EQU XXSSA_L 256 * Build SSA max length. EQU NPARM XXSSA+XXSSA_L * DL1 function call #parms. (BIN) EQU NPARM_L 4 * DL1 function call #parms. (4-bytes) EQU ICALL NPARM+NPARM_L * DL1 function name. (CHKP or XRST) EQU ICALL_L 4 * DL1 function name length. EQU CHKID ICALL+ICALL_L * Checkpoint id. EQU CHKID_L 14 * Checkpoint id area length. EQU CHKNO CHKID+CHKID_L * Checkpoint number. (BIN) EQU CHKNO_L 4 * Checkpoint number length. (4-bytes) OPT WORKLEN CHKNO+CHKNO_L PAGEDEPTH=9999 DO XRST_RTN STOPAFT=1 * Execute XRST (once only). POS XXSSA = " *L " STOPAFT=1 * Initialise SSA for ISRT. GN CBLGSAMD #1 IMS INTO INREC * GSAM input (SEGNAME + data). MOVE 8 AT INREC+PSEG TO XXSSA * Insert segment name. POS INREC+LRECL, INREC+INREC_L-1 = " " * Clear residue. ISRT DI21PART #1 IMS FROM INREC+PDAT SSA=XXSSA IF POS STATUS <> " " * If unexpected status code. THEN CANCEL * Cancel further operations. DO CHKP_RTN * Checkpoint. GOTO GET * Get the next input value. ** Sub-Routines follow ** Insert (ISRT) specific named segments with program restart possibility: continued...
IMS/DL1 Sample 5 ==XRST_RTN== ** Extended restart - (Normal start if chkpid is blank). POS ICALL = 'XRST' * DL1 function. POS NPARM = X'0000,0006' * #parms. CALL ASMTDLI NPARM ICALL PARM-2 CHKID_L CHKID UXLRECL-8 1 IF POS CHKID, CHKID+CHKID_L-1 = ' ' FILL=' ' * If not restart. THEN POS CHKID = 'SELC ' * Init CHKP id. THEN POS CHKNO = X'0000,0000' * Init CHKP count. =RETURN= ==CHKP_RTN== POS ICALL = 'CHKP' * DL1 function. ADD 1 TO CHKNO_L AT CHKNO TYPE=B * CHKP id + 1 CVBC CHKNO_L AT CHKNO TO CHKID+4 FMT=9999 * Char format. CALL ASMTDLI NPARM ICALL PARM-2 CHKID_L CHKID UXLRECL-8 1 =RETURN= /* ...continued Compute(Bridgend) Ltd
SLC Program • Included in SELCOPY Product Suite • Alternative SELCOPY program written in C++ • SELCOPY for Windows, Linux and UNIX source code • Same control statement syntax as SELCOPY program • Features available only in SLC include: • Regular Expressions • Declared Variables • IF/AND/OR range tests reverse scan • CHANGE, LEFT, RIGHT, CENTRE and CHOP • Date conversion and arithmetic • Input SELCOPYi generated lists Compute(Bridgend) Ltd
z/OS SLC Sample //JGESI JOB ,,CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1),NOTIFY=&SYSUID //* // SET VOL=CBLM06 Tailor volume name to run against. //* //SLCUNCAT EXEC PGM=SLC,PARM='&VOL' //SYSPRINT DD DISP=SHR,DSN=CBL.SYSPRINT(UC&VOL) //SYSIN DD * NOPRINT * Suppress print of control statements and summary. * SELCOPY (SLC) to identify uncataloged datasets on a specified volume. option REPORT HEAD='Uncataloged datasets on VOL=%1' option WORKLEN=44444 PAGEDEPTH=9999 do GetVTOCEntry do CheckIfCataloged goto get * Return to the start of the implied loop. ==CheckIfCataloged== ** Internal Sub-routines ** close MYCAT * Close current catalog entry list. pos 101 = 'cat' !pos 101+4 = 44 at 1 * "CAT <entryname>" if pos 101+4,101+4+44-1 = ' ' then pos @ = '.' * Extra dot prevents wildcards being auto-added. read MYCAT list=44+4 at 101 select='ENTRY' into 201 if eof MYCAT or pos 201 <> pos 1 length=44 then print '**Uncat**: ' from @L at 1 then @uncat = 0 stopaft=1 then @uncat = @uncat+1 =return= ==GetVTOCEntry== read MYVTOC list='vtoc %1' header \ select='DSN,SMi,ORG,RECFM,LRECL,BLKSZ' @L = lrecl * Save length of VTOC record if eof MYVTOC then space 2 then print 'Number of uncat datasets on %1:' @uncat fmt='zz,zz9' then space 4 !then EOJ if incount MYVTOC <= 2 * If it's a header/scale record. then print ' ' from @L at 1 then goto GetVTOCEntry =return= Report uncataloged VTOC entries for a specified volume:
SELCOPY for Windows • Included in SELCOPY Product Suite mainframe licences • STDIN/STDOUT for piping • I/O for different file line data (record) formats: • RECFM U - crlf, lf or other end-of-line characters • RECFM F - Fixed length lines • RECFM V/VB – Variable length with RDW/BDW • Non-native data types (Packed Decimal/Hex Float) • Micro Focus file I/O (VSAM emulation) • Database/Spreadsheet I/O via ODBC Compute(Bridgend) Ltd