- Este tópico contém 4 respostas, 4 vozes e foi atualizado pela última vez 15 anos, 8 meses atrás por
leo_jf.
-
AutorPosts
-
7 de julho de 2010 às 7:00 am #94967
leo_jf
ParticipanteSenhores,
aproveitando as duvidas, alguém saberia me responder como procedo no seguinte caso:
Hr_saida Hr_entrada Total
23:00 15:00 8
08:00 07:00 1
07:00 23:00 -16?????????????Obs: Ambos campos são (ambos varchar2(5))
A coluna total é buscada através de um select. Para chegar a esse resultado, usei um “POG” rsrs da vida, que é SUBSTR das primeiras posições(entrada) menos substr das ultimas(saida) /60.
O problema que quando tenho a hora da saida maior do que a entrada gero um valor errado.
Teoricamente o select mostra que, no primeiro caso, o func. entrou na empresa as 15:00 e saiu às 23:00, fazendo 8 horas de trabalho.
Entretanto no caso do func. entrar 23:00 e sair às 07:00 dá um erro!!!!
p.s (o que leva um func. a entrar 23:00 em uma empresa, e sair 07:00? rsrs mas enfim).Alguém teria uma dica?
Através de variaveis consegue chegar a um resultado correto, mas tive que usar no pl/sql. Através de uma query não teria uma forma mais simples?Existe alguma função, atualmente, para trabalharmos com horas?[/code]
7 de julho de 2010 às 6:40 pm #94970Ishii
ParticipanteOlá,
Leo, se você tiver como adicionar a data para que esteja no formato do Oracle dd-mon-yyyy hh24:mi:ss ou outra parecida. Então você poderá usar o
extract hour day to second…Um exemplo vale mais que mil explicações:
create table TIME_SHEET_TEST
(
ID_TM NUMBER,
ENTRADA DATE,
SAIDA DATE,
INTERVALO NUMBER
);insert into time_sheet_test
values
(1,to_date('06-jul-2010 22:00:00','dd-mon-yyyy hh24:mi:ss'), to_date('07-jul-2010 07:00:00','dd-mon-yyyy hh24:mi:ss'), null);
Então o uso do extract
select t.entrada, t.saida, extract(hour from (t.saida - t.entrada) day to second) intervalo,
extract(minute from (t.saida - t.entrada) day to second) intervalo_min,
round(extract(minute from (t.saida - t.entrada) day to second)/60,2) intervalo_min_ajus
from time_sheet_test tNote que a primeira coluna intervalo sempre vai trazer a quantidade em horas e a segunda em minutos, para ajustar utilize a lógica da terceira coluna (afinal 30 minutos é 0,5 hora).
A lógica vale para triggers também.
create or replace trigger TR_E_B_TIMESHEET
before insert or update on time_sheet_testfor each row
-- Trigger de calculo de intervalo
begin
:new.intervalo := extract(hour from (:new.saida - :new.entrada) day to second) + round(extract(minute from (:new.saida - :new.entrada) day to second)/60,2);
end TR_E_B_TIMESHEET;
Boa sorte!!!
[]s Ishii
7 de julho de 2010 às 11:26 pm #94977burga
ParticipanteDá pra fazer usando case também, com a função to_date e mais alguns cálculos:
WITH TABELA AS (
SELECT '23:00' HR_SAIDA,'15:00' HR_ENTRADA FROM DUAL
UNION ALL
SELECT '08:00','07:00' FROM DUAL
UNION ALL
SELECT '07:00','23:00' FROM DUAL
UNION ALL
SELECT '07:00','07:00' FROM DUAL)
SELECT HR_SAIDA, HR_ENTRADA,
CASE
WHEN TO_DATE(HR_SAIDA,'HH24:MI') >= TO_DATE(HR_ENTRADA,'HH24:MI')
THEN (TO_DATE(HR_SAIDA,'HH24:MI')-TO_DATE(HR_ENTRADA,'HH24:MI'))24
ELSE
(TRUNC(TO_DATE(HR_ENTRADA,'HH24:MI'),'MONTH')+1-TO_DATE(HR_ENTRADA,'HH24:MI')
+(TO_DATE(HR_SAIDA,'HH24:MI')-TRUNC(TO_DATE(HR_ENTRADA,'HH24:MI'),'MONTH')))24
END TOTAL
FROM TABELA;HR_SAIDA HR_ENTRADA TOTAL
--------|----------|----------------------
23:00 15:00 8
08:00 07:00 1
07:00 23:00 8
07:00 07:00 08 de julho de 2010 às 3:52 am #94979fsitja
ParticipanteGuardar datas e/ou horas como varchar2 é muito ruim… principalmente porque é muito difícil validar a consistência dos dados. Não se surpreenda se encontrar horários inválidos, maior que 24 horas ou coisas absurdas.
O correto seria armazenar os horários como tipo DATE, contendo o dia + a hora, que é o padrão para Date. Aí seria muito fácil, só fazer um menos o outro e jogar numa variável number.
8 de julho de 2010 às 6:03 am #94980leo_jf
ParticipanteBoa Noite para todos,
Obrigado pelas dicas.
Usei a dica do burga, e ajudou bastante, pois reduziu bastante meu código.Alguém precisando, só dizer.
Vlw mais uma vez, burga!
-
AutorPosts
- Você deve fazer login para responder a este tópico.