Oracle
 sql >> Database >  >> RDS >> Oracle

Oracle sql - sottrazione della data all'interno di una funzione

I problemi banali sono che ti manca un ; quando definisci v_depart , e alla fine della riga assegni il valore a v_duration; e stai confondendo i nomi delle variabili. (Sei incoerente anche sul tipo di car_info.id; l'hai creato come varchar quando probabilmente dovrebbe essere un numero, ma è più un commento alla tua domanda precedente).

Il problema principale è che non puoi eseguire un meno su due stringhe, poiché in realtà non significa nulla. Devi fare la manipolazione delle date originali e poi capire come vuoi restituire il risultato al chiamante.

Sottraendo una data da un'altra si ottiene un valore numerico, che è il numero di giorni; i giorni parziali sono frazioni, quindi 0,25 è 6 ore. Con le date della tua domanda precedente, questa query:

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

... mostra la durata di 2.125, ovvero 2 giorni e 3 ore.

Questo non è il modo migliore per farlo, ma per mostrarti il ​​processo di cosa sta succedendo userò quel numero di durata e lo convertirò in una stringa in un modo piuttosto prolisso:

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

Puoi giocare con le maschere di formato numerico ecc. per ottenere l'output che desideri.