Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle SQL - Datumssubtraktion innerhalb einer Funktion

Triviale Probleme sind, dass Ihnen ein ; fehlt wenn Sie v_depart definieren , und am Ende der Zeile weisen Sie v_duration den Wert zu; und Sie verwechseln Ihre Variablennamen. (Sie sind auch in Bezug auf den Typ von car_info.id uneinheitlich; Sie haben es als varchar erstellt obwohl es wahrscheinlich eine Zahl sein sollte, aber das ist eher ein Kommentar zu Ihrer vorherigen Frage).

Das Hauptproblem ist, dass Sie kein Minus auf zwei Saiten ausführen können, da dies nicht wirklich etwas bedeutet. Sie müssen die ursprünglichen Daten manipulieren und dann herausfinden, wie Sie das Ergebnis an den Aufrufer zurückgeben möchten.

Das Subtrahieren eines Datums von einem anderen ergibt einen Zahlenwert, der die Anzahl der Tage darstellt; Teiltage sind Brüche, also sind 0,25 6 Stunden. Mit den Daten aus Ihrer vorherigen Frage, dieser Abfrage:

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

... zeigt eine Dauer von 2,125, was 2 Tagen und 3 Stunden entspricht.

Dies ist nicht der beste Weg, dies zu tun, aber um Ihnen den Vorgang zu zeigen, was vor sich geht, verwende ich diese Dauerzahl und wandle sie auf ziemlich umständliche Weise in einen String um:

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

Sie können mit den Zahlenformatmasken usw. spielen, um die gewünschte Ausgabe zu erhalten.