[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