sql >> Base de Datos >  >> RDS >> Oracle

Oracle sql - resta de fecha dentro de una función

Los problemas triviales son que te falta un ; cuando defines v_depart , y al final de la línea le asignas el valor a v_duration; y estás mezclando los nombres de tus variables. (También es inconsistente sobre el tipo de car_info.id; lo has creado como un varchar cuando probablemente debería ser un número, pero eso es más un comentario sobre su pregunta anterior).

El principal problema es que no puede realizar un menos en dos cadenas, ya que eso realmente no significa nada. Debe realizar la manipulación de las fechas originales y luego averiguar cómo desea devolver el resultado a la persona que llama.

Restar una fecha de otra da un valor numérico, que es el número de días; los días parciales son fracciones, por lo que 0,25 son 6 horas. Con las fechas de su consulta anterior, esta consulta:

select arrival, departure, departure - arrival as duration
from car_info
where car_id = 1;

... muestra una duración de 2.125, que son 2 días y 3 horas.

Esta no es la mejor manera de hacer esto, pero para mostrarle el proceso de lo que está pasando, usaré ese número de duración y lo convertiré en una cadena de forma bastante larga:

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

Puede jugar con las máscaras de formato de número, etc. para obtener el resultado que desea.