2008-09-04 37 views
5

Chúng tôi hiện đang sử dụng NHibernate để kết nối với cơ sở dữ liệu khác nhau dựa trên nơi phần mềm của chúng tôi được cài đặt. Vì vậy, tôi đang chuyển nhiều thủ tục SQL cho Oracle.Oracle tương đương với SQL Server/Sybase DateDiff

Máy chủ SQL có chức năng đẹp gọi là DateDiff có phần ngày, bắt đầu và kết thúc.

Ví dụ về các bộ phận ngày là ngày, tuần, tháng, năm, v.v. .

Tương đương với Oracle là gì?

Tôi chưa tìm thấy ai để tạo phiên bản của riêng mình?

(cập nhật bởi Mark Harrison) có một số câu trả lời hay giải thích số học ngày của Oracle. Nếu bạn cần một dateiff của Oracle() xem câu trả lời của Einstein. (Tôi cần điều này để giữ cho các kịch bản SQL spme tương thích giữa Sybase và Oracle.) Lưu ý rằng câu hỏi này áp dụng như nhau cho Sybase.

+0

Có một cái nhìn ở đây: (Nếu liên kết này vẫn còn bị mục nát, hãy sử dụng liên kết bên dưới) http://asktom.oracle.com/pls/asktom/ASKTOM.download_file?p_file=6551242712657900129 –

Trả lời

1

Bài viết của Tom rất cũ. Nó chỉ thảo luận về loại NGÀY. Nếu bạn sử dụng các loại TIMESTAMP thì số học ngày được tích hợp vào 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 

hoặc

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 - bạn không cần điều đó. DATE trong Oracle thực sự là một kiểu dữ liệu ngày tháng và thời gian. Sự khác biệt duy nhất giữa DATE và TIMESTAMP là DATE giải quyết xuống giây thứ hai nhưng TIMESTAMP phân giải xuống micro giây. Do đó, bài viết Ask Tom hoàn toàn hợp lệ cho các cột TIMESTAMP.

4

Tôi đã đánh cắp hầu hết điều này từ một bài báo cũ của Tom cách đây vài năm, khắc phục một số lỗi từ bài viết và làm sạch nó. Các đường phân giới cho dateiff được tính toán khác nhau giữa oracle và MSSQL, do đó bạn phải cẩn thận với một số ví dụ nổi xung quanh có không đúng tài khoản cho MSSQL/Sybase phong cách ranh giới mà không cung cấp kết quả phân đoạn.

Sau đây bạn có thể sử dụng cú pháp MSSQL và nhận kết quả tương tự như MSSQL như SELECT DATEDIFF (dd, getdate(), DATEADD (đ, 5, getdate())) TỪ DUAL;

Tôi chỉ cho rằng nó hoạt động - không phải là cách hiệu quả hay cách tốt nhất để thực hiện. Tôi không phải là người Oracle :) Và bạn có thể muốn suy nghĩ kỹ về việc sử dụng các macro chức năng của mình để giải quyết các câu hỏi xung quanh dd, mm, hh, mi..etc.

(cập nhật bởi Mark Harrison) thêm chức năng dy làm bí danh cho 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

Bạn có thể viết một hàm trong oracle cho điều này

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; 

và sử dụng nó như:

DATEDIFF('YYYY-MM-DD', SYSTIMESTAMP, SYSTIMESTAMP) 
Các vấn đề liên quan