Nesse artigo vou mostrar uma forma simples de como criar uma stored procedure para retornar o próximo dia útil de uma data desconsiderando feriados pré cadastrados. O objetivo dessa procedure é verificar se a data informada no parâmetro é sábado, domingo ou feriado e caso seja irá retornar o próximo dia útil.
Lembrando que utilizei a versão 1.5 do Firebird para fazer este artigo.
Esse exemplo armazena os feriados como tipo DATE, e com isso será necessário atualizar os feriados anualmente, porém pode-se armazenar somente o dia e mês do feriado em campos separados e com isso eliminar essa atualização anual da tabela de feriados.
Mas voltado ao artigo, o primeiro passo é criar uma tabela para armazenar as datas dos feriados anuais e suas respectivas descrições. Segue a estrutura dessa tabela a seguir:
--tabela de feriados
CREATE TABLE FERIADOS
(
DT DATE NOT NULL,
DES VARCHAR(30)
)
Agora vamos criar nossa stored procedure:
CREATE PROCEDURE SP_PROXIMO_DIAUTIL
(
PI_DATA DATE
)
RETURNS
(
PO_DATA DATE
)
AS
DECLARE VARIABLE VDATA DATE;
DECLARE VARIABLE VDAY INTEGER;
DECLARE VARIABLE VNEWDAY INTEGER;
DECLARE VARIABLE I INTEGER;
DECLARE VARIABLE J INTEGER;
DECLARE VARIABLE VOK INTEGER;
BEGIN
--pega o dia da semana
SELECT EXTRACT(WEEKDAY FROM :PI_DATA) FROM RDB$DATABASE INTO :VDAY;
--se for sexta incrementa dois dias
IF (VDAY=6) THEN
VDATA = PI_DATA+2;
--se for domingo incrementa um dia
ELSE IF (VDAY=0) THEN
VDATA = PI_DATA+1;
--caso contrário não incrementa nada
ELSE
VDATA = PI_DATA;
--verifica se a data é um feriado
SELECT COALESCE(COUNT(*),0) FROM FERIADOS F WHERE F.DT = :VDATA INTO :I;
--se for incrementa ate que a data não seja feriado e seja um dia util
IF (I>0) THEN
BEGIN
VDATA = VDATA+1;
VOK = 0;
WHILE (VOK=0) DO
BEGIN
SELECT COALESCE(COUNT(*), 0) FROM FERIADOS F WHERE F.DT = :VDATA INTO :J;
IF (J>0) THEN
VDATA = VDATA+1;
ELSE BEGIN
SELECT EXTRACT(WEEKDAY FROM :VDATA) FROM RDB$DATABASE INTO :VNEWDAY;
IF (VNEWDAY=6) THEN
VDATA = VDATA+2;
ELSE IF (VNEWDAY=0) THEN
VDATA = VDATA+1;
ELSE
VOK = 1;
END
END
END
PO_DATA = VDATA;
SUSPEND;
END;
Espero que tenham gostado e até o próximo artigo.