Oracle sql - 函数内的日期减法

时间:2012-03-02 12:51:37

标签: sql oracle date time subtraction

(从上一篇文章转移) - 抱歉,如果这被视为重复! 嗨,大家好, 只是在日期计算中遇到一些问题并从函数中的日期中减去。

我对我应该使用的数据类型感到困惑,因为我必须从日期转换为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无效

任何关于此的输入都会被大大收到,

如果帖子比较大,很抱歉!

的问候,

的Darren

3 个答案:

答案 0 :(得分:2)

DATE算法适用于不在VARCHAR2上的DATE:

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 :(得分:2)

琐碎的问题是,当您定义;时,您错过了v_depart,并且在该行的末尾您将值分配给v_duration;而你正在混淆你的变量名称。 (你对car_info.id的类型也不一致;当它可能应该是一个数字时你已经创建它为varchar,但这更像是对你前一个问题的评论。) / p>

主要问题是你不能对两个字符串执行减号,因为这并不意味着什么。您需要对原始日期进行操作,然后确定如何将结果返回给调用者。

从另一个日期中减去一个日期会给出一个数字值,即天数;部分天是分数,所以0.25是6小时。使用上一个问题的日期,此查询:

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

您可以使用数字格式蒙版等来获得所需的输出。

答案 2 :(得分:0)

一旦将日期转换为varchar2,你不能减去日期(to_char函数会这样做!)。而是使用v_duration := v_stop - v_start;,它会在几天内为您提供结果'v_duration'。然后你可以把它转换成小时,分钟等。