[firebase-br] Stored Procedure para retornar dias úteis entre datas
Eduardo Bahiense
eduardo em icontroller.com.br
Ter Maio 27 03:19:37 -03 2008
A melhor forma de implementar isso é criando uma tabela de calendário.
São 365 registros por ano, muito leve, e você pode ter um campo 'UTIL'
(T/F). tendo isso, fica muto fácil.
SELECT COUNT*) FROM CALENDARIO WHERE IDDATA BETWEEN X AND Y WHERE UTIL='T'
Como hoje estou muito bonzinho, aí vai a estrutura que uso, além de umas
procedures que calculam até carnaval e páscoa
CREATE TABLE YCLD (
IDDATA DEF_DATE NOT NULL /* DEF_DATE = DATE */,
DD SMALL_INT /* SMALL_INT = SMALLINT */,
MM SMALL_INT /* SMALL_INT = SMALLINT */,
YY SMALL_INT /* SMALL_INT = SMALLINT */,
SS SMALL_INT /* SMALL_INT = SMALLINT */,
LTV BOOLF /* BOOLF = VARCHAR(1) DEFAULT 'F' */,
UTIL BOOLF /* BOOLF = VARCHAR(1) DEFAULT 'F' */,
DESCRICAO NOME_MEDIO /* NOME_MEDIO = VARCHAR(40) */
);
/******************************************************************************/
/**** Primary Keys
****/
/******************************************************************************/
ALTER TABLE YCLD ADD CONSTRAINT PK_YCLD PRIMARY KEY (IDDATA);
/******************************************************************************/
/**** Indices
****/
/******************************************************************************/
CREATE INDEX YCLD_IDX1 ON YCLD (YY, MM);
CREATE INDEX YCLD_IDX2 ON YCLD (SS, IDDATA);
CREATE INDEX YCLD_IDX3 ON YCLD (DD, MM, YY);
SET TERM ^ ;
CREATE PROCEDURE FERIADOS (
ANO INTEGER)
AS
DECLARE VARIABLE C INTEGER;
DECLARE VARIABLE I INTEGER;
DECLARE VARIABLE J INTEGER;
DECLARE VARIABLE K INTEGER;
DECLARE VARIABLE L INTEGER;
DECLARE VARIABLE N INTEGER;
DECLARE VARIABLE M INTEGER;
DECLARE VARIABLE D INTEGER;
DECLARE VARIABLE P DATE;
begin
/* Procedure Text */
c = Ano / 100;
n = Ano - 19 * (Ano / 19);
k = (c - 17) / 25;
i = c - (c / 4) - ((c - k) / 3) + (19 * n) + 15;
i = i - 30 * (i / 30);
i = i - (i / 28) * (1 - (1 / 28) * (29 / (i + 1)) * ((21 - n)
/ 11));
j = Ano + (Ano / 4) + i + 2 - c + (c / 4);
j = j - 7 * (j / 7);
L = i - j;
m = 3 + ((L + 40) / 44);
d = L + 28 - 31 * (m / 4);
p = CAST(D||'.'||M||'.'||:ANO AS DATE);
UPDATE YCLD SET UTIL='F', LTV='F', DESCRICAO='Páscoa' WHERE IDDATA=:P;
UPDATE YCLD SET UTIL='F', LTV='F', DESCRICAO='Quarta-Feira de
Cinzas' WHERE IDDATA=:P-46;
UPDATE YCLD SET UTIL='F', LTV='F', DESCRICAO='Carnaval'
WHERE IDDATA=:P-47;
UPDATE YCLD SET UTIL='F', LTV='F', DESCRICAO='Segunda de Carnaval'
WHERE IDDATA=:P-48;
UPDATE YCLD SET UTIL='F', LTV='F', DESCRICAO='Corpus Christi'
WHERE IDDATA=:P+60;
UPDATE YCLD SET UTIL='F', LTV='F', DESCRICAO='Paixão de Cristo'
WHERE IDDATA=:P-2;
UPDATE YCLD SET UTIL='F', LTV='F', DESCRICAO='Confraternização
Universal' WHERE IDDATA='01.01.'||:ANO;
UPDATE YCLD SET UTIL='F', LTV='F', DESCRICAO='Tiradentes'
WHERE IDDATA='21.04.'||:ANO;
UPDATE YCLD SET UTIL='F', LTV='F', DESCRICAO='Dia do trabalhador'
WHERE IDDATA='01.05.'||:ANO;
UPDATE YCLD SET UTIL='F', LTV='F', DESCRICAO='Independência do
Brasil' WHERE IDDATA='07.09.'||:ANO;
UPDATE YCLD SET UTIL='F', LTV='F', DESCRICAO='Nossa Senhora
Aparecida' WHERE IDDATA='12.10.'||:ANO;
UPDATE YCLD SET UTIL='F', LTV='F', DESCRICAO='Finados'
WHERE IDDATA='02.11.'||:ANO;
UPDATE YCLD SET UTIL='F', LTV='F', DESCRICAO='Proclamação da
República' WHERE IDDATA='15.11.'||:ANO;
UPDATE YCLD SET UTIL='F', LTV='F', DESCRICAO='Natal'
WHERE IDDATA='25.12.'||:ANO;
end
^
SET TERM ; ^
GRANT SELECT,UPDATE ON YCLD TO PROCEDURE FERIADOS;
GRANT EXECUTE ON PROCEDURE FERIADOS TO SYSDBA;
SET TERM ^ ;
CREATE PROCEDURE CLD_ANO (
ANO INTEGER)
AS
DECLARE VARIABLE D DATE;
DECLARE VARIABLE DM DATE;
DECLARE VARIABLE SS INTEGER;
DECLARE VARIABLE U CHAR(1);
BEGIN
D = CAST('01.01.'||ANO AS DATE);
DM = CAST('31.12.'||ANO AS DATE);
WHILE (D <= DM) DO
BEGIN
SS = EXTRACT(WEEKDAY FROM :D)+1;
IF (SS IN (1,6)) THEN
U = 'F';
ELSE
U = 'T';
INSERT INTO YCLD (IDDATA,DD,MM,YY,SS,LTV,UTIL) VALUES
(:D,EXTRACT(DAY FROM :D), EXTRACT(MONTH FROM :D), :ANO, :SS,:U,:U);
D = D+1;
END
EXECUTE PROCEDURE FERIADOS(:ANO);
END
^
SET TERM ; ^
GRANT INSERT ON YCLD TO PROCEDURE CLD_ANO;
GRANT EXECUTE ON PROCEDURE FERIADOS TO PROCEDURE CLD_ANO;
GRANT EXECUTE ON PROCEDURE CLD_ANO TO SYSDBA;
Carlos Andrade escreveu:
> Boa tarde! Alguém pode me dizer como seria o código para criar uma SP para
> retornar a quantidade de dias úteis entre duas datas e retirando também os
> feriados que tenho gravado em uma tabela?
>
>
>
> Obrigado pela disponibilidade de todos!!!
>
> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para saber como gerenciar/excluir seu cadastro na lista, use: http://www.firebase.com.br/fb/artigo.php?id=1107
> Para consultar mensagens antigas: http://firebase.com.br/pesquisa
>
Mais detalhes sobre a lista de discussão lista