基于数字键/CHG分隔符合并转置多记录的技术实现咨询
用DFSORT实现按数字键分组的记录合并/重组(满足两种输出需求)
首先,我明白你需要把按数字键(或含CHG的记录)分隔的记录块进行处理:要么把同块记录合并成单条,要么让每条table记录关联块内的CHG/DATA/MOTIVE信息。之前用RESIZE失败是因为没有按分组键处理,导致不同块的记录被混在一起了。
先明确你的输入、期望输出和之前的尝试:
输入数据示例
1 CHG 1 DATA 1 MOTIVE 1 table1 1 table2 1 table3 2 CHG 2 DATA 2 MOTIVO 2 table1 3 CHG 3 DATA 3 MOTIVE 3 table1 3 table2 3 table3 3 table4 3 table5
最低要求输出
1 CHG 1 DATA 1 MOTIVE 1 table1 1 table2 1 table3 2 CHG 2 DATA 2 MOTIVO 2 table1 3 CHG 3 DATA 3 MOTIVE 3 table1 3 table2 3 table3 3 table4 3 table5
理想输出(移除记录首字节冗余)
1 CHG DATA MOTIVE table1 1 CHG DATA MOTIVE table2 1 CHG DATA MOTIVE table3 2 CHG DATA MOTIVE table1 3 CHG DATA MOTIVE table1 3 CHG DATA MOTIVE table2 3 CHG DATA MOTIVE table3 3 CHG DATA MOTIVE table4 3 CHG DATA MOTIVE table5
之前的尝试(未成功的JCL)
//TOOLIN DD * RESIZE FROM(INDD) TO(OUTDD1) TOLEN(600) USING(CTL1) //TOOLIN DD * RESIZE FROM(INDD) TO(OUTDD1) TOLEN(600) USING(CTL1) //CTL1CNTL DD * INREC BUILD=(1,50) OUTFIL FNAMES=OUTDD1,OVERLAY=(1:1,600) /*
一、实现最低要求输出(同组记录合并为单条)
核心是给RESIZE加上分组控制,让它按数字键(第1位)分别处理每个记录块:
//SORTJOB JOB ... //SORT EXEC PGM=SORT //SYSOUT DD SYSOUT=* //INDD DD DSN=YOUR.INPUT.FILE,DISP=SHR //OUTDD1 DD DSN=YOUR.OUTPUT.MIN,DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(1,1)),LRECL=600,RECFM=FB //TOOLIN DD * RESIZE FROM(INDD) TO(OUTDD1) TOLEN(600) - GROUPBY=(1,1,CH) // 关键:按第1位数字键分组,避免跨块混淆 //CTL1CNTL DD * INREC BUILD=(1,50) // 提取前50字节有效数据,可根据实际调整 OUTFIL FNAMES=OUTDD1,BUILD=(1,600) /*
说明
GROUPBY=(1,1,CH)是DFSORT对RESIZE的扩展支持,它会把第1位相同的记录归为一组,每组内的记录单独合并成单条,完美解决你之前不同块混淆的问题。TOLEN(600)设置输出记录长度为600,足够容纳每组最多50条60字节记录的拼接(匹配你提到的记录块数量范围1-50)。
二、实现理想输出(每条table记录关联组内表头)
这个需求需要先收集每组内的CHG、DATA、MOTIVE(或MOTIVO)信息,再把这些信息和每组内的tableN记录拼接。这里用DFSORT的GROUP功能来实现:
//SORTJOB JOB ... //SORT EXEC PGM=SORT //SYSOUT DD SYSOUT=* //INDD DD DSN=YOUR.INPUT.FILE,DISP=SHR //OUTDD2 DD DSN=YOUR.OUTPUT.IDEAL,DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(1,1)),LRECL=80,RECFM=FB //SYSIN DD * OPTION EQUALS // 给每条记录标记类型,方便后续分组收集 INREC IFTHEN=(WHEN=(2,4,CH,EQ,C'CHG '),BUILD=(1,1,C'C',2,57)), IFTHEN=(WHEN=(2,5,CH,EQ,C'DATA '),BUILD=(1,1,C'D',2,57)), IFTHEN=(WHEN=(2,6,CH,EQ,C'MOTIVE',OR,2,6,CH,EQ,C'MOTIVO'), BUILD=(1,1,C'M',2,57)), IFTHEN=(WHEN=(2,5,CH,EQ,C'table'),BUILD=(1,1,C'T',2,57)) // 按数字键排序,确保同组记录连续 SORT FIELDS=(1,1,CH,A) // 分组收集每组的CHG、DATA、MOTIVE信息,推送到每条记录 GROUP BY=(1,1), PUSH=(60:IFTHEN=(WHEN=(2,1,CH,EQ,C'C'),BUILD=(3,57)), // 收集CHG行内容 117:IFTHEN=(WHEN=(2,1,CH,EQ,C'D'),BUILD=(3,57)), // 收集DATA行内容 174:IFTHEN=(WHEN=(2,1,CH,EQ,C'M'),BUILD=(3,57))), // 收集MOTIVE行内容 RECORDS=50 // 匹配你的最大记录块数量 // 只保留table记录,拼接成理想格式 OUTFIL FNAMES=OUTDD2, REMOVECC, INCLUDE=(2,1,CH,EQ,C'T'), // 过滤出table类型记录 BUILD=(1,1,X, // 数字键 60,5,X, // CHG部分(如"CHG") 117,6,X, // DATA部分(如"DATA") 174,7,X, // MOTIVE/MOTIVO部分 3,5) // tableN部分 /*
说明
- 记录类型标记:用
INREC给每条记录加一个类型标识(C=CHG, D=DATA, M=MOTIVE/MOTIVO, T=table),方便后续筛选和收集。 - 分组收集:
GROUP BY=(1,1)按数字键分组,PUSH把每组内的C/D/M记录内容提取出来,放到每条记录的扩展区域。 - 输出拼接:过滤出T类型的table记录,把收集到的表头信息和table内容拼接成你想要的格式,自动去掉了每条记录开头重复的数字键。
为什么之前的RESIZE失败?
你之前的RESIZE没有指定分组规则,它会把所有输入记录当成一个整体来合并,自然会把不同数字键的记录块混在一起。加上GROUPBY参数后,就可以让RESIZE按你需要的数字键分组处理,完美解决这个问题。
内容的提问来源于stack exchange,提问作者csbl
相关产品推荐
相关产品推荐

