如何比较来自不同数据集的两个总数
How to compare two totals from different datasets
我们有三个不同的文件,一个是这样的
文件A
000001000
000002000
000003000
000004000
文件 B(对文件 A 中的所有记录求和后)
000010000
文件 C
Total : - 10000
我必须比较文件 C 和文件 B 中的值,如果值匹配成功,我必须设置所需的 Return 代码 RC。
单词的起始位置"Total"是五
为什么你不使用 JOINKEYS?
专业人士会知道不要将 JOINKEYS
用于此任务,或者会识别反对使用它的具体建议。
对于其他人,这就是为什么不。
JOINKEYS 由三个 "Tasks"、主任务和两个子任务(每个输入数据集一个)组成。这意味着 JOINKEYS 最多可以使用普通 SORT/MERGE/COPY 三倍的内存。这意味着 JOINKEYS 步骤可能更难 "select" 并且可以阻止其他作业被选中。这也意味着 JOINKEYS 步骤将比不使用 JOINKEYS 的等效解决方案慢(这可能取决于确切的解决方案,但对于任何琐碎的事情都是如此)。
更多内存,更多 CPU,更多经过时间,对其他 JOB 的影响更大。
仅在必要时使用 JOINKEYS。 "so I can type/copy-paste less code"不是必须的意思,是说当一个好的解决方案需要使用JOINKEYS.
如果解决方案不需要 JOINKEYS,则不要使用 JOINKEYS。有人为额外的资源和影响买单。专业人士可以避免此类费用。
当然,这样的建议是免费的,有时您会得到您付出的代价。但是,我是 www.ibmmainframes.com 的 DFSORT 版主,接替了 IBM 的 Frank Yaeger(现代 DFSORT 的发明者)的任务。
此外,在 https://whosebug.com/users/5433120/sharad-singhal 给出的示例代码中,JOINKEYS 甚至无法使用他们自己在问题中显示的数据,因为字段类型不同(一个左零填充,另一个前导零 t运行cated, right-space-padded).
您当然可以使用 JNF2CNTL DD
和一些代码(此处包含所需的代码)规范化第二个密钥。
但是。甚至。尽管。它。能。是。制成。到。工作。连接键。是。答:不好。解决方案。为了。这个。任务。
我希望这对未来的搜索者来说是清楚的。
I have to set the desired Return Code RC
这是不可能的,除非是巧合。 DFSORT 提供给您的唯一条件 Code/Return 代码 (CC/RC) 是零、四和 16。
也许这提供了您想要的 CC/RC 之一。如果没有,请改变您的愿望。或者通过使用 IDCAMS 步骤将 "convert" 从 DFSORT 得到的 CC/RC 变成你迫切想要的 CC/RC 来做一些奇怪的事情。
使用正确的控制卡,除了零 RC 之外,您可以获得的唯一方法是使用空输出文件(SORTOUT 或 OUTFIL 数据集)。
您想求和。 SUM 需要 SORT 或 MERGE。您还可以使用 OUTFIL 报告函数、REMOVECC 和 TOTAL 来获取总和,但到那时您没有机会测试两个总计是否相等。
匹配数据集是 JOINKEYS 的好任务。
您也可以自己编码求和。
在资源方面,由于您可能是初学者,最好的解决方案是 MERGE。
您的 JCL 中需要两个 DD,SORTIN01 和 SORTIN02,以代替通常用于 SORT 步骤的 SORTIN。您还需要至少一个输出 DD,可以是 SORTOUT,但最好是另一个,并且应该将其设置为 DUMMY 或 DSN=NULLFILE。
您需要安排所有值记录得到一个相等的 "key",以便它们可以求和,并且您的总计记录应该得到一个不同的值。
//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 symbols/SYMNAMES。这些是在 SYMNAMES DD 上定义的(最好作为 PDSE(或 PDS)成员,固定长度的 80 字节记录。
SYMNOUT DD 语句列出了源符号,以及 DFSORT 用来翻译控制卡的规范化符号。
在 INREC 中,建立合并键,在总记录的情况下,与值记录上的值匹配的输入位置(不再需要)设置为零。输入文件中不需要输出的任何数据都可以愉快地销毁(如果不写入,则不写入,因此其内容无关紧要,如果方便的话可以修改)。
MERGE 然后使用刚刚建立的密钥。这只是允许使用 SUM 的技巧。所有的值记录(键5)将被求和为一个实际值,总记录将保持原样(因为它的键是唯一的)。
在 OUTREC 中,总计记录中的总计将使用 WHEN=GROUP 推送到下一条记录(求和值)。 Total 记录的无符号自由格式数据将转换为 Zoned Decimal 值。
然后有两个OUTFIL语句。
首先查看 SUMmed 记录并将该值与 Total 记录中的 PUSHed 值进行比较。如果它们相等,则将一条记录写入 OUTFIL(在 JCL 中为 DUMMY)。 RC4 不会被设置。如果值不同,则不会写入任何记录并设置 RC4。
第二个 OUTFIL 是创建您的 FILEB,它本身不需要作为文件。如果你不需要 FILEB 做其他任何事情,你可以删除这个 OUTFIL。
我已将 SORTOUT DD 留在 JCL 中,因此您可以查看记录发生了什么。一旦您很高兴知道发生了什么,就可以将其删除。
您唯一可以获得的其他 RC 是 16。避免这种情况,因为 16 也是为控制卡或 运行-time 错误而产生的。
我也找到了使用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
/*
当匹配成功时,它将return RC=0
并且
当 Match 未完全成功时,它将 return RC=4,因为它是使用 PARM 提供的。
基本上它会在输出文件(sortout)中搜索记录,如果匹配成功,jcl 排序实用程序会将记录从 fileB 复制到输出文件(在假脱机中),如果匹配不成功,则输出文件为空并且在 PARM='NULLOUT=RC4′ 的帮助下 return RC=4.
我们有三个不同的文件,一个是这样的
文件A
000001000
000002000
000003000
000004000
文件 B(对文件 A 中的所有记录求和后)
000010000
文件 C
Total : - 10000
我必须比较文件 C 和文件 B 中的值,如果值匹配成功,我必须设置所需的 Return 代码 RC。
单词的起始位置"Total"是五
为什么你不使用 JOINKEYS?
专业人士会知道不要将 JOINKEYS
用于此任务,或者会识别反对使用它的具体建议。
对于其他人,这就是为什么不。
JOINKEYS 由三个 "Tasks"、主任务和两个子任务(每个输入数据集一个)组成。这意味着 JOINKEYS 最多可以使用普通 SORT/MERGE/COPY 三倍的内存。这意味着 JOINKEYS 步骤可能更难 "select" 并且可以阻止其他作业被选中。这也意味着 JOINKEYS 步骤将比不使用 JOINKEYS 的等效解决方案慢(这可能取决于确切的解决方案,但对于任何琐碎的事情都是如此)。
更多内存,更多 CPU,更多经过时间,对其他 JOB 的影响更大。
仅在必要时使用 JOINKEYS。 "so I can type/copy-paste less code"不是必须的意思,是说当一个好的解决方案需要使用JOINKEYS.
如果解决方案不需要 JOINKEYS,则不要使用 JOINKEYS。有人为额外的资源和影响买单。专业人士可以避免此类费用。
当然,这样的建议是免费的,有时您会得到您付出的代价。但是,我是 www.ibmmainframes.com 的 DFSORT 版主,接替了 IBM 的 Frank Yaeger(现代 DFSORT 的发明者)的任务。
此外,在 https://whosebug.com/users/5433120/sharad-singhal 给出的示例代码中,JOINKEYS 甚至无法使用他们自己在问题中显示的数据,因为字段类型不同(一个左零填充,另一个前导零 t运行cated, right-space-padded).
您当然可以使用 JNF2CNTL DD
和一些代码(此处包含所需的代码)规范化第二个密钥。
但是。甚至。尽管。它。能。是。制成。到。工作。连接键。是。答:不好。解决方案。为了。这个。任务。
我希望这对未来的搜索者来说是清楚的。
I have to set the desired Return Code RC
这是不可能的,除非是巧合。 DFSORT 提供给您的唯一条件 Code/Return 代码 (CC/RC) 是零、四和 16。
也许这提供了您想要的 CC/RC 之一。如果没有,请改变您的愿望。或者通过使用 IDCAMS 步骤将 "convert" 从 DFSORT 得到的 CC/RC 变成你迫切想要的 CC/RC 来做一些奇怪的事情。
使用正确的控制卡,除了零 RC 之外,您可以获得的唯一方法是使用空输出文件(SORTOUT 或 OUTFIL 数据集)。
您想求和。 SUM 需要 SORT 或 MERGE。您还可以使用 OUTFIL 报告函数、REMOVECC 和 TOTAL 来获取总和,但到那时您没有机会测试两个总计是否相等。
匹配数据集是 JOINKEYS 的好任务。
您也可以自己编码求和。
在资源方面,由于您可能是初学者,最好的解决方案是 MERGE。
您的 JCL 中需要两个 DD,SORTIN01 和 SORTIN02,以代替通常用于 SORT 步骤的 SORTIN。您还需要至少一个输出 DD,可以是 SORTOUT,但最好是另一个,并且应该将其设置为 DUMMY 或 DSN=NULLFILE。
您需要安排所有值记录得到一个相等的 "key",以便它们可以求和,并且您的总计记录应该得到一个不同的值。
//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 symbols/SYMNAMES。这些是在 SYMNAMES DD 上定义的(最好作为 PDSE(或 PDS)成员,固定长度的 80 字节记录。
SYMNOUT DD 语句列出了源符号,以及 DFSORT 用来翻译控制卡的规范化符号。
在 INREC 中,建立合并键,在总记录的情况下,与值记录上的值匹配的输入位置(不再需要)设置为零。输入文件中不需要输出的任何数据都可以愉快地销毁(如果不写入,则不写入,因此其内容无关紧要,如果方便的话可以修改)。
MERGE 然后使用刚刚建立的密钥。这只是允许使用 SUM 的技巧。所有的值记录(键5)将被求和为一个实际值,总记录将保持原样(因为它的键是唯一的)。
在 OUTREC 中,总计记录中的总计将使用 WHEN=GROUP 推送到下一条记录(求和值)。 Total 记录的无符号自由格式数据将转换为 Zoned Decimal 值。
然后有两个OUTFIL语句。
首先查看 SUMmed 记录并将该值与 Total 记录中的 PUSHed 值进行比较。如果它们相等,则将一条记录写入 OUTFIL(在 JCL 中为 DUMMY)。 RC4 不会被设置。如果值不同,则不会写入任何记录并设置 RC4。
第二个 OUTFIL 是创建您的 FILEB,它本身不需要作为文件。如果你不需要 FILEB 做其他任何事情,你可以删除这个 OUTFIL。
我已将 SORTOUT DD 留在 JCL 中,因此您可以查看记录发生了什么。一旦您很高兴知道发生了什么,就可以将其删除。
您唯一可以获得的其他 RC 是 16。避免这种情况,因为 16 也是为控制卡或 运行-time 错误而产生的。
我也找到了使用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
/*
当匹配成功时,它将return RC=0 并且
当 Match 未完全成功时,它将 return RC=4,因为它是使用 PARM 提供的。
基本上它会在输出文件(sortout)中搜索记录,如果匹配成功,jcl 排序实用程序会将记录从 fileB 复制到输出文件(在假脱机中),如果匹配不成功,则输出文件为空并且在 PARM='NULLOUT=RC4′ 的帮助下 return RC=4.