Since IDCAMS REPRO does not support VSAM datasets in RLS mode (and neither does SORT, nor FileAID) you can’t use it to backup or restore a CLUSTER while it is open somewhere else. This is something that ShareOption/5 used to allow but this product is defunct. I’d like to be able to copy/merge one KSDS to another while the dataset is open to CICS adding new records, replacing the records in the target dataset that have the same keys as the records in the source dataset (and leaving the other target dataset records extant) while the target dataset is being shared in RLS mode.
Access method services do not use RLS when performing an IDCAMS EXPORT, IMPORT, PRINT, or REPRO command. If the RLS keyword is specified in the DD statement of a data set to be opened by access method services, the keyword is ignored and the data set is opened and accessed in non-RLS mode. — z/OS DFSMS Using Data Sets
So, let’s do this in C, because I happen to have access to the C compiler.
??=pragma filetag("IBM-1047") #pragma langlvl(extended) /* Merge a KSDS (sysut1) with another (sysut2) adding new reqcords and replacing existing records. The KSDSs must be defined with the same record length, key position and key length otherwise results are unpredictable. */ #include <stdio.h> int main(void) { FILE * sysut1; FILE * sysut2; unsigned int rec1l; unsigned char * rec1p; unsigned char * rec2p; int sysut1_reads = 0; int sysut2_writes = 0; int sysut2_updates = 0; struct __fileData filedata1; struct __fileData filedata2; char filename1[256]; char filename2[256]; /* setenv("_EDC_IO_TRACE","(//DD:*,2,)",1); */ sysut1 = fopen("dd:sysut1", "rb,type=record"); if (sysut1 == NULL) { perror("dd:sysut1 open error"); exit(16); } fldata(sysut1, filename1, &filedata1); printf("Note: %s opened (SYSUT1)\n", filedata1.__dsname); if (filedata1.__vsamRLS == __RLS) printf("Note: SYSUT1 is using RLS\n"); if (filedata1.__vsamRLS == __TVS) printf("Note: SYSUT1 is using TVS\n"); rec1p = (unsigned char *) malloc(filedata1.__maxreclen); sysut2 = fopen("dd:sysut2", "rb+,type=record"); if (sysut2 == NULL) { perror("dd:sysut2 open error"); exit(16); } fldata(sysut2, filename2, &filedata2); printf("Note: %s opened (SYSUT2)\n", filedata2.__dsname); if (filedata2.__vsamRLS == __RLS) printf("Note: SYSUT2 is using RLS\n"); if (filedata2.__vsamRLS == __TVS) printf("Note: SYSUT2 is using TVS\n"); rec2p = (unsigned char *) malloc(filedata2.__maxreclen); if (filedata1.__maxreclen > filedata2.__maxreclen) printf("Note: SYSUT1 maximum record length is greater than SYSUT2\n"); if ((filedata1.__vsamRKP != filedata2.__vsamRKP) || (filedata1.__vsamkeylen != filedata2.__vsamkeylen)) printf("Note: SYSUT1 key position/length differs from SYSUT2\n"); putchar('\n'); /* -- */ rec1l = fread(rec1p, 1, filedata1.__maxreclen, sysut1); while (rec1l > 0) { ++sysut1_reads; if (flocate(sysut2, rec1p+filedata2.__vsamRKP, filedata2.__vsamkeylen, __KEY_EQ) == 0) { fread(rec2p, 1, filedata2.__maxreclen, sysut2); if (ferror(sysut2)) { perror("dd:sysut2 read error"); exit(16); } fupdate(rec1p, rec1l, sysut2); if (ferror(sysut2)) { perror("dd:sysut2 update error"); exit(16); } ++sysut2_updates; } else { clearerr(sysut2); fwrite(rec1p, 1, rec1l, sysut2); if (ferror(sysut2)) { perror("dd:sysut2 write error"); exit(16); } ++sysut2_writes; } rec1l = fread(rec1p, 1, filedata1.__maxreclen, sysut1); } if (ferror(sysut1)) { perror("dd:sysut1 read error"); exit(16); } printf(" %5i SYSUT1 records read\n", sysut1_reads); printf(" %5i SYSUT2 records updated\n", sysut2_updates); printf(" %5i SYSUT2 new records written\n", sysut2_writes); fclose(sysut1); fclose(sysut2); }
Compile with something like this…
//* // JCLLIB ORDER=(CBC.SCCNPRC) //* //CC EXEC EDCCB, // INFILE='XXXXXXX.SRC.C(VSAMCOPY)', // OUTFILE='XXXXXXX.SRC.LOAD(VSAMCOPY),DISP=SHR', // CPARM='LIST,SOU,XREF,NOMARG,NOSEQ,RENT,OPT,ARCH(10),TUNE(10),LOC' //*
Obviously, seeing ARCH(10), I must be running on (at least) a zEC12, eh? Anyway, this new program can be executed with something like:
//* //COPY EXEC PGM=VSAMCOPY //STEPLIB DD DISP=SHR,DSN=XXXXXXX.SRC.LOAD //SYSUT1 DD DISP=SHR,DSN=VSAM.INPUT,RLS=NRI //SYSUT2 DD DISP=SHR,DSN=VSAM.OUTPUT,RLS=NRI //SYSOUT DD SYSOUT=* //SYSPRINT DD SYSOUT=*