sql sql-server oracle sybase datediff

Oracle equivalente a SQL Server/Sybase DateDiff



sybase ase (4)

Ahora estamos usando NHibernate para conectarnos a diferentes bases de datos en donde se instala nuestro software. Por lo tanto, transfiero muchos procedimientos SQL a Oracle.

SQL Server tiene una bonita función llamada DateDiff que toma una parte de fecha, fecha de inicio y fecha de finalización.

Los ejemplos de partes de fecha son día, semana, mes, año, etc. .

¿Cuál es el equivalente de Oracle?

No he encontrado ninguno ¿Tengo que crear mi propia versión?

(Actualización de Mark Harrison) hay varias respuestas agradables que explican la aritmética de la fecha de Oracle. Si necesita un Oracle datediff (), vea la respuesta de Einstein. (Necesito esto para mantener las secuencias de comandos SQL compatibles entre Sybase y Oracle). Tenga en cuenta que esta pregunta se aplica igualmente a Sybase.


El artículo de Tom es muy viejo. Solo trata sobre el tipo de FECHA. Si usa tipos TIMESTAMP, la aritmética de fecha está integrada en 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

o

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: no necesitas eso. FECHA en Oracle es en realidad un tipo de datos de fecha y hora. La única diferencia entre DATE y TIMESTAMP es que DATE se resuelve hasta el segundo, pero TIMESTAMP se resuelve hasta el micro segundo. Por lo tanto, el artículo Ask Tom es perfectamente válido también para las columnas TIMESTAMP.


Robé la mayor parte de esto de un viejo artículo de Tom hace unos años, solucioné algunos errores del artículo y lo limpié. Las líneas de demarcación para datediff se calculan de forma diferente entre Oracle y MSSQL, por lo que debe tener cuidado con algunos ejemplos que flotan por ahí y que no representan correctamente los límites de estilo de MSSQL / Sybase que no proporcionan resultados fraccionarios.

Con lo siguiente, debería poder utilizar la sintaxis MSSQL y obtener los mismos resultados que MSSQL, como SELECT DATEDIFF (dd, getdate (), DATEADD (dd, 5, getdate ()) FROM DUAL;

Solo afirmo que funciona; no es que sea eficiente o la mejor manera de hacerlo. No soy una persona de Oracle :) Y es posible que desee pensar dos veces sobre el uso de mis macros de funciones para solucionar las necesidades de citas de dd, mm, hh, mi..etc.

(actualización de Mark Harrison) agregó la función dy como alias para 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; /


USTED podría escribir una función en Oracle para esto

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;

y úsalo como:

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