Логика управления потоком: детальный разбор параметра COND и конструкций IF/THEN/ELSE/ENDIF
Логика управления потоком: детальный разбор параметра COND и конструкций IF/THEN/ELSE/ENDIF
В мире мейнфреймов редко встречаются задания (Jobs), которые выполняются строго линейно от первого шага до последнего без каких-либо условий. Реальные бизнес-процессы требуют гибкости: если шаг сортировки данных завершился с ошибкой, нет смысла запускать шаг генерации отчета. Если база данных пуста, программу обновления нужно пропустить.
В JCL (Job Control Language) управление потоком выполнения — это критически важный навык. В этой статье мы детально разберем два основных механизма ветвления: классический (и часто запутанный) параметр COND и более современную, читаемую конструкцию IF/THEN/ELSE.
Концепция кодов возврата (Return Codes)
Прежде чем управлять потоком, нужно понять, на чем основываются решения. Любая программа, завершая работу в среде z/OS, возвращает системе числовой код завершения — Return Code (RC). Этот код помещается в регистр 15 процессора при выходе из программы.
Стандартные значения кодов возврата, принятые в индустрии (хотя программист может определить свои):
| Код (RC) | Значение | Описание |
|---|---|---|
| 0000 | OK | Успешное выполнение, ошибок нет. |
| 0004 | WARNING | Предупреждение. Программа отработала, но были незначительные проблемы (например, пустой файл). |
| 0008 | ERROR | Ошибка. Часть данных не обработана или логика нарушена. |
| 0012 | SEVERE | Серьезная ошибка. Выполнение невозможно продолжить корректно. |
| 0016 | TERMINAL | Фатальная ошибка. Аварийное завершение. |
Именно эти числа мы анализируем, чтобы решить: запускать следующий шаг или нет.
Параметр COND: Классический подход
Параметр COND (Condition) — это старейший способ управления выполнением шагов. Его главная особенность, которая сбивает с толку новичков, заключается в обратной логике.
В JCL параметр COND задает условие для ПРОПУСКА (bypass) шага, а не для его выполнения.
Если условие, описанное в COND, истинно (TRUE), то шаг НЕ выполняется.
Синтаксис параметра COND
Параметр может быть указан как на уровне задания (JOB), так и на уровне шага (EXEC).
//STEPNAME EXEC PGM=PROGNAME,COND=(код,оператор,шаг)
Где:
код— числовая константа, с которой мы сравниваем код возврата.оператор— логический оператор сравнения.шаг(опционально) — имя конкретного предыдущего шага, чей код возврата мы проверяем. Если не указано, проверяются коды возврата всех предыдущих шагов.
Операторы сравнения
В JCL используются мнемонические коды для операторов:
- GT (Greater Than) — Больше ()
- GE (Greater or Equal) — Больше или равно ()
- EQ (Equal) — Равно ()
- NE (Not Equal) — Не равно ()
- LT (Less Than) — Меньше ()
- LE (Less or Equal) — Меньше или равно ()
Формула проверки условия
Чтобы понять, будет ли пропущен шаг, система проверяет следующее неравенство:
Где — это константа, указанная вами в JCL, — оператор сравнения (GT, LT и т.д.), а — реальный код возврата (Return Code) предыдущего шага.
Если это выражение истинно — шаг пропускается.
Примеры и разбор логики
Рассмотрим самый частый пример. Мы хотим запустить шаг STEP2 только если STEP1 завершился успешно (RC=0).
Неправильная логика (как думают новички): "Запустить, если RC равно 0". Правильная логика JCL (COND): "Пропустить, если RC не равно 0".
Код:
//STEP1 EXEC PGM=PROG1
//STEP2 EXEC PGM=PROG2,COND=(0,NE,STEP1)
Разберем COND=(0,NE,STEP1):
- Константа: 0
- Оператор: NE (не равно)
- Проверка:
Если STEP1 вернул 4 (Warning):
— это Истина (True). Результат: STEP2 пропускается.
Если STEP1 вернул 0 (OK):
— это Ложь (False). Результат: STEP2 выполняется.
Еще примеры:
COND=(4,LT): Пропустить, если 4 меньше RC (то есть, если RC > 4). Это означает: "Выполнять только если RC <= 4" (допускаем 0 и 4).COND=(0,EQ): Пропустить, если 0 равно RC. Это означает: "Выполнять только если RC не равно 0" (обычно используется для обработки ошибок).
Специальные параметры: EVEN и ONLY
Существуют два особых значения для COND, которые меняют поведение при аварийном завершении (ABEND) предыдущих шагов.
- COND=EVEN: Шаг выполняется, даже если предыдущий шаг завершился аварийно (ABEND). Обычно используется для шагов очистки (cleanup).
- COND=ONLY: Шаг выполняется только если предыдущий шаг завершился аварийно.
Пример комбинирования:
//STEP3 EXEC PGM=CLEANUP,COND=((4,LT,STEP1),EVEN)
Здесь STEP3 запустится, даже если был ABEND, НО также будет проверено условие 4 < RC от STEP1. Если условие истинно, шаг все равно будет пропущен, несмотря на EVEN.
Конструкция IF/THEN/ELSE/ENDIF
Введенная позже для упрощения жизни системных программистов, конструкция IF/THEN/ELSE работает по привычной для всех логике: "Если условие истинно — ВЫПОЛНИТЬ".
Синтаксис
// IF (логическое_выражение) THEN
//STEPNAME EXEC PGM=...
// ELSE
//STEPNAME2 EXEC PGM=...
// ENDIF
Ключевые отличия от COND
- Прямая логика:
IF (RC = 0)значит "Делай, если 0". - Читаемость: Код гораздо понятнее для сопровождения.
- Гибкость: Поддержка сложных логических выражений с
AND,OR,NOT.
Операторы в IF
Можно использовать как мнемоники (GT, EQ), так и символы:
>(GT)<(LT)=(EQ)!=или¬=(NE)>=(GE)<=(LE)
Также используются логические связки:
&илиAND|илиOR¬илиNOT
Примеры использования
Пример 1: Простая последовательность
Запустить STEP2, только если STEP1 завершился успешно (RC=0).
//STEP1 EXEC PGM=PROG1
// IF (STEP1.RC = 0) THEN
//STEP2 EXEC PGM=PROG2
// ENDIF
Пример 2: Сложное условие
Запустить STEP3, если STEP1 прошел без ошибок, ИЛИ если STEP2 вернул Warning (RC=4).
// IF (STEP1.RC = 0 | STEP2.RC = 4) THEN
//STEP3 EXEC PGM=PROG3
// ENDIF
Пример 3: Проверка ABEND
Конструкция IF также позволяет проверять на аварийное завершение с помощью ключевых слов ABEND и ABENDCC.
// IF (ABEND) THEN
//ERROR EXEC PGM=NOTIFY
// ENDIF
Сравнение COND и IF/THEN
Давайте сравним реализацию одной и той же логики: "Выполнить STEP2, только если RC STEP1 меньше или равен 4".
Вариант с COND: Нам нужно условие для пропуска. Если мы хотим выполнять при , значит, пропускать нужно при . В терминах COND (): .
//STEP2 EXEC PGM=MYPROG,COND=(4,LT,STEP1)
Вариант с IF: Пишем условие для выполнения.
// IF (STEP1.RC <= 4) THEN
//STEP2 EXEC PGM=MYPROG
// ENDIF
Очевидно, что вариант с IF воспринимается человеком быстрее и с меньшей вероятностью ошибки.
Лучшие практики
- Используйте IF/THEN для нового кода. Это стандарт де-факто для современной разработки на z/OS. Это снижает порог входа для новых сотрудников.
- Понимайте COND для поддержки легаси. Огромное количество JCL, написанного 20-30 лет назад, использует
COND. Вы обязаны уметь читать его "на лету". - Осторожнее с COND на уровне JOB. Если вы напишете
COND=(4,LT)в первой строке//JOB, это условие будет применяться ко всем шагам. Если любой шаг вернет RC > 4, все последующие шаги будут пропущены. - Проверяйте синтаксис. В
IFобязательно наличиеENDIF. Отсутствие закрывающего тега приведет к JCL Error.
Заключение
Управление потоком — это то, что превращает набор команд в интеллектуальный сценарий. Понимание "обратной" логики COND отличает новичка от профессионала, а умелое использование IF/THEN делает ваши скрипты надежными и читаемыми. В следующей статье мы рассмотрим работу с процедурами (PROC), где эти знания пригодятся для создания переиспользуемых шаблонов.