Деление умножения с использованием утилиты DFSORT в мейнфрейме

Есть два файла FILE1.DATA и FILE2.DATA. Для расчета процента (количество записей в FILE1 / количество записей в FILE2) * 100 с использованием DFSORT в мейнфрейме. И установка кода возврата, если он пересекает порог (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)                                                
//*                                                                  
  1. Проблема, с которой я столкнулся, заключается в том, что наборы данных FILE1.DATA.COUNT и FILE1.DATA.COUNT создаются длиной 15 записей, несмотря на упоминание LRECL 6. (обратите внимание, это был вопрос, который существовал, когда был написан первый ответ, и сейчас не относится к приведенному выше коду).
  2. Можем ли мы объединить оба шага в один?
  3. Что конкретно это, (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)), означает?

person deepaklearner    schedule 31.01.2017    source источник
comment
Предположительно ваши файлы довольно большие? Это сделает весь процесс неэффективным. Возьмите подсчеты из чего-то, что уже считывает данные, и тогда у вас будет что-то действительно простое и эффективное. Каковы RECFM и LRECL ваших входов? Вы читали документацию COUNT (нет, это ответ, так что читайте)?   -  person Bill Woodger    schedule 31.01.2017
comment
@Bill Мои оба входных файла содержат около 10000 записей.   -  person deepaklearner    schedule 31.01.2017
comment
Я добавил ЦИФРЫ (6) на шаге 001 и изменил ниже OUTFIL FNAMES=SETRC,NULLOFL=RC4,INCLUDE=(23,6,CH,GT,C'090.00'). Теперь он работает нормально.   -  person deepaklearner    schedule 01.02.2017
comment
Занимательный. Ваш комментарий должен был появиться, когда я писал ответ. Прочтите ответ, пожалуйста.   -  person Bill Woodger    schedule 01.02.2017
comment
Большое спасибо, Билл. Я просмотрю твой ответ,   -  person deepaklearner    schedule 01.02.2017
comment
@Bill Я неправильно понял приведенный ниже код: 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))   -  person deepaklearner    schedule 01.02.2017


Ответы (1)


Ответ на ваш первый вопрос заключается в том, что вы просто не сказали оператору COUNT ICETOOL, какой длины должны быть выходные данные, поэтому он придумал свою собственную цифру.

Это из Руководства по программированию приложений DFSORT:

WRITE(countdd) Определяет ddname набора данных счетчика, который будет создан ICETOOL для этой операции. Должен присутствовать оператор countdd DD. ICETOOL устанавливает атрибуты набора данных счетчика следующим образом:

v Для RECFM установлено значение FB.

v Для LRECL задано одно из следующих значений:

– Если указан WIDTH(n), LRECL устанавливается равным n. Используйте WIDTH(n), если длина записи счетчика и LRECL должны быть установлены на определенное значение (например, 80) или если вы хотите, чтобы длина записи счетчика не превышала определенного максимума (например, 20 байтов). .

– Если WIDTH(n) не указан, LRECL устанавливается равным расчетной требуемой длине записи. Если для вашего LRECL не нужно устанавливать конкретное значение, вы можете позволить ICETOOL определить и установить соответствующее значение LRECL, не указывая WIDTH(n).

А также:

ЦИФРЫ (г)

Указывает d цифр для количества в выходной записи, переопределяя 15 цифр по умолчанию. d может принимать значения от 1 до 15. Число записывается в виде d десятичных цифр с ведущими нулями. DIGITS можно указать, только если указано WRITE(countdd).

Если вы знаете, что для вашего подсчета требуется менее 15 цифр, вы можете вместо этого использовать меньшее количество цифр (d), указав DIGITS(d). Например, если указано DIGITS(10), вместо 15 используются 10 цифр.

Если вы используете DIGITS(d) и счетчик превышает количество используемых цифр, ICETOOL завершает операцию. Вы можете предотвратить переполнение, указав более высокое значение d для DIGITS(d). Например, если DIGITS(5) приводит к переполнению, вместо него можно использовать DIGITS(6).

А также:

ШИРИНА (n)

Указывает длину записи и LRECL, которые ICETOOL должен использовать для набора данных счетчика. 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 равным расчетной длине записи.

Используйте WIDTH(n), если длина записи счетчика и LRECL должны быть установлены на определенное значение (например, 80) или если вы хотите, чтобы длина записи счетчика не превышала определенного максимума (например, 20 байтов). . В противном случае вы можете позволить ICETOOL вычислить и установить соответствующую длину записи и LRECL, не указывая WIDTH(n).

Что касается вашего второго вопроса, да, это можно сделать за один шаг и значительно упростить.

Дело в том, что его можно еще больше упростить, сделав что-то еще. Что именно еще зависит от вашей реальной задачи, чего мы не знаем, мы знаем только решение, которое вы выбрали для своей задачи.

Например, вы хотите знать, когда один файл находится в пределах 10% от размера другого. Один из способов, если точная точность не требуется, — это поговорить с техническим персоналом, который управляет вашим хранилищем. Скажите им, что вы хотите сделать, и, возможно, у них уже есть что-то, с чем вы можете это сделать (при обсуждении этого имейте в виду, что технически это наборы данных, а не файлы).

Кроме того, кто-то уже ранее читал или записывал эти файлы. Если последняя программа, которая сделала это, еще не производит подсчет того, что она прочитала/записала (на мой взгляд, стандартная хорошая практика, при этом программа также выполняет согласование), тогда измените программы, чтобы сделать это сейчас. Там. Магия. У вас есть свои счета.

Организуйте, чтобы эти подсчеты находились в собственном наборе данных (желательно с типами записей, заголовками/конечниками, более стандартной хорошей практикой).

Один шаг, чтобы сделать большее (ожидание) из двух значений, «вычислить», что будет 00% (не нужно ничего, кроме простого вычитания с правильными данными) и создать файл формата SYMNAMES (фиксированная длина 80 -байтовые записи) с символом SORT для константы с этим значением.

Второй шаг, который использует INCLUDE/OMIT с символом по сравнению со вторым счетчиком записей, используя NULLOUT или NULLOFL.

Преимущество вышеупомянутых типов решений заключается в том, что они в основном используют очень мало ресурсов. На мейнфрейме клиент платит за ресурсы. Ваш клиент может быть не так счастлив в конце года, обнаружив, что он заплатил за чтение и «подсчет» 7,3 млн записей только для того, чтобы вы могли установить RC.

Ладно, может быть, 7,3 млн — это не так уж и много, но когда у вас есть «решение», следующий человек сделает это со 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 — это divde.

+2 — числовая константа.

1,6,ZD,DIV,+2 означает «взять шестизначное число, начинающееся с первой позиции, и разделить его на два, получив «результат», который будет помещен в следующую доступную позицию (16 в вашем случае) .

M11 — это встроенная маска редактирования. Подробную информацию о том, что это за маска, можно найти в руководстве, так как в то же время вы обнаружите другие полезные предопределенные маски. Используйте это для форматирования результата.

LENGTH=6 ограничивает результат шестью цифрами.

До сих пор число в первых шести позициях будет делиться на два и обрабатываться (по маске) ​​как беззнаковое зональное десятичное число из шести цифр, начиная с позиции 16.

Остальные элементы утверждения аналогичны. Скобки влияют на «приоритет» числовых операторов обычным образом (обратитесь к руководству, чтобы ознакомиться с правилами приоритета).

РЕДАКТИРОВАТЬ=(ТТТ.ТТ) — это используемая определенная маска редактирования, в данном случае вставка десятичной точки, усечение существующей в противном случае крайней левой цифры и при необходимости наличие значащих начальных нулей.

person Bill Woodger    schedule 31.01.2017