Бывают случаи, когда использование возможностей DB2 для оперирования с датами либо затруднено, либо просто невозможно.
Вот тогда и приходится решать данные задачи исключительно средствами PL/I.
Один из простых примеров - имеется задача вычитания 1 месяца из даты в формате DD-MM-YYYY.
Давайте напишем процедуру, которая будет выполнять данную операцию:
SUB_MONTH: PROC(DAT_IN) RETURNS (CHAR(10)); DCL DAT_IN CHAR (10) ; DCL 1 IN_S BASED (ADDR (DAT_IN) ), 3 DD CHAR (02), 3 S1 CHAR (01), 3 MM CHAR (02), 3 S2 CHAR (01), 3 CC CHAR (02), 3 YY CHAR (02); IF IN_S.MM = '01' THEN DO; IN_S.MM = '12'; IN_S.YY = IN_S.YY - 1; END; ELSE DO; IN_S.MM = IN_S.MM - 1; END; RETURN (DAT_IN); END;
Использование переменных минимизировано, так и использование преобразований типа. Функции по преобразованию переменных типа CHAR в DECIMAL возложены на плечи компилятора =) Если версия компилятора не поддерживает, то следует вводить нове переменные типа PIC'99' для оперирования с месяцем и годом.
Как Вы видете, я возвращаю тут же переменную, что и было получена в виде параметра. А это значит, что передачу параметров следует выполнять по значению, а не по указателю.
Т.е. вызов процедуры следует производить таким образом:
NEW_DATE = SUB_MONTH( (OLD_DATE) );
Обратите на экранирование переменной в "( )", что препятствует ее модификации внутри процедуры.
Процедуру добавления месяца к дате можно организовать аналогичным образом:
ADD_MONTH: PROC(DAT_IN) RETURNS (CHAR(10)); DCL DAT_IN CHAR (10) ; DCL 1 IN_S BASED (ADDR (DAT_IN) ), 3 DD CHAR (02), 3 S1 CHAR (01), 3 MM CHAR (02), 3 S2 CHAR (01), 3 CC CHAR (02), 3 YY CHAR (02); IF IN_S.MM = '12' THEN DO; IN_S.MM = '01'; IN_S.YY = IN_S.YY + 1; END; ELSE DO; IN_S.MM = IN_S.MM + 1; END; RETURN (DAT_IN); END;
Отправить комментарий