2008-09-04 67 views
5

我们现在使用NHibernate连接到安装软件的不同数据库。所以我将许多SQL程序移植到Oracle。Oracle相当于SQL Server/Sybase DateDiff

SQL Server有一个很好的叫做DateDiff的函数,它使用日期部分,开始日期和结束日期。

日期部件的例子是日,周,月,年等。 。

什么是Oracle等价物?

我还没有找到我需要创建自己的版本吗?

(由Mark Harrison更新)有几个很好的答案可以解释Oracle日期算法。如果你需要一个Oracle的日期(见)爱因斯坦的答案。 (我需要这样做才能保持sybase和Oracle之间spme SQL脚本兼容。)请注意,这个问题同样适用于Sybase。

+0

看看这里:(如果此链接仍然被破坏,请使用下面的链接) http://asktom.oracle.com/pls/asktom/ASKTOM.download_file?p_file=6551242712657900129 – 2008-09-04 14:09:52

回答

1

汤姆的文章很旧。它只讨论DATE类型。如果您使用TIMESTAMP类型,则日期算法将内置到PL/SQL中。

http://www.akadia.com/services/ora_date_time.html

DECLARE 
ts_a timestamp; 
ts_b timestamp; 
diff interval day to second; 
BEGIN 
    ts_a := systimestamp; 
    ts_b := systimestamp-1/24; 
    diff := ts_a - ts_b; 
    dbms_output.put_line(diff); 
END; 
+00 01:00:00.462000 

DECLARE 
ts_b timestamp; 
ts_a timestamp; 
date_part interval day to second; 

BEGIN 
    ts_a := systimestamp; 
    date_part := to_dsinterval('0 01:23:45.678'); 
    ts_b := ts_a + date_part; 
    dbms_output.put_line(ts_b); 
END; 

04-SEP-08 05.00.38.108000 PM 
4

JohnLavoie - 你不需要这样。 Oracle中的DATE实际上是日期和时间数据类型。 DATE和TIMESTAMP之间的唯一区别是DATE解析为秒,但TIMESTAMP解析为微秒。因此,Ask Tom文章对于TIMESTAMP列也是完全有效的。

4

几年前,我从一篇老汤姆的文章中偷走了大部分内容,修复了文章中的一些bug并将其清理干净。用于datediff的分界线在oracle和MSSQL之间的计算方式是不同的,所以你必须小心一些浮动的例子,这些例子没有正确考虑不提供分数结果的MSSQL/Sybase样式边界。

使用以下命令应该可以使用MSSQL语法并获得与MSSQL相同的结果,如SELECT DATEDIFF(dd,getdate(),DATEADD(dd,5,getdate()))FROM DUAL;

我只是声称它的工作原理 - 不是它的有效性或最好的方法。我不是甲骨文的人:)而且你可能想要考虑使用我的函数宏来解决需要dd,mm,hh,mi..etc引号的解决方法。

(由Mark Harrison更新)添加了dy函数作为dd的别名。

CREATE OR REPLACE FUNCTION GetDate 
RETURN date IS today date; 
BEGIN 
RETURN(sysdate); 
END; 
/

CREATE OR REPLACE FUNCTION mm RETURN VARCHAR2 IS BEGIN RETURN('mm'); END; 
/
CREATE OR REPLACE FUNCTION yy RETURN VARCHAR2 IS BEGIN RETURN('yyyy'); END; 
/
CREATE OR REPLACE FUNCTION dd RETURN VARCHAR2 IS BEGIN RETURN('dd'); END; 
/
CREATE OR REPLACE FUNCTION dy RETURN VARCHAR2 IS BEGIN RETURN('dd'); END; 
/
CREATE OR REPLACE FUNCTION hh RETURN VARCHAR2 IS BEGIN RETURN('hh'); END; 
/
CREATE OR REPLACE FUNCTION mi RETURN VARCHAR2 IS BEGIN RETURN('mi'); END; 
/
CREATE OR REPLACE FUNCTION ss RETURN VARCHAR2 IS BEGIN RETURN('ss'); END; 
/

CREATE OR REPLACE Function DateAdd(date_type IN varchar2, offset IN integer, date_in IN date) 
RETURN date IS date_returned date; 
BEGIN 
date_returned := CASE date_type 
    WHEN 'mm' THEN add_months(date_in,TRUNC(offset)) 
    WHEN 'yyyy' THEN add_months(date_in,TRUNC(offset) * 12) 
    WHEN 'dd' THEN date_in + TRUNC(offset) 
    WHEN 'hh' THEN date_in + (TRUNC(offset)/24) 
    WHEN 'mi' THEN date_in + (TRUNC(offset) /24/60) 
    WHEN 'ss' THEN date_in + (TRUNC(offset) /24/60/60) 
    END; 
RETURN(date_returned); 
END; 
/

CREATE OR REPLACE Function DateDiff(return_type IN varchar2, date_1 IN date, date_2 IN date) 
RETURN integer IS number_return integer; 
BEGIN 
number_return := CASE return_type 
    WHEN 'mm' THEN ROUND(MONTHS_BETWEEN(TRUNC(date_2,'MM'),TRUNC(date_1, 'MM'))) 
    WHEN 'yyyy' THEN ROUND(MONTHS_BETWEEN(TRUNC(date_2,'YYYY'), TRUNC(date_1, 'YYYY')))/12 
    WHEN 'dd' THEN ROUND((TRUNC(date_2,'DD') - TRUNC(date_1, 'DD'))) 
    WHEN 'hh' THEN (TRUNC(date_2,'HH') - TRUNC(date_1,'HH')) * 24 
    WHEN 'mi' THEN (TRUNC(date_2,'MI') - TRUNC(date_1,'MI')) * 24 * 60 
    WHEN 'ss' THEN (date_2 - date_1) * 24 * 60 * 60 
    END; 
RETURN(number_return); 
END; 
/
0

你可以写在Oracle中的功能此

function  datediff(p_what in varchar2, p_d1 in date, p_d2 in date) return number as l_result number; 
BEGIN 
     select (p_d2-p_d1) * 
      decode(upper(p_what), 'SS', 24*60*60, 'MI', 24*60, 'HH', 24, NULL) 
     into l_result from dual; 

     return l_result; 
END; 

,并用它喜欢:

DATEDIFF('YYYY-MM-DD', SYSTIMESTAMP, SYSTIMESTAMP)