Оператор 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, например), которые я исправил, чтобы он заработал.

Другие вопросы по тегам