Системы IBM i (бывшие AS/400) десятилетиями хранят критически важную бизнес-логику в программах на RPG. Старый код на RPG III или раннем RPG IV часто выглядит монолитным: циклы, цепочки к файлам, подпрограммы с EXSR и GOTO. Такой подход работал надежно, но сегодня он усложняет поддержку, интеграцию и привлечение новых разработчиков. Модернизация через переход на современный RPG IV с free-format, subprocedures и embedded SQL делает код модульным, читаемым и эффективным. Многие компании уже прошли этот путь, сохранив стабильность и повысив производительность.
Переход начинается с простого шага - конвертации источника командой CVTRPGSRC. Она переводит RPG III в RPG IV, сохраняя логику, но открывая доступ к новым возможностям. Дальше разработчик вручную очищает код, переводит в free-format и разбивает на модули.
Subprocedures как основа модульности
В старом RPG подпрограммы ограничивались локальными переменными и вызовом через EXSR. Subprocedures в RPG IV меняют подход кардинально. Каждая процедура получает свои параметры, возвращает значения и компилируется в ILE-модули или service programs.
Это позволяет вынести повторяющуюся логику в отдельные процедуры. Например, валидацию данных, расчеты или работу с файлами. Программа превращается в набор вызовов процедур, а не в сплошной цикл.
Технически subprocedure определяется с DCL-PI (интерфейс процедуры) и DCL-PR (прототип), а тело в DCL-PROC и END-PROC. В free-format код выглядит чисто:
dcl-proc CalculateTax export;
dcl-pi *n packed(11:2);
amount packed(11:2) const;
rate packed(5:4) const;
end-pi;
return amount * rate;
end-proc;Лучшие практики рекомендуют:
- Выносить бизнес-правила в service programs для повторного использования.
- Использовать EXPORT для видимых процедур и LOCAL для внутренних.
- Применять CTL-OPT MAIN для линейных программ без цикла.
- Избегать глобальных переменных, передавая все через параметры.
Такой код легче тестировать и отлаживать. Один разработчик отмечал: после разбиения монолитной программы на 20 процедур время поиска ошибок сократилось втрое.
Embedded SQL для современного доступа к данным
Традиционный доступ через CHAIN, READ или SETLL работает, но embedded SQL открывает мощь DB2 напрямую. SELECT, INSERT, UPDATE и DELETE встраиваются в RPG, избавляя от ручного управления индикаторами и цепочками.
В free-format SQL начинается с EXEC SQL и заканчивается точкой с запятой. Прекомпилятор CRTSQLRPGI обрабатывает источник.
Простой пример выборки:
exec sql
SELECT COUNT(*) INTO :count
FROM CUSTOMERS
WHERE STATUS = 'ACTIVE';Для множественных строк используют курсоры:
exec sql DECLARE c1 CURSOR FOR
SELECT ID, NAME, BALANCE
FROM CUSTOMERS
WHERE BALANCE > :threshold;
exec sql OPEN c1;
exec sql FETCH c1 INTO :id, :name, :balance;
dow sqlcod = 0;
// обработка
exec sql FETCH c1 INTO :id, :name, :balance;
enddo;
exec sql CLOSE c1;SQL эффективнее для сложных запросов с JOIN, GROUP BY или подзапросами. Он автоматически оптимизируется планировщиком DB2. Многие заменяют циклы по файлам на один SELECT с INTO массивом для блочной выборки.
Комбинация subprocedures и SQL в модернизации
Настоящая сила раскрывается при совместном использовании. Бизнес-логика разбивается так: главная процедура оркестрирует вызовы, каждая subprocedure выполняет задачу с SQL внутри.
Представьте legacy-программу обработки заказов. Раньше - цикл по файлу заказов, CHAIN к клиентам и товарам, расчеты в подпрограммах.
После модернизации:
- GetCustomerData - процедура с SELECT по ID клиента.
- ValidateOrder - проверка с SQL на наличие товаров.
- CalculateTotal - чистый расчет с возвратом значения.
- UpdateOrder - UPDATE через SQL.
Service program собирает эти процедуры, а главная программа вызывает их по мере надобности.
Один набор преимуществ такой подхода:
- Модульность упрощает unit-тесты
- SQL снижает I/O и ускоряет выполнение
- Free-format повышает читаемость в разы
- ILE позволяет биндинг с другими языками
- Легче интегрировать с веб-сервисами или API
Инструменты вроде RDi или VS Code с Code for i помогают автоматизировать конвертацию в free-format.
Практические наблюдения из реальных проектов
Компании, прошедшие модернизацию, отмечают рост производительности на 20-50% за счет оптимизированных запросов. Код становится понятным даже новичкам, знающим SQL. Один случай: монолит на 10 тысяч строк разбили на 50 процедур - поддержка ускорилась, ошибки уменьшились.
Если задуматься, этот подход не просто обновляет код, а переводит его на современные рельсы. Логика остается той же, но обретает гибкость. Переход требует времени, но окупается быстро - особенно когда нужно добавить новые функции или интегрировать с внешними системами.
Природа IBM i позволяет эволюционировать постепенно: конвертировать по одной программе, тестировать, внедрять. Embedded SQL и subprocedures открывают путь к чистому, эффективному коду, который прослужит еще десятилетия. Стоит ли откладывать? Многие уже увидели разницу и не жалеют о шагах в сторону современного RPG IV.