Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Oracle sql - subtração de data dentro de uma função


Problemas triviais são que você está perdendo um ; quando você define v_depart , e no final da linha você atribui o valor a v_duration; e você está misturando seus nomes de variáveis. (Você também é inconsistente sobre o tipo de car_info.id; você o criou como um varchar quando provavelmente deveria ser um número, mas isso é mais um comentário sobre sua pergunta anterior).

O principal problema é que você não pode executar um sinal de menos em duas cordas, pois isso não significa nada. Você precisa fazer a manipulação das datas originais e descobrir como deseja retornar o resultado ao chamador.

Subtrair uma data de outra dá um valor numérico, que é o número de dias; dias parciais são frações, então 0,25 é 6 horas. Com as datas da sua pergunta anterior, esta consulta:
select arrival, departure, departure - arrival as duration
from car_info
where car_id = 1;

... mostra a duração de 2.125, que é de 2 dias e 3 horas.

Esta não é a melhor maneira de fazer isso, mas para mostrar o processo do que está acontecendo, usarei esse número de duração e o converterei em uma string de maneira bastante prolixa:
CREATE OR REPLACE FUNCTION get_duration (p_car_id number)
RETURN varchar2 is
    v_arrive date;
    v_depart date;
    v_duration number;
    v_days number;
    v_hours number;
    v_minutes number;
    v_seconds number;
BEGIN

    select arrival, departure, departure - arrival
    into v_arrive, v_depart, v_duration
    from car_info
    where car_id = p_car_id;

    -- Days is the whole-number part, which you can get with trunc
    v_days := trunc(v_duration);
    -- Hours, minutes and seconds are extracted from the remainder
    v_hours := trunc(24 * (v_duration - v_days));
    v_minutes := trunc(60 * (v_duration - v_days - (v_hours/24)));
    v_seconds := trunc(60 * (v_duration - v_days - (v_hours/24)
        - (v_minutes/(24*60))));

    return v_days || ' days '
        || to_char(v_hours, '00') || ' hours '
        || to_char(v_minutes, '00') || ' minutes '
        || to_char(v_seconds, '00') || ' seconds';
END;
/

Function created.

show errors

No errors.

select get_duration(1) from dual;

GET_DURATION(1)
--------------------------------------------------------------------------------
2 days  03 hours  00 minutes  00 seconds

Você pode brincar com as máscaras de formato numérico etc. para obter a saída desejada.