2012-03-02 76 views
0

(從前一篇文章移除) - 抱歉,如果這被看作是重複! 大家好, 只是有一些問題與日期計算和從功能中的日期減去。Oracle sql - 函數內的日期減法

我很困惑我應該使用的數據類型,因爲我不得不從日期to_char轉換爲例如。我不確定是否將返回類型設置爲varchar2或date?

這裏是接收car_id,看起來在表中那部車,翻出車到達日期,並將其存儲在變量

一個日期與日期,相同的功能。

然後將兩個日期轉換爲to_char,進行相減並將其返回到varchar2中。

當我調用函數時,它會輸入car_id作爲參數, 然後將返回的結果存儲在varchar變量中,以用於dbms輸出。 例如。

v_result := get_duration('0001') 

這裏是功能:

DROP FUNCTION get_duration; 
CREATE FUNCTION get_duration (p_car_id number) 
RETURN varchar2 is 
v_arrive date; 
v_depart date 
v_duration varchar2(25); --not too sure about this variable choice 

begin 

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

v_duration := to_char(v_depart, 'dd-mon-yyyy hh24:mi:ss') - to_char(v_arrive, 'dd-mon-yyyy hh24:mi:ss') 
return v_duration; 
END; 
/

正如你所看到的,我試圖把開始和結束時間從表中的變量,然後減去從一開始就結束日期日期。

功能編譯,但有一個警告,當我要調用的函數,錯誤:get_duration無效

任何對此的投入將極大地好評,

很抱歉,如果該職位是比較大!

問候,

達倫

+0

當'v_stop'和'v_start'沒有聲明時它是如何編譯的? – Ollie 2012-03-02 12:56:56

+1

@Ollie - '警告:使用編譯錯誤創建函數。「* 8- 8-)。在前面的Q中,我建議提供'show errors'的輸出,無論如何都會首先標記缺失的';'。 – 2012-03-02 13:35:50

回答

2

瑣碎的問題是,你缺少一個;當你定義v_depart,並且在該行的末尾,你的值賦給v_duration;你正在混合你的變量名稱。 (您對car_info.id的類型也不一致;您可能將它創建爲varchar,因爲它可能應該是一個數字,但這更像是對您以前的問題的評論)。

主要問題是您不能對兩個字符串執行減號,因爲這並不意味着什麼。您需要對原始日期進行操作,然後弄清楚如何將結果返回給調用者。

從另一個日期減去一個日期給出一個數字值,這是天數;部分日子是分數,所以0.25是6個小時。與以前的quesiton的日期,這個查詢:

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

...顯示的2.125,也就是2天3小時的時間。

這不是做到這一點的最好辦法,但給你看這是怎麼回事,我會使用持續時間號,並將其轉換成字符串在相當長氣路的過程:

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 

你可以使用數字格式掩碼等來獲得你想要的輸出。

+0

+1,用於小時,分鐘,秒等的輸出。 – Ollie 2012-03-02 13:22:44

+0

哇!謝謝你爲我付出這麼大的努力,這將是非常非常有用的!優秀的答案,再次感謝 – DarrenJ65 2012-03-02 13:42:35

2

日期運算工作的日期不是的varchar2:

CREATE FUNCTION get_duration (p_car_id number) 
RETURN varchar2 is 
v_arrive date; 
v_depart date 
v_duration number; --<<< 

begin 

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

v_duration := v_arrive - v_depart; 
return v_duration; 
END; 

這給在天的結果。

+1

你可能想用'v_arrive'和'v_depart'替換'v_stop'和'v_start'來編譯(並將返回類型改爲'NUMBER')。 – Ollie 2012-03-02 13:00:10

+0

@Ollie,謝謝! – 2012-03-02 13:01:46

+0

對不起,這是打字錯誤,我被另一個項目弄糊塗了!在我的實際代碼中,它不是這樣的 – DarrenJ65 2012-03-02 13:03:45

0

不能一旦你將它們轉換成varchar2(to_char函數做到這一點!)就減去日期。而是使用v_duration := v_stop - v_start;,這會在幾天內爲您提供結果'v_duration'。然後,你可以將其轉換爲小時,分鐘等。