使用大型机中的 DFSORT 实用程序进行乘法除法
Posted
技术标签:
【中文标题】使用大型机中的 DFSORT 实用程序进行乘法除法【英文标题】:Multiplication division using DFSORT utility in Mainframe 【发布时间】:2017-01-31 03:12:48 【问题描述】:有两个文件 FILE1.DATA 和 FILE2.DATA 在 Mainframe 中使用 DFSORT 计算百分比(FILE1 中的记录数/FILE2 中的记录数)*100。如果超过阈值 (90%),则设置返回代码。
//********Extracting Unique records data*****************
//SORTT000 EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTIN DD DSN=SAMPLE.DATA1,DISP=SHR
//SORTOUT DD DSN=FILE1.DATA,
// SPACE=(2790,(5376,1075),RLSE),
// UNIT=TSTSF,
// DCB=(RECFM=FB,LRECL=05,BLKSIZE=0),
// DISP=(NEW,CATLG,DELETE)
//SYSIN DD *
SORT FIELDS=(10,5,CH,A)
OUTREC FIELDS=(1:10,5)
SUM FIELDS=NONE
/*
//************Getting count of records*****************
//STEP001 EXEC PGM=ICETOOL
//TOOLMSG DD SYSOUT=*
//DFSMSG DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//IN1 DD DISP=SHR,DSN=FILE1.DATA
//IN2 DD DISP=SHR,DSN=FILE2.DATA
//OUT1 DD DSN=FILE1.DATA.COUNT,
// SPACE=(2790,(5376,1075),RLSE),
// UNIT=TSTSF,
// DCB=(RECFM=FB,LRECL=06,BLKSIZE=0),
// DISP=(NEW,CATLG,DELETE)
//OUT2 DD DSN=FILE2.DATA.COUNT,
// SPACE=(2790,(5376,1075),RLSE),
// UNIT=TSTSF,
// DCB=(RECFM=FB,LRECL=06,BLKSIZE=0),
// DISP=(NEW,CATLG,DELETE)
//TOOLIN DD *
COUNT FROM(IN1) WRITE(OUT1) DIGITS(6)
COUNT FROM(IN2) WRITE(OUT2) DIGITS(6)
/*
//*******Calculating percentage and if above 90% setting RC 04*****
//STEP002 EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTIN DD DSN=FILE2.DATA.COUNT,DISP=SHR
// DD DSN=FILE1.DATA.COUNT,DISP=SHR
//SORTOUT DD DSN=FILE.DATA.COUNT.OUT,
// SPACE=(2790,(5376,1075),RLSE),
// UNIT=TSTSF,
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=0),
// DISP=(NEW,CATLG,DELETE)
//SETRC DD SYSOUT=*
//SYSIN DD *
INREC IFTHEN=(WHEN=INIT,BUILD=(1,6,X,6X'00',SEQNUM,1,ZD,80:X)),
IFTHEN=(WHEN=(14,1,ZD,EQ,2),OVERLAY=(8:1,6))
SORT FIELDS=(7,1,CH,A),EQUALS
SUM FIELDS=(8,4,BI,12,2,BI)
OUTREC OVERLAY=(15:X,1,6,ZD,DIV,+2,M11,LENGTH=6,X,
(8,6,ZD,MUL,+100),DIV,1,6,ZD,MUL,+100,EDIT=(TTT.TT))
OUTFIL FNAMES=SETRC,NULLOFL=RC4,INCLUDE=(23,6,CH,GT,C'090.00')
OUTFIL BUILD=(05:C'TOTAL NUMBER RECRODS IN FILE2 : ',1,6,/,
05:C'TOTAL NUMBER RECRODS IN FILE1 : ',8,6,/,
05:C'PERCENTAGE : ',23,6,/,
80:X)
//*
-
我面临的问题是尽管提到了 LRECL 6,但数据集 FILE1.DATA.COUNT 和 FILE1.DATA.COUNT 被创建为 15 条记录长度。(注意,这是在编写第一个答案时存在的问题并且确实现在与上面的代码无关)。
我们可以将这两个步骤合并为一个吗?
(15:X,1,6,ZD,DIV,+2,M11,LENGTH=6,X, (8,6,ZD,MUL,+100),DIV,1,6,ZD,MUL,+100,EDIT=(TTT.TT))
这具体是什么意思?
【问题讨论】:
大概你的文件很大吧?这将使整个过程效率低下。从已经在读取数据的东西中获取计数,然后你就拥有了一些非常简单和高效的东西。您输入的 RECFM 和 LRECL 是什么?您是否阅读了 COUNT 的文档(否,答案是,所以这样做)? @Bill 我的两个输入文件都有大约 10000 条记录。 我在 step001 中添加了 DIGITS(6) 并在 OUTFIL FNAMES=SETRC,NULLOFL=RC4,INCLUDE=(23,6,CH,GT,C'090.00') 下面进行了修改。现在它工作正常。 有趣。您的评论一定是在我写答案时到达的。请阅读答案。 非常感谢比尔。我会通过你的回答, 【参考方案1】:你第一个问题的答案就是你没有告诉 ICETOOL 的 COUNT 运算符你希望输出数据多长时间,所以 它想出了自己的形象。
这是来自 DFSORT 应用程序编程指南:
WRITE(countdd) 指定计数数据集的ddname为 由 ICETOOL 为该操作制作。 countdd DD 语句必须是 展示。 ICETOOL设置count数据集的属性如下:
v RECFM 设置为 FB。
v LRECL 设置为以下之一:
– 如果指定了 WIDTH(n),则 LRECL 设置为 n。如果您计数,请使用 WIDTH(n) 记录长度和 LRECL 必须设置为特定值(对于 例如 80),或者如果要确保计数记录长度 不超过特定的最大值(例如,20 个字节)。
–如果没有指定WIDTH(n),则将LRECL设置为计算所需 记录长度。如果您的 LRECL 不需要设置为特定的 值,您可以让 ICETOOL 确定并设置合适的 LRECL 通过不指定 WIDTH(n) 来获取值。
还有:
数字(d)
为输出记录中的计数指定 d 位,覆盖 默认为 15 位。 d 可以是 1 到 15。计数写为 d 带前导零的十进制数字。只有在以下情况下才能指定 DIGITS 指定了 WRITE(countdd)。
如果您知道您的计数需要少于 15 位,您可以使用 通过指定 DIGITS(d) 来减少位数 (d)。为了 例如,如果指定了 DIGITS(10),则使用 10 位而不是 15 位。
如果您使用 DIGITS(d) 并且计数溢出位数 使用,ICETOOL 终止操作。你可以防止溢出 通过为 DIGITS(d) 指定适当更高的 d 值。为了 例如,如果 DIGITS(5) 导致溢出,您可以使用 DIGITS(6) 而是。
还有:
宽度(n)
指定您希望 ICETOOL 使用的记录长度和 LRECL 计数数据集。 n 可以是 1 到 32760。WIDTH 只能指定 如果指定了 WRITE(countdd)。 ICETOOL 总是计算记录 写入计数记录所需的长度并使用如下:
v 如果指定了 WIDTH(n) 并且计算的记录长度小于 大于或等于 n,ICETOOL 将记录长度和 LRECL 设置为 n。 ICETOOL 用空格填充右侧的计数记录 长度。
v 如果指定了 WIDTH(n) 并且计算的记录长度更大 大于 n,ICETOOL 会发出错误消息并终止操作。
v 如果未指定 WIDTH(n),ICETOOL 将设置记录长度并 LRECL 到计算的记录长度。
如果您的计数记录长度和 LRECL 必须设置为 特定值(例如,80),或者如果您想确保 count 记录长度不超过特定的最大值(例如, 20 个字节)。否则,您可以让 ICETOOL 计算并设置 通过不指定 WIDTH(n) 来获得适当的记录长度和 LRECL。
对于第二个问题,是的,它可以一步完成,并且大大简化。
问题是,它可以通过做其他事情来进一步简化。究竟还有什么取决于您的实际任务,我们不知道,我们只知道您为任务选择的解决方案。
例如,您想知道一个文件何时在另一个文件大小的 10% 以内。如果不需要实时准确度,一种方法是与管理您的存储的技术人员交谈。告诉他们您想做什么,他们可能已经有了您可以使用的东西(在讨论这个问题时,请记住这些在技术上是数据集,而不是文件)。
或者,某些东西之前已经读取或写入了这些文件。如果最后一个这样做的程序还没有产生它读/写的计数(在我看来,标准的良好实践,程序也可以协调),那么现在修改程序以这样做。那里。魔法。你有你的计数。
将这些计数安排在他们自己的数据集中(最好使用记录类型、标题/拖尾,更标准的良好做法)。
采取两个计数中较大的(预期)的步骤,“计算” 00% 将是多少(不需要任何东西,只需简单的减法,使用正确的数据)并生成一个 SYMNAMES 格式文件(固定-length 80 字节记录),带有一个 SORT 符号,表示具有该值的常量。
第二步,使用 INCLUDE/OMIT 和符号来比较第二个记录计数,使用 NULLOUT 或 NULLOFL。
上述几种解决方案的优点是它们基本上使用的资源很少。在大型机上,客户端为资源付费。您的客户可能会在年底发现他们为阅读和“计数”730 万条记录而支付费用只是为了您可以设置 RC。
好吧,也许 7.3m 不是那么大,但是,当你有了你的“解决方案”时,下一个人会处理 100,000 条记录,下一个人会处理 1,000,000 条记录。全部设置RC。任何一次运行(即使以 10,000 条记录为例)都将超过未来 15 年以上每天运行的“大型机”解决方案的成本。
第三个问题:
OUTREC OVERLAY=(15:X,1,6,ZD,DIV,+2,M11,LENGTH=6,X,
(8,6,ZD,MUL,+100),DIV,1,6,ZD,MUL,+100,EDIT=(TTT.TT))
OUTREC 在 SORT/MERGE 和 SUM(如果存在)之后处理,否则在 INREC 之后处理。请注意,这些在 JCL 中指定的物理顺序不会影响它们的处理顺序。
OVERLAY 表示“使用这些数据操作更新当前记录中的信息(BUILD 始终创建当前记录的新副本)。
15:是记录中的“第 15 列”(第 15 位)。
X 插入一个空格。
1,6,ZD 表示“信息,此时在起始位置一,长度为六,是带区十进制格式”。
DIV 是除数。
+2 是一个数值常数。
1,6,ZD,DIV,+2 的意思是“取从位置一开始的六位数,除以二,得到一个‘结果’,它将被放置在下一个可用位置(16 in你的情况)。
M11 是一个内置的编辑掩码。有关该掩码的详细信息,请在手册中查找,因为您会发现其他有用的预定义掩码。使用它来格式化结果。
LENGTH=6 将结果限制为六位数。
到目前为止,前六个位置的数字将除以二,(通过掩码)被视为从第 16 位开始的六位无符号分区十进制数。
语句的其余元素是相似的。括号以正常方式影响数字运算符的“优先级”(请参阅手册以熟悉优先级规则)。
EDIT=(TTT.TT) 是一个使用定义的编辑掩码,在这种情况下插入一个小数点,截断原本存在的最左边的数字,并在必要时使用重要的前导零。
【讨论】:
以上是关于使用大型机中的 DFSORT 实用程序进行乘法除法的主要内容,如果未能解决你的问题,请参考以下文章