2008-09-04 60 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)