Оператор SELECT
//ICETSIM1 EXEC PGM=ICETOOL
//TOOLMSG DD SYSOUT=*
//DFSMSG DD SYSOUT=*
//SYMNOUT DD SYSOUT=*
//NAMESIN DD *
LINK_REC;1,45
LINK_REFDATE;=,8,CH
LINK;*,16,CH
LINK_COLL;*,16,CH
LINK_TYPE;*,3,CH
LINK_LABEL;*,02,CH
LINK_P_LABEL;=,1,CH
LINK_S_LABEL;*,1,CH
//NAMESOUT DD DSN=&NAMES,DISP=(,PASS,DELETE),SPACE=(TRK,1)
//TOOLIN DD *
COPY FROM(NAMESIN) TO(NAMESOUT)
//S01 EXEC PGM=ICETOOL
//TOOLMSG DD SYSOUT=*
//DFSMSG DD SYSOUT=*
//SYMNAMES DD DSN=&NAMES,DISP=(OLD,PASS)
//SYMNOUT DD SYSOUT=*
//IN2 DD DISP=SHR,DSN=LINKS.001
SELECT FROM(IN2) TO(OU2) ON(LINK) FIRST USING(CTL2)
//CTL2CNTL DD *
OUTFIL FNAMES=OU2,
OUTREC=(LINK_REFDATE,16X,LINK,500X,LINK_TYPE,C'22')
Этот ICETOOL выбирает первую запись для каждого значения LINK в LINKS.001. Вопрос в том, ожидает ли оператор SELECT входных данных для сортировки? Если да, его нужно отсортировать по всем полям LINKS.001 (REF_DATE, LINK, LINK_COLL...)?
1 ответ
Я большой поклонник SORT символов /SYMNAMES, так приятно видеть, что вы используете это, и довольно продвинутым способом. Вы указываете только одну начальную позицию для своей записи и связываете все остальное с предыдущим полем, что является наиболее гибким способом сделать это.
Я не знал, что можно использовать точку с запятой, поэтому я изменил ее на запятую. Вы не можете иметь пустую строку (вы можете иметь комментарий, * в первом столбце, а оставшуюся строку оставить пустым).
Я не знаю, почему у вас есть первый шаг, поэтому я пропустил его, пока вы не объясните. Лучший способ использовать SYMNAMES DD - это использовать DSN=, а затем PDS/PDSE с именем участника, тогда ваши карты должны быть внутри участника. Для объяснения я использую DD *.
В вашем файле USING у вас есть контрольные карты SORT, что правильно, но в первом столбце они должны быть пустыми.
OUTREC для OUTFIL устарел, доступен для обратной совместимости, поэтому я изменил его на BUILD (который является синонимом OUTREC для OUTFIL и FIELDS для INREC и OUTREC - посмотрите, насколько менее запутанным является использование только BUILD?).
По умолчанию оператор SELECT ICETOOL сортирует данные по каждому указанному вами полю ON в указанном порядке. Если ваши данные уже находятся в правильной последовательности, вы используете USING (который у вас уже есть в любом случае) и укажите SORT FIELDS=COPY
или же OPTION COPY
там. Ваши данные не будут снова отсортированы.
//S01 EXEC PGM=ICETOOL
//TOOLMSG DD SYSOUT=*
//DFSMSG DD SYSOUT=*
//SYMNAMES DD *
LINK_REC,1,45
LINK_REFDATE,=,8,CH
LINK,*,16,CH
LINK_COLL,*,16,CH
LINK_TYPE,*,3,CH
LINK_LABEL,*,02,CH
LINK_P_LABEL,=,1,CH
LINK_S_LABEL,*,1,CH
//SYMNOUT DD SYSOUT=*
//IN2 DD *
1111111111111111111
1111111111111111111
2222222222222222222
//OU2 DD SYSOUT=*
//TOOLIN DD *
SELECT FROM(IN2) TO(OU2) ON(LINK) FIRST USING(CTL2)
//CTL2CNTL DD *
SORT FIELDS=COPY
OUTFIL FNAMES=OU2,
BUILD=(LINK_REFDATE,
16X,
LINK,
500X,
LINK_TYPE,
C'22')
Выше, с моими простыми тестовыми данными, получается то, что вы хотите. Было несколько других опечаток (без OU2 DD, например), которые я исправил, чтобы он заработал.