如何比较不同数据集中的两个总计

时间:2015-10-11 11:09:16

标签: mainframe dfsort

我们有三个不同的文件,就像那个

档案A

000001000
000002000
000003000 
000004000 

文件B(在对文件A中的所有记录求和之后)

000010000

档案C

     Total : - 10000

我必须比较文件C和文件B中的值,如果值匹配成功,我必须设置所需的返回码RC。

单词" Total"的起始位置是五。

2 个答案:

答案 0 :(得分:0)

为什么你不会使用JOINKEYS?

专业人员会知道不会将JOINKEYS用于此任务,或者会认识到不使用它的具体建议。

对于其他人来说,这就是为什么不呢。

JOINKEYS由三个"任务",主任务和两个子任务(每个输入数据集一个)组成。这意味着JOINKEYS最多可以使用普通SORT / MERGE / COPY的三倍内存。这意味着JOINKEYS步骤可能更难以选择"并且可以防止其他JOB被选中。这也意味着JOINKEYS步骤将比不使用JOINKEYS的等效解决方案慢(这可能取决于确切的解决方案,但对于任何微不足道的事情都是如此)。

更多内存,更多CPU,更多时间,对其他JOB的影响更大。

仅在必要时使用JOINKEYS。必要并不意味着"因此我可以输入/复制粘贴较少的代码",这意味着当一个好的解决方案需要使用JOINKEYS时。

如果解决方案不要求 JOINKEYS,那么请不要使用JOINKEYS。有人支付额外的资源和影响。专业人士避免这样的费用。

当然,这样的建议是免费的,而且你有时会得到你付出的代价。但是,我是www.ibmmainframes.com上的DFSORT主持人,接管了现代DFSORT的发明者IBM的Frank Yaeger的任务。

另外,在https://stackoverflow.com/users/5433120/sharad-singhal给出的示例代码中,JOINKEYS甚至无法使用他们自己在问题中显示的数据,因为字段类型不同(一个左零填充,另一个前导零截断,右空间填充)。

您当然可以使用JNF2CNTL DD和一些代码(此处包含所需代码)来规范化第二个密钥。

但是。甚至。虽然。它。能够。是。制作。至。工作。 JOINKEYS。是。答:不好。解。对于。这个。任务。

我希望任何未来的搜索者都清楚这一点。

  

我必须设置所需的返回码RC

除了巧合之外,这是不可能的。 DFSORT唯一可用的条件代码/返回代码(CC / RC)为零,四和十六。

也许这提供了你想要的CC / RC之一。如果没有,改变你的愿望。或者通过使用IDCAMS步骤来转换"转换"您从DFSORT到CC / RC的CC / RC,你非常想要。

使用正确的控制卡,除了零RC之外,唯一可以获得的方法是使用空输出文件(SORTOUT或OUTFIL数据集)。

你想要SUM。 SUM需要SORT或MERGE。您还可以使用OUTFIL报告函数REMOVECC和TOTAL来获得总和,但到那时您还没有机会测试两个总数是否相等。

匹配数据集对JOINKEYS来说是一项很好的任务。

您也可以自己编码总结。

资源方面,既然你可能是初学者,最好的解决方案就是MERGE。

您需要在JCL,SORTIN01和SORTIN02中使用两个DD代替SORTIN,这通常用于SORT步骤。您还需要至少一个输出DD,可以是SORTOUT,但最好是另一个,这应该设置为DUMMY或DSN = NULLFILE。

您需要安排所有价值记录获得"密钥"它是相同的,因此它们可以被SUMmed,你的Total记录应该得到不同的值。

//MATCHTOT EXEC PGM=SORT 
//SYMNAMES DD * 
* IN- is the input records with values (and the summed value later)
* EXT- are temporary extensions made to the record for processing 
* TOT- is the total record 
* IND- is an indicator determining wheter value or total record 
IN-RECORD,*,80,CH 
EXT-IN-IND,*,1,CH 
EXT-TOT-TOTAL-VALUE,*,9,zd 
POSITION,IN-RECORD 
IN-VALUE,=,9,ZD 
IN-SUM-VALUE,=,=,= 
POSITION,IN-RECORD 
SKIP,5 
TOT-TOTAL-NAME,*,5,CH 
SKIP,5 
TOT-TOTAL-VALUE,*,9,CH 
* Constants 
TOTAL-TEXT,C'Total' 
IND-TOT-TOTAL,C'0' 
IND-IN-VALUE,C'5' 
CLOBBER-FIRST-PART,C'000000000' 
//SYMNOUT  DD SYSOUT=* 
//CHECK    DD DUMMY 
//SYSOUT   DD SYSOUT=* 
//SORTOUT  DD SYSOUT=* 
//FILEB DD SYSOUT=* 
//SYSIN    DD * 

  INREC IFTHEN=(WHEN=(TOT-TOTAL-NAME,
                 EQ, 
                TOTAL-TEXT), 
                 OVERLAY=(EXT-IN-IND: 
                           IND-TOT-TOTAL, 
                          IN-VALUE: 
                           CLOBBER-FIRST-PART)), 
        IFTHEN=(WHEN=NONE, 
                 OVERLAY=(EXT-IN-IND: 
                           IND-IN-VALUE)) 

  MERGE FIELDS=(EXT-IN-IND,A) 

  SUM FIELDS=(IN-VALUE) 

  OUTREC IFTHEN=(WHEN=GROUP, 
                  BEGIN=(EXT-IN-IND, 
                          EQ, 
                         IND-TOT-TOTAL), 
                  PUSH=(EXT-TOT-TOTAL-VALUE: 
                         TOT-TOTAL-VALUE)), 

         IFTHEN=(WHEN=INIT, 
                  OVERLAY=(EXT-TOT-TOTAL-VALUE: 
                            EXT-TOT-TOTAL-VALUE,UFF,
                            TO=ZD, 
                            LENGTH=9)) 

  OUTFIL FNAMES=CHECK, 
         INCLUDE=(EXT-IN-IND, 
                   EQ, 
                  IND-IN-VALUE, 
                 AND, 
                  IN-SUM-VALUE, 
                   EQ, 
                  EXT-TOT-TOTAL-VALUE), 
         NULLOFL=RC4 

  OUTFIL FNAMES=FILEB, 
         INCLUDE=(EXT-IN-IND,CH,EQ,IND-IN-VALUE), 
         BUILD=(IN-RECORD) 

//SORTIN01 DD * 
000001000 
000002000 
000003000 
000004000 
//SORTIN02 DD * 
     Total : - 20000

这使用DFSORT符号/ SYMNAMES。这些是在SYMNAMES DD上定义的(最好是PDSE(或PDS)成员,固定长度的80字节记录。

SYMNOUT DD语句列出了源符号,以及DFSORT用于转换控制卡的规范化符号。

在INREC中,建立合并的密钥,在Total记录的情况下,与值记录的值匹配的输入位置(不再需要)设置为零。来自输入文件的输出不需要的任何数据都可以很好地销毁(如果没有写入,则不会写入,因此其内容无关紧要,如果方便的话可以修改)。

MERGE然后使用刚刚建立的密钥。这只是允许使用SUM的技巧。所有值记录(键五)将被SUMmed为实际值,总记录将保持原样(因为其键是唯一的)。

在OUTREC中,使用WHEN = GROUP将总记录中的总数推送到下一记录(SUMmed值)。 Total记录的Unsigned Free Format数据将转换为Zoned Decimal值。

然后有两个OUTFIL语句。

第一个查看SUMmed记录,并将值与总记录中的值PUSHed进行比较。如果它们相等,则会将记录写入OUTFIL(在JCL中为DUMMY)。 RC4将不会被设置。如果值不同,则不会写入任何记录,并且将设置RC4。

第二个OUTFIL是创建你的FILEB,它本身不需要作为文件。如果您不需要FILEB,则可以删除此OUTFIL。

我已将SORTOUT DD留在JCL中,以便您可以看到记录会发生什么。一旦你开心就知道发生了什么,你就可以删除它。

唯一可以获得的其他RC是16.避免这种情况,因为控制卡或运行时错误也会产生16。

答案 1 :(得分:0)

我也使用JOINKEY找到问题的解决方案。

代码如下。

//STEP1  EXEC PGM=SORT,PARM=’NULLOUT=RC4′                     
//SORTJNF1 DD DSN=FILEB                                   
//SORTJNF2 DD DSN=FILEC                                   
//SORTOUT  DD SYSOUT=*                           
//SYSOUT   DD SYSOUT=*                           
//SYSIN    DD *                                   
 JOINKEYS FILE=F1,FIELDS=(1,9,A) 
 JOINKEYS FILE=F2,FIELDS=(5,9,a) 
 REFORMAT FIELDS=(F1:1,80)                 
 OPTION COPY     
/*              

当匹配成功时,它将返回RC = 0 并且

当匹配未成功时,它将返回RC = 4,因为它是使用PARM提供的。

基本上它在输出文件中搜索记录(sortout)如果匹配成功,jcl排序实用程序会将记录从fileB复制到输出文件(在假脱机中),如果不成功匹配,则输出文件为空并且在PARM ='NULLOUT = RC4'的帮助下,它返回RC = 4。