简化读取 SMF 以分析数据集生命周期的 DF/Sort 作业
Simplifying a DF/Sort job thats reads SMF to analyse a dataset's lifecycle
所以我有一个批处理作业,它将 SMF 类型 14、15 和 17 的记录提取到 3 个单独的文件中,然后格式化这些文件以生成一个列表,其中列出了哪些作业读取、写入和删除了哪些数据集。然后按时间戳排序,因此您可以看到特定数据集的 'lifecycle'。
但是,我知道 DF/Sortt 非常强大,我认为我最初分离 14、15 和 17 类型记录的步骤不是必需的,并且可以一步完成,但我不确定从哪里开始,因为 DFSort/ICETOOL 已经变得相当复杂了。
这是我当前的 JCL:
//JBSP03DL JOB (JSDBBSP,P10),'SMF F NOW',
// NOTIFY=&SYSUID,
// CLASS=L,
// MSGCLASS=X,
// REGION=8M
//*
//DELETE EXEC PGM=IEFBR14
//OUTDSN DD DISP=(MOD,DELETE),DSN=JSDBSP.JBSP03.DSLIFE.TXT,
// UNIT=SYSDA
//*
//SMFDUMP EXEC PGM=IFASMFDP,REGION=6M
//*
//SYSPRINT DD SYSOUT=*
//* Extract type 14, 15 and 17 records into 3 temporary datasets
//DUMPIN DD DISP=SHR,DSN=JSHSMF.SMF.JXSF.MANDUMP
//*
//DUMP14 DD DISP=(,PASS),DSN=&&TYPE14,
// UNIT=SYSDA,SPACE=(CYL,(500,200),RLSE),
// BUFNO=20,BLKSIZE=27998,LRECL=32760,RECFM=VBS
//DUMP15 DD DISP=(,PASS),DSN=&&TYPE15,
// UNIT=SYSDA,SPACE=(CYL,(500,200),RLSE),
// BUFNO=20,BLKSIZE=27998,LRECL=32760,RECFM=VBS
//DUMP17 DD DISP=(,PASS),DSN=&&TYPE17,
// UNIT=SYSDA,SPACE=(CYL,(500,200),RLSE),
// BUFNO=20,BLKSIZE=27998,LRECL=32760,RECFM=VBS
//*
//SYSIN DD *
INDD(DUMPIN,OPTIONS(DUMP))
OUTDD(DUMP14,TYPE(14))
OUTDD(DUMP15,TYPE(15))
OUTDD(DUMP17,TYPE(17))
//*
//SORTPROC PROC
//SORTWRTE EXEC PGM=SORT,REGION=8M
//SORTOUT DD DISP=MOD,DSN=&&SORTTMP,
// SPACE=(CYL,(20,20)),UNIT=SYSDA
//SYSOUT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SORTWK01 DD DISP=(NEW,DELETE),DSN=&&TEMPSORT,UNIT=SYSDA,
// SPACE=(CYL,(50,50))
// PEND
//*
//* Process the type 14 records
//TYPE14 EXEC SORTPROC
//SORTIN DD DISP=SHR,DSN=&&TYPE14
//SORTOUT DD DISP=(,PASS),DSN=&&SORTTMP,
// SPACE=(CYL,(20,20)),UNIT=SYSDA,
// LRECL=133
//SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
SUM FIELDS=NONE
OUTREC BUILD=(11,4,DT1,EDIT=(TTTT-TT-TT), DATE OF RECORD
C' AT ',
7,4,TM4,EDIT=(TT:TT:TT.TT), TIME OF RECORD
C' ',
69,44,
C' was opened by ',
19,8),CONVERT
//*
//* Process the type 15 records
//TYPE15 EXEC SORTPROC
//SORTIN DD DISP=SHR,DSN=&&TYPE15
//SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
SUM FIELDS=NONE
OUTREC BUILD=(11,4,DT1,EDIT=(TTTT-TT-TT), DATE OF RECORD
C' AT ',
7,4,TM4,EDIT=(TT:TT:TT.TT), TIME OF RECORD
C' ',
19,8,
C' opened ',
69,44,
C' for output'),CONVERT
//*
//* Process the type 17 records
//TYPE17 EXEC SORTPROC
//SORTIN DD DISP=SHR,DSN=&&TYPE17
//SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
SUM FIELDS=NONE
OUTREC BUILD=(11,4,DT1,EDIT=(TTTT-TT-TT), DATE OF RECORD
C' AT ',
7,4,TM4,EDIT=(TT:TT:TT.TT), TIME OF RECORD
C' ',
19,8,
C' deleted ',
44,44),CONVERT
//*
//* Finally sort the output file by the date & time stamp
//*
//FINAL EXEC SORTPROC
//SORTIN DD DISP=(OLD,DELETE),DSN=&&SORTTMP
//SORTOUT DD DISP=(NEW,CATLG),DSN=JSDBSP.JBSP03.DSLIFE.TXT,
// UNIT=SYSDA,LRECL=121,RECFM=FB,SPACE=(CYL,(20,30))
//SYSIN DD *
SORT FIELDS=(1,23,CH,A)
是否可以在不将第 14、15 和 17 条记录分成单独的文件的情况下执行此操作?
编辑:上面的 JCL 完全符合我的要求,但如果可能的话,我希望能够按数据集名称或作业名称进行过滤,因为这会产生很多输出,这对于 ISPF 来说太大了编辑或查看以供进一步分析
编辑:
Type 14 :
5 5 SMF14RTY 1 binary Record type 14 (X'0E').
18 12 SMF14JBN 8 EBCDIC Job name.
68 44 SMF14_JFCBDSNM 44 EBCDIC DATA SET NAME (DSNAME=)
Type 15 :
5 5 SMF14RTY 1 binary Record type 14 (X'0F').
18 12 SMF15JBN 8 EBCDIC Jobname
68 44 SMF15_JFCBDSNM 44 EBCDIC DATA SET NAME (DSNAME=)
Type 17:
5 5 SMF17RTY 1 binary Record type 17 (X'11').
18 12 SMF17JBN 8 EBCDIC Job name.
44 2C SMF17DSN 44 EBCDIC Data set name.
进一步的改进是检查 OPEN 是否真的在创建数据集。我还应该添加重命名,否则你可能
忘记了特定数据集发生了什么。
编辑:
按照 Bill 的指导,我的 JCL 现在是:
//DELETE EXEC PGM=IEFBR14
//OUTDSN DD DISP=(MOD,DELETE),DSN=JSDBSP.JBSP03.DSLIFE.TXT,
// UNIT=SYSDA
//*
//SORTWRTE EXEC PGM=SORT,REGION=8M
//*
//SORTIN DD DISP=SHR,DSN=JSHSMF.SMF.JXSG.MANDUMP
//SORTOUT DD DISP=(MOD,CATLG),DSN=JSDBSP.JBSP03.DSLIFE.TXT,
// SPACE=(CYL,(20,20)),
// UNIT=SYSDA,LRECL=133
//*
//SYSOUT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYMNOUT DD SYSOUT=*
//SYMNAMES DD *
SMF-RECORD-TYPE,5,1,BI
SMF-JOB-NAME,19,8,CH
SMF-14-15-DSN,69,44,CH
SMF-17-DSN,44,44,CH
SMF-DATE,11,4,DT1
SMF-TIME,7,4,TM4
//*
//SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
OUTREC IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,14),
BUILD=(SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-14-15-DSN,
C' was opened by ',
SMF-JOB-NAME)),CONVERT
但这给出了:
OUTREC IFTHEN=(WHEN=(5,1,BI,EQ,14),BUILD=(11,4,DT1,EDIT=(TTTT-TT-TT),C' AT ',7,4
,TM4,EDIT=(TT:TT:TT.TT),C' ',69,44,C' was opened by ',19,8)),CONVERT
*
WER268A OUTREC STATEMENT : SYNTAX ERROR
离开
,CONVERT
给我:
WER235A OUTREC RDW NOT INCLUDED
编辑 - 最新更新:
只是试图隔离类型 14 的记录,所以当前输入现在是:
//SYMNAMES DD *
SMF-RECORD-TYPE,6,1,BI
SMF-JOB-NAME,11,8,CH
SMF-14-15-DSN,65,44,CH
SMF-17-DSN,44,44,CH
SMF-DATE,11,4,DT1
SMF-TIME,7,4,TM4
SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
OUTFIL IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,14),
BUILD=(1,4,SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-14-15-DSN,
C' was opened by ',
SMF-JOB-NAME))
"Is it possible to do this without separating the 14, 15 and 17 records into separate files?"
根据http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IEA2G2C0/3.2.1
...DD 语句
//DUMP DD DISP=(,PASS),...
... 控制语句为
OUTDD(DUMP,TYPE(14,15,17))
...会将所有类型合并到一个文件中。
是的,而且相当无痛。
IFTHEN=(WHEN=
允许各种类型的条件处理。
在这里你可以使用 IFTHEN=(WHEN=(logicalexpression) 来创建一个 case/select/evaluate-type 结构:
IFTHEN=(WHEN=(5,1,B,EQ,14),
...),
IFTHEN=(WHEN=(5,1,B,EQ,15),
...),
IFTHEN=(WHEN=NONE,
...)
WHEN=NONE
是 "catch-all",因为前面测试的 none 为真。当一个测试为真时,IFTHEN=(WHEN=(logicalexpression) 停止当前记录。即使当前记录的第二个条件为真,它也不会被执行。如果你想要两个或更多 "hits"在 IFTHEN=(WHEN=(logicalexpression) 那么你必须在每次测试结束时使用 HIT=NEXT ,你可能想要 "pass it on" 到下一个测试。
在这里,这无关紧要,因为它是针对单个值测试的同一字段。
IFTHEN 可以出现在 INREC
、OUTREC
或 OUTFIL
上。你在 OUTREC 上进行了处理,所以你会(尽管请参阅我后来的评论):
OUTREC IFTHEN=(WHEN=(5,1,B,EQ,14),
...),
IFTHEN=(WHEN=(5,1,B,EQ,15),
...),
IFTHEN=(WHEN=NONE,
...)
BUILD
、OVERLAY
和 PARSE
可以在 IFTHEN 中使用。
一些想法和提示。
我怀疑你的 SUM FIELDS=NONE
。这将删除任何具有重复键的记录。保留输入中的哪条记录取决于。如果您在 SORT
(或 MERGE
)上使用 OPTION EQUALS
或 EQUALS
,则将始终保留第一条记录。如果您不这样做,则在密钥重复时保留的记录可能会有所不同 运行 运行。 EQUALS 对性能有一些影响。
无论如何,我不确定为什么你在这里有 FIELDS=NONE。您甚至可以在完全不同的数据集上进行 "accidental" 匹配。
如果您要排序然后 select 仅部分数据(在 OUTREC 或 OUTFIL 中),则始终考虑 "cutting down" 要排序的记录,以便它只包括您稍后将使用的数据。排序时,数据越少,使用的时间、内存和临时存储空间就越少。
考虑使用 DYNAM
作为临时存储,并从 JCL 中删除您的 SORTWKn
DD 名称(这里只有一个,但是...)。工作区的动态分配意味着您根本不必考虑工作区(除非您有大量数据记录长度变化很大的数据集)并且您不需要 "overallocate".
排序符号。符号允许您命名您的数据,因此可以通过名称来引用同一字段,并且 SORT 负责每次键入起始位置和长度的不那么令人兴奋的任务。它还减少了所需的注释量,因为该字段已经有一个名称,您可以对其进行描述。
符号在单独的数据集 (F/FB 80) 中定义,带有 SYMNAMES DD。翻译后的符号(也提供了所用内容的记录)保存在 SYMNOUT 数据集中,这不是必需的,但很有用。
SORT 然后将符号应用于您的控制卡,并在 SYSOUT 中显示您的原始来源,并向您显示翻译后的卡。
可以按照这些行指定此任务的符号
SMF-RECORD-TYPE,5,1,BI
SMF-JOB-NAME,18,8,CH
SMF-14-15-DSN,68,44,CH
SMF-17-DSN,44,44,CH
SMF-DATE,11,4,DT1
SMF-TIME,7,4,TM4
然后你可以用符号替换同一个字段的多个定义,让SORT来完成工作。
如果你想对数据集做selection,你可以看看使用PARM和特殊符号JP0
-JP9
。或者硬编码。或者从数据集列表生成 SORT 控制卡,或者使用 JOINKEYS
.
哦,我知道你知道,但你实际上在使用 SYNCSORT。 DFSORT 在 OUTREC 上没有 CONVERT
,但在 OUTFIL 上有。为了便于携带,这里只需将您的 OUTREC 更改为 OUTFIL。
好的 - 在 Bill 的帮助下(他让我接受了他的回答)并且在决定坚持使用手册之后,这是我的结果:
//jobname JOB (acct_code),'pgmr_name',
// NOTIFY=&SYSUID,
// CLASS=L,
// MSGCLASS=X,
// REGION=8M
//*
// SET OUTFILE=your.results.file
//*
//DELETE EXEC PGM=IEFBR14
//OUTDSN DD DISP=(MOD,DELETE),DSN=&OUTFILE,
// UNIT=SYSDA
//*
//SMFDUMP EXEC PGM=IFASMFDP,REGION=6M
//*
//SYSPRINT DD SYSOUT=*
//*
//DUMPIN DD DISP=SHR,DSN=your.smf.dataset
//*
//DUMPOUT DD DISP=(,PASS),DSN=&&SMFTEMP,
// UNIT=SYSDA,SPACE=(CYL,(500,200),RLSE),
// BUFNO=20,DCB=*.DUMPIN
//*
//SYSIN DD *
INDD(DUMPIN,OPTIONS(DUMP))
OUTDD(DUMPOUT,TYPE(14,15,17,18))
//*
//SORTPROC PROC
//SORTWRTE EXEC PGM=SORT,REGION=8M
//SORTIN DD DUMMY
//SORTOUT DD DUMMY
//SYSOUT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYMNAMES DD *
RDW,1,4,BI
SMF-RECORD-TYPE,6,1,BI
SMF-JOB-NAME,19,8,CH
SMF-14-15-DSN,69,44,CH
SMF-17-18-DSN,45,44,CH
SMF-17-DSN,45,44,CH
SMF-18-DSN,45,44,CH
SMF-18-NDSN,89,44,CH
SMF-DATE,11,4,DT1
SMF-TIME,7,4,TM4
SMFDEBOP,253,1
// PEND
//*
//PROCESS EXEC SORTPROC
//SORTIN DD DISP=OLD,DSN=&&SMFTEMP
//SORTOUT DD DISP=(,PASS),DSN=&&SORTTMP,
// SPACE=(CYL,(20,20)),UNIT=SYSDA
//SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
OUTREC IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,14),
BUILD=(RDW,SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-14-15-DSN,
C' was opened by ',
SMF-JOB-NAME)),
IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,15),
BUILD=(RDW,SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-JOB-NAME,
C' opened ',
SMF-14-15-DSN,
C' for output')),
IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,17),
BUILD=(RDW,SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-JOB-NAME,
C' deleted ',
SMF-17-DSN)),
IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,18),
BUILD=(RDW,SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-JOB-NAME,
C' renamed ',
SMF-18-DSN,
C' to ',
SMF-18-NDSN))
//*
//FINAL EXEC SORTPROC
//SORTIN DD DISP=OLD,DSN=&&SORTTMP
//SORTOUT DD DSN=&OUTFILE,
// DISP=(NEW,CATLG),UNIT=SYSDA,SPACE=(CYL,(20,30),RLSE)
//SYSIN DD *
OPTION VLSHRT,VLSCMP
SORT FIELDS=(5,25,CH,A)
INCLUDE COND=(1,125,SS,EQ,C'PEEL',
AND,
1,125,SS,EQ,C'XCOM')
OUTFIL FNAMES=SORTOUT,VTOF,OUTREC=(5,126)
我无法确定是否可以将最后一步合并到主要步骤中,但我对它的现状很满意。请注意,我们实际上使用的是 Syncsort,而不是 DF/Sort,因此请注意,如果您是 DF/Sort 商店,则可能需要进行更改。
存在 INCLUDE COND 是因为在大多数情况下,输出数据集对于 ISPF 编辑或查看来说太大,否则您可以只编辑输出并在那里进行过滤。
所以我有一个批处理作业,它将 SMF 类型 14、15 和 17 的记录提取到 3 个单独的文件中,然后格式化这些文件以生成一个列表,其中列出了哪些作业读取、写入和删除了哪些数据集。然后按时间戳排序,因此您可以看到特定数据集的 'lifecycle'。
但是,我知道 DF/Sortt 非常强大,我认为我最初分离 14、15 和 17 类型记录的步骤不是必需的,并且可以一步完成,但我不确定从哪里开始,因为 DFSort/ICETOOL 已经变得相当复杂了。
这是我当前的 JCL:
//JBSP03DL JOB (JSDBBSP,P10),'SMF F NOW',
// NOTIFY=&SYSUID,
// CLASS=L,
// MSGCLASS=X,
// REGION=8M
//*
//DELETE EXEC PGM=IEFBR14
//OUTDSN DD DISP=(MOD,DELETE),DSN=JSDBSP.JBSP03.DSLIFE.TXT,
// UNIT=SYSDA
//*
//SMFDUMP EXEC PGM=IFASMFDP,REGION=6M
//*
//SYSPRINT DD SYSOUT=*
//* Extract type 14, 15 and 17 records into 3 temporary datasets
//DUMPIN DD DISP=SHR,DSN=JSHSMF.SMF.JXSF.MANDUMP
//*
//DUMP14 DD DISP=(,PASS),DSN=&&TYPE14,
// UNIT=SYSDA,SPACE=(CYL,(500,200),RLSE),
// BUFNO=20,BLKSIZE=27998,LRECL=32760,RECFM=VBS
//DUMP15 DD DISP=(,PASS),DSN=&&TYPE15,
// UNIT=SYSDA,SPACE=(CYL,(500,200),RLSE),
// BUFNO=20,BLKSIZE=27998,LRECL=32760,RECFM=VBS
//DUMP17 DD DISP=(,PASS),DSN=&&TYPE17,
// UNIT=SYSDA,SPACE=(CYL,(500,200),RLSE),
// BUFNO=20,BLKSIZE=27998,LRECL=32760,RECFM=VBS
//*
//SYSIN DD *
INDD(DUMPIN,OPTIONS(DUMP))
OUTDD(DUMP14,TYPE(14))
OUTDD(DUMP15,TYPE(15))
OUTDD(DUMP17,TYPE(17))
//*
//SORTPROC PROC
//SORTWRTE EXEC PGM=SORT,REGION=8M
//SORTOUT DD DISP=MOD,DSN=&&SORTTMP,
// SPACE=(CYL,(20,20)),UNIT=SYSDA
//SYSOUT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SORTWK01 DD DISP=(NEW,DELETE),DSN=&&TEMPSORT,UNIT=SYSDA,
// SPACE=(CYL,(50,50))
// PEND
//*
//* Process the type 14 records
//TYPE14 EXEC SORTPROC
//SORTIN DD DISP=SHR,DSN=&&TYPE14
//SORTOUT DD DISP=(,PASS),DSN=&&SORTTMP,
// SPACE=(CYL,(20,20)),UNIT=SYSDA,
// LRECL=133
//SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
SUM FIELDS=NONE
OUTREC BUILD=(11,4,DT1,EDIT=(TTTT-TT-TT), DATE OF RECORD
C' AT ',
7,4,TM4,EDIT=(TT:TT:TT.TT), TIME OF RECORD
C' ',
69,44,
C' was opened by ',
19,8),CONVERT
//*
//* Process the type 15 records
//TYPE15 EXEC SORTPROC
//SORTIN DD DISP=SHR,DSN=&&TYPE15
//SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
SUM FIELDS=NONE
OUTREC BUILD=(11,4,DT1,EDIT=(TTTT-TT-TT), DATE OF RECORD
C' AT ',
7,4,TM4,EDIT=(TT:TT:TT.TT), TIME OF RECORD
C' ',
19,8,
C' opened ',
69,44,
C' for output'),CONVERT
//*
//* Process the type 17 records
//TYPE17 EXEC SORTPROC
//SORTIN DD DISP=SHR,DSN=&&TYPE17
//SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
SUM FIELDS=NONE
OUTREC BUILD=(11,4,DT1,EDIT=(TTTT-TT-TT), DATE OF RECORD
C' AT ',
7,4,TM4,EDIT=(TT:TT:TT.TT), TIME OF RECORD
C' ',
19,8,
C' deleted ',
44,44),CONVERT
//*
//* Finally sort the output file by the date & time stamp
//*
//FINAL EXEC SORTPROC
//SORTIN DD DISP=(OLD,DELETE),DSN=&&SORTTMP
//SORTOUT DD DISP=(NEW,CATLG),DSN=JSDBSP.JBSP03.DSLIFE.TXT,
// UNIT=SYSDA,LRECL=121,RECFM=FB,SPACE=(CYL,(20,30))
//SYSIN DD *
SORT FIELDS=(1,23,CH,A)
是否可以在不将第 14、15 和 17 条记录分成单独的文件的情况下执行此操作?
编辑:上面的 JCL 完全符合我的要求,但如果可能的话,我希望能够按数据集名称或作业名称进行过滤,因为这会产生很多输出,这对于 ISPF 来说太大了编辑或查看以供进一步分析
编辑:
Type 14 :
5 5 SMF14RTY 1 binary Record type 14 (X'0E').
18 12 SMF14JBN 8 EBCDIC Job name.
68 44 SMF14_JFCBDSNM 44 EBCDIC DATA SET NAME (DSNAME=)
Type 15 :
5 5 SMF14RTY 1 binary Record type 14 (X'0F').
18 12 SMF15JBN 8 EBCDIC Jobname
68 44 SMF15_JFCBDSNM 44 EBCDIC DATA SET NAME (DSNAME=)
Type 17:
5 5 SMF17RTY 1 binary Record type 17 (X'11').
18 12 SMF17JBN 8 EBCDIC Job name.
44 2C SMF17DSN 44 EBCDIC Data set name.
进一步的改进是检查 OPEN 是否真的在创建数据集。我还应该添加重命名,否则你可能 忘记了特定数据集发生了什么。
编辑:
按照 Bill 的指导,我的 JCL 现在是:
//DELETE EXEC PGM=IEFBR14
//OUTDSN DD DISP=(MOD,DELETE),DSN=JSDBSP.JBSP03.DSLIFE.TXT,
// UNIT=SYSDA
//*
//SORTWRTE EXEC PGM=SORT,REGION=8M
//*
//SORTIN DD DISP=SHR,DSN=JSHSMF.SMF.JXSG.MANDUMP
//SORTOUT DD DISP=(MOD,CATLG),DSN=JSDBSP.JBSP03.DSLIFE.TXT,
// SPACE=(CYL,(20,20)),
// UNIT=SYSDA,LRECL=133
//*
//SYSOUT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYMNOUT DD SYSOUT=*
//SYMNAMES DD *
SMF-RECORD-TYPE,5,1,BI
SMF-JOB-NAME,19,8,CH
SMF-14-15-DSN,69,44,CH
SMF-17-DSN,44,44,CH
SMF-DATE,11,4,DT1
SMF-TIME,7,4,TM4
//*
//SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
OUTREC IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,14),
BUILD=(SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-14-15-DSN,
C' was opened by ',
SMF-JOB-NAME)),CONVERT
但这给出了:
OUTREC IFTHEN=(WHEN=(5,1,BI,EQ,14),BUILD=(11,4,DT1,EDIT=(TTTT-TT-TT),C' AT ',7,4
,TM4,EDIT=(TT:TT:TT.TT),C' ',69,44,C' was opened by ',19,8)),CONVERT
*
WER268A OUTREC STATEMENT : SYNTAX ERROR
离开
,CONVERT
给我:
WER235A OUTREC RDW NOT INCLUDED
编辑 - 最新更新:
只是试图隔离类型 14 的记录,所以当前输入现在是:
//SYMNAMES DD *
SMF-RECORD-TYPE,6,1,BI
SMF-JOB-NAME,11,8,CH
SMF-14-15-DSN,65,44,CH
SMF-17-DSN,44,44,CH
SMF-DATE,11,4,DT1
SMF-TIME,7,4,TM4
SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
OUTFIL IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,14),
BUILD=(1,4,SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-14-15-DSN,
C' was opened by ',
SMF-JOB-NAME))
"Is it possible to do this without separating the 14, 15 and 17 records into separate files?"
根据http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IEA2G2C0/3.2.1
...DD 语句
//DUMP DD DISP=(,PASS),...
... 控制语句为
OUTDD(DUMP,TYPE(14,15,17))
...会将所有类型合并到一个文件中。
是的,而且相当无痛。
IFTHEN=(WHEN=
允许各种类型的条件处理。
在这里你可以使用 IFTHEN=(WHEN=(logicalexpression) 来创建一个 case/select/evaluate-type 结构:
IFTHEN=(WHEN=(5,1,B,EQ,14),
...),
IFTHEN=(WHEN=(5,1,B,EQ,15),
...),
IFTHEN=(WHEN=NONE,
...)
WHEN=NONE
是 "catch-all",因为前面测试的 none 为真。当一个测试为真时,IFTHEN=(WHEN=(logicalexpression) 停止当前记录。即使当前记录的第二个条件为真,它也不会被执行。如果你想要两个或更多 "hits"在 IFTHEN=(WHEN=(logicalexpression) 那么你必须在每次测试结束时使用 HIT=NEXT ,你可能想要 "pass it on" 到下一个测试。
在这里,这无关紧要,因为它是针对单个值测试的同一字段。
IFTHEN 可以出现在 INREC
、OUTREC
或 OUTFIL
上。你在 OUTREC 上进行了处理,所以你会(尽管请参阅我后来的评论):
OUTREC IFTHEN=(WHEN=(5,1,B,EQ,14),
...),
IFTHEN=(WHEN=(5,1,B,EQ,15),
...),
IFTHEN=(WHEN=NONE,
...)
BUILD
、OVERLAY
和 PARSE
可以在 IFTHEN 中使用。
一些想法和提示。
我怀疑你的 SUM FIELDS=NONE
。这将删除任何具有重复键的记录。保留输入中的哪条记录取决于。如果您在 SORT
(或 MERGE
)上使用 OPTION EQUALS
或 EQUALS
,则将始终保留第一条记录。如果您不这样做,则在密钥重复时保留的记录可能会有所不同 运行 运行。 EQUALS 对性能有一些影响。
无论如何,我不确定为什么你在这里有 FIELDS=NONE。您甚至可以在完全不同的数据集上进行 "accidental" 匹配。
如果您要排序然后 select 仅部分数据(在 OUTREC 或 OUTFIL 中),则始终考虑 "cutting down" 要排序的记录,以便它只包括您稍后将使用的数据。排序时,数据越少,使用的时间、内存和临时存储空间就越少。
考虑使用 DYNAM
作为临时存储,并从 JCL 中删除您的 SORTWKn
DD 名称(这里只有一个,但是...)。工作区的动态分配意味着您根本不必考虑工作区(除非您有大量数据记录长度变化很大的数据集)并且您不需要 "overallocate".
排序符号。符号允许您命名您的数据,因此可以通过名称来引用同一字段,并且 SORT 负责每次键入起始位置和长度的不那么令人兴奋的任务。它还减少了所需的注释量,因为该字段已经有一个名称,您可以对其进行描述。
符号在单独的数据集 (F/FB 80) 中定义,带有 SYMNAMES DD。翻译后的符号(也提供了所用内容的记录)保存在 SYMNOUT 数据集中,这不是必需的,但很有用。
SORT 然后将符号应用于您的控制卡,并在 SYSOUT 中显示您的原始来源,并向您显示翻译后的卡。
可以按照这些行指定此任务的符号
SMF-RECORD-TYPE,5,1,BI
SMF-JOB-NAME,18,8,CH
SMF-14-15-DSN,68,44,CH
SMF-17-DSN,44,44,CH
SMF-DATE,11,4,DT1
SMF-TIME,7,4,TM4
然后你可以用符号替换同一个字段的多个定义,让SORT来完成工作。
如果你想对数据集做selection,你可以看看使用PARM和特殊符号JP0
-JP9
。或者硬编码。或者从数据集列表生成 SORT 控制卡,或者使用 JOINKEYS
.
哦,我知道你知道,但你实际上在使用 SYNCSORT。 DFSORT 在 OUTREC 上没有 CONVERT
,但在 OUTFIL 上有。为了便于携带,这里只需将您的 OUTREC 更改为 OUTFIL。
好的 - 在 Bill 的帮助下(他让我接受了他的回答)并且在决定坚持使用手册之后,这是我的结果:
//jobname JOB (acct_code),'pgmr_name',
// NOTIFY=&SYSUID,
// CLASS=L,
// MSGCLASS=X,
// REGION=8M
//*
// SET OUTFILE=your.results.file
//*
//DELETE EXEC PGM=IEFBR14
//OUTDSN DD DISP=(MOD,DELETE),DSN=&OUTFILE,
// UNIT=SYSDA
//*
//SMFDUMP EXEC PGM=IFASMFDP,REGION=6M
//*
//SYSPRINT DD SYSOUT=*
//*
//DUMPIN DD DISP=SHR,DSN=your.smf.dataset
//*
//DUMPOUT DD DISP=(,PASS),DSN=&&SMFTEMP,
// UNIT=SYSDA,SPACE=(CYL,(500,200),RLSE),
// BUFNO=20,DCB=*.DUMPIN
//*
//SYSIN DD *
INDD(DUMPIN,OPTIONS(DUMP))
OUTDD(DUMPOUT,TYPE(14,15,17,18))
//*
//SORTPROC PROC
//SORTWRTE EXEC PGM=SORT,REGION=8M
//SORTIN DD DUMMY
//SORTOUT DD DUMMY
//SYSOUT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYMNAMES DD *
RDW,1,4,BI
SMF-RECORD-TYPE,6,1,BI
SMF-JOB-NAME,19,8,CH
SMF-14-15-DSN,69,44,CH
SMF-17-18-DSN,45,44,CH
SMF-17-DSN,45,44,CH
SMF-18-DSN,45,44,CH
SMF-18-NDSN,89,44,CH
SMF-DATE,11,4,DT1
SMF-TIME,7,4,TM4
SMFDEBOP,253,1
// PEND
//*
//PROCESS EXEC SORTPROC
//SORTIN DD DISP=OLD,DSN=&&SMFTEMP
//SORTOUT DD DISP=(,PASS),DSN=&&SORTTMP,
// SPACE=(CYL,(20,20)),UNIT=SYSDA
//SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
OUTREC IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,14),
BUILD=(RDW,SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-14-15-DSN,
C' was opened by ',
SMF-JOB-NAME)),
IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,15),
BUILD=(RDW,SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-JOB-NAME,
C' opened ',
SMF-14-15-DSN,
C' for output')),
IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,17),
BUILD=(RDW,SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-JOB-NAME,
C' deleted ',
SMF-17-DSN)),
IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,18),
BUILD=(RDW,SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-JOB-NAME,
C' renamed ',
SMF-18-DSN,
C' to ',
SMF-18-NDSN))
//*
//FINAL EXEC SORTPROC
//SORTIN DD DISP=OLD,DSN=&&SORTTMP
//SORTOUT DD DSN=&OUTFILE,
// DISP=(NEW,CATLG),UNIT=SYSDA,SPACE=(CYL,(20,30),RLSE)
//SYSIN DD *
OPTION VLSHRT,VLSCMP
SORT FIELDS=(5,25,CH,A)
INCLUDE COND=(1,125,SS,EQ,C'PEEL',
AND,
1,125,SS,EQ,C'XCOM')
OUTFIL FNAMES=SORTOUT,VTOF,OUTREC=(5,126)
我无法确定是否可以将最后一步合并到主要步骤中,但我对它的现状很满意。请注意,我们实际上使用的是 Syncsort,而不是 DF/Sort,因此请注意,如果您是 DF/Sort 商店,则可能需要进行更改。
存在 INCLUDE COND 是因为在大多数情况下,输出数据集对于 ISPF 编辑或查看来说太大,否则您可以只编辑输出并在那里进行过滤。