Pular para o conteúdo

Fóruns SQL e PL/SQL data timestamp Responder a: data timestamp

#147720
Avatar photoJosé Laurindo Chiappa
Moderador

    Blz ? Então, primeiro de tudo no SGBD Oracle vc NÃO TEM um datatype que contenha só datas, TANTO o DATE QUANTO o TIMESTAMP ou o TIMESTAMP WITH TIME ZONE na verdade SEMPRE contém hora/minuto/segundo (E no caso de timestamp, fração de segundo) – se na hora do INSERT não for especificado valores para hora/min/segundo (e fração, no caso do timestamp) o Oracle vai gravar zero MAS o espaço pra esses dados SEMPRE vai estar presente….
    SEGUNDO, plz EXPLICA melhor o que é esses “parâmetros”, e como vc os passa pra query : por exemplo, se esses “parâmetros” na verdade forem BIND VARIABLEs que vc cria na sua app ou na sua tool de front-end, vc TEM que as converter pro datatype correto : usar simplesmente como string , confiando na conversão implícita, é uma PÉSSIMA IDÉIA, vc VAI cedo ou tarde obter conversões errôneas…..

    Isto posto, é simples : se vc quer comparar apenas a porção dd/mm/yyyy da coluna, OU vc usa as funções de truncagem/arredondamento de valores (como TRUNC) OU, caso a tua BIND VARIABLE seja do tipo string, vc CONVERTE pra timestamp desprezando a porção hh/mm/ss/fração… Meu exemplo :

    => primeiro, ajusto o Formato de Exibição na minha tool de front-end, que é o sqlplus :
    scott@DESENV:SQL>alter session set NLS_TIMESTAMP_FORMAT=’dd/mm/yyyy hh24:mi:ss.FF’;

    Sessão alterada.

    => crio a tabela e insiro alguns dados :

    scott@DESENV:SQL>create table NOTAS(NUM_NOTA number, DT_FATURA timestamp);

    Tabela criada.

    scott@DESENV:SQL>insert into NOTAS values(1, systimestamp-1);

    1 linha criada.

    scott@DESENV:SQL>insert into NOTAS values(2, systimestamp);

    1 linha criada.

    scott@DESENV:SQL>insert into NOTAS values(3, systimestamp);

    1 linha criada.

    scott@DESENV:SQL>select * from notas;

    NUM_NOTA DT_FATURA


         1 25/04/2021 10:43:20,000000
         2 26/04/2021 10:43:37,583000
         3 26/04/2021 10:44:21,114000
    

    => Ok : no MEU caso, a query vai usar como “argumentos” bind variables, que no caso do sqlplus são do tipo string :

    scott@DESENV:SQL>variable V_DT_INI varchar2(10);
    scott@DESENV:SQL>variable V_DT_FIM varchar2(10);
    scott@DESENV:SQL>exec :V_DT_INI := ’26/04/2021′;

    Procedimento PL/SQL concluído com sucesso.

    scott@DESENV:SQL>exec :V_DT_FIM := ’26/04/2021′;

    Procedimento PL/SQL concluído com sucesso.

    scott@DESENV:SQL>print v_dt_ini

    V_DT_INI

    26/04/2021

    scott@DESENV:SQL>print v_dt_fim

    V_DT_FIM

    26/04/2021

    => Aqui é que vem o pulo do gato : NÃO SÓ eu farei a conversão Explícita (usar strings diretamente é SEMPRE arriscado) mas eu TAMBÉM indicarei que ele deve considerar de 0 hora:0minuto:0segundos.0fração até 23h:59m:59s.99999 fração :

    scott@DESENV:SQL>ed
    Gravou file afiedt.buf

    1 select * from NOTAS where dt_fatura
    2 between TO_TIMESTAMP(:V_DT_INI || ‘ 00:00:00.000000’, ‘dd/mm/yyyy hh24:mi:ss.FF’)
    3* and TO_TIMESTAMP(:V_DT_FIM || ‘ 23:59:59.999999’, ‘dd/mm/yyyy hh24:mi:ss.FF’)
    scott@DESENV:SQL>/

    NUM_NOTA DT_FATURA


         2 26/04/2021 10:43:37.583000
         3 26/04/2021 10:44:21.114000
    

    => vou passar um outro dia :

    scott@DESENV:SQL>exec :V_DT_INI := ’25/04/2021′;

    Procedimento PL/SQL concluído com sucesso.

    scott@DESENV:SQL>print v_dt_ini

    V_DT_INI

    25/04/2021

    => vai funcionar perfeitamente, tanto dia inicial quanto o final vai desconsiderar hh/mm/ss.fração, vai pegar todos :

    scott@DESENV:SQL>l
    1 select * from NOTAS where dt_fatura
    2 between TO_TIMESTAMP(:V_DT_INI || ‘ 00:00:00.000000’, ‘dd/mm/yyyy hh24:mi:ss.FF’)
    3* and TO_TIMESTAMP(:V_DT_FIM || ‘ 23:59:59.999999’, ‘dd/mm/yyyy hh24:mi:ss.FF’)
    scott@DESENV:SQL>/

    NUM_NOTA DT_FATURA


         1 25/04/2021 10:43:20.000000
         2 26/04/2021 10:43:37.583000
         3 26/04/2021 10:44:21.114000
    

    scott@DESENV:SQL>

    ==> Ok ??

    Abraços,

    Chiappa