Бывают случаи, когда использование возможностей 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;
Off White X Max 180-90
Отправить комментарий