Oracle等同于SQL Server / Sybase DateDiff
现在,我们正在使用NHibernate连接到基于我们软件安装位置的不同数据库。因此,我正在将许多SQL过程移植到Oracle。
SQL Server有一个很好的名为DateDiff的函数,该函数包含日期部分,开始日期和结束日期。
日期部分的示例是日,周,月,年等。 。
什么是Oracle同等学历?
我还没有找到自己的版本吗?
(由Mark Harrison更新),有几个不错的答案可以解释Oracle日期算术。如果我们需要Oracle datediff(),请参阅爱因斯坦的答案。 (我需要这样做,以使spme SQL脚本在Sybase和Oracle之间兼容。)请注意,此问题同样适用于Sybase。
解决方案
回答
汤姆的文章很老。它仅讨论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
回答
JohnLavoie,我们不需要。 Oracle中的DATE实际上是日期和时间数据类型。 DATE和TIMESTAMP之间的唯一区别是DATE解析为秒,而TIMESTAMP解析为微秒。因此,Ask Tom文章对于TIMESTAMP列也完全有效。
回答
几年前,我从一篇旧的tom文章中窃取了大部分内容,修复了该文章中的一些错误并进行了清理。在oracle和MSSQL之间,datediff的分界线的计算方式不同,因此我们必须小心一些未正确说明MSSQL / Sybase样式边界(无法提供小数结果)的示例。
使用以下代码,我们应该能够使用MSSQL语法并获得与MSSQL相同的结果,例如SELECT DATEDIFF(dd,getdate(),DATEADD(dd,5,getdate()))FROM DUAL;
我只声称它行之有效,不是做到这一点的最佳方法。我不是Oracle专家:)我们可能需要三思而后行才能使用函数宏来解决需要在dd,mm,hh,mi等周围加引号的问题。
(由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; /