You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于数字键/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部分
/*

说明

  1. 记录类型标记:用INREC给每条记录加一个类型标识(C=CHG, D=DATA, M=MOTIVE/MOTIVO, T=table),方便后续筛选和收集。
  2. 分组收集:GROUP BY=(1,1)按数字键分组,PUSH把每组内的C/D/M记录内容提取出来,放到每条记录的扩展区域。
  3. 输出拼接:过滤出T类型的table记录,把收集到的表头信息和table内容拼接成你想要的格式,自动去掉了每条记录开头重复的数字键。

为什么之前的RESIZE失败?

你之前的RESIZE没有指定分组规则,它会把所有输入记录当成一个整体来合并,自然会把不同数字键的记录块混在一起。加上GROUPBY参数后,就可以让RESIZE按你需要的数字键分组处理,完美解决这个问题。

内容的提问来源于stack exchange,提问作者csbl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:06:44