2017-04-26 22 views
1

我需要將日期列表傳遞給數據庫函數,並比較所選日期是否落入正在傳遞的這些假期的列表中。我的數據庫功能目前如下。需要將動態節假日的alist作爲輸入參數傳遞給此函數,並檢查START_DATE是否也落入該假期列表中。通過java將日期列表傳遞到oracle數據庫函數

create or replace 
FUNCTION getWorkingDays (DATE_ONE DATE, DATE_TWO DATE) RETURN NUMBER 
IS 
DAY_COUNT NUMBER := 0; 
START_DATE DATE; 
END_DATE DATE; 
BEGIN -- loop through and update 
IF(DATE_ONE is not null and DATE_TWO is not null) 
THEN 
IF DATE_ONE < DATE_TWO THEN 
    START_DATE := DATE_ONE; 
    END_DATE := DATE_TWO; 
ELSE 
    START_DATE := DATE_TWO; 
    END_DATE := DATE_ONE; 
END IF; 

WHILE START_DATE < END_DATE 
LOOP 
    IF TO_CHAR(START_DATE,'DY') NOT IN ('SAT','SUN') THEN 
    DAY_COUNT := DAY_COUNT + 1; 
END IF; 
    START_DATE := START_DATE + 1; 
END LOOP; 
END IF; 
RETURN DAY_COUNT; 
EXCEPTION 
WHEN OTHERS THEN 
RETURN NULL; 
END getWorkingDays; 
+0

那麼,這是什麼問題? – Nitish

+0

我如何將一個日期列表傳遞給一個DB函數作爲其輸入參數?我如何比較開始日期是否落入函數內的這個日期? – Ann

+0

看看[這個問題](http://stackoverflow.com/questions/19888520/pass-array-from-java-to-oracle-java-sql-sqlexception-fail-to-convert-to-intern)對於你的問題的第一部分。問題的第二部分是算法發展,它超出了SO問題的範圍。 – Nitish

回答

2

將數組傳遞給數據庫函數有很多方法。一個簡單的一個情況如下:

首先,你應該建立在你的DB模式的TABLE類型:

CREATE TYPE DATE_ARRAY AS TABLE OF DATE; 

這之後你應該寫一FUNCTION這個新類型的輸入:

-- a dummy function just for presenting the usage of input array 
CREATE FUNCTION Date_Array_Test_Function(p_data IN DATE_ARRAY) 
RETURN INTEGER 
IS 
    TYPE Cur IS REF CURSOR; 
    MyCur cur; 

    single_date DATE; 
BEGIN 
    /* Inside this function you can do anything you wish 
     with the input parameter: p_data */ 

    OPEN MyCur FOR SELECT * FROM table(p_data); 

    LOOP 
     FETCH MyCur INTO single_date; 
     EXIT WHEN MyCur%NOTFOUND; 

     dbms_output.put_line(to_char(single_date)); 
    END LOOP; 

    RETURN 0; 

END Date_Array_Test_Function; 

現在在java代碼中,您可以使用以下代碼來調用具有數組輸入類型的此類函數:

import java.sql.CallableStatement; 
import java.sql.Connection; 
import java.sql.Date; 
import java.sql.DriverManager; 
import java.sql.SQLException; 
import java.sql.Types; 

import oracle.sql.ARRAY; 
import oracle.sql.ArrayDescriptor; 

public class Main 
{   
    public static void main(String[] args) throws SQLException 
    { 
     Connection c = DriverManager.getConnection(url, user, pass); 

     String query = "begin ? := date_array_test_function(?); end;"; 

     // note the uppercase "DATE_ARRAY" 
     ArrayDescriptor arrDescriptor = ArrayDescriptor.createDescriptor("DATE_ARRAY", c); 

     // Test dates 
     Date[] inputs = new Date[] {new Date(System.currentTimeMillis()), 
            new Date(System.currentTimeMillis()), 
            new Date(System.currentTimeMillis())}; 

     ARRAY array = new ARRAY(arrDescriptor, c, inputs); 

     CallableStatement cs = c.prepareCall(query); 
     cs.registerOutParameter(1, Types.INTEGER); // the return value 
     cs.setObject(2, array); // the input of the function 
     cs.executeUpdate(); 

     System.out.println(cs.getInt(1)); 
    } 
} 

希望這會有所幫助。

好運

0
CREATE TYPE DateList IS TABLE OF DATE; 
/

CREATE FUNCTION getWorkingDays (
    in_start_date IN DATE, 
    in_end_date IN DATE, 
    in_date_list IN DateList 
) RETURN NUMBER 
IS 
    p_start_date DATE; 
    p_end_date  DATE; 
    p_working_days NUMBER; 
BEGIN 
    IF in_start_date IS NULL OR in_end_date IS NULL THEN 
    RETURN NUll; 
    END IF; 

    p_start_date := TRUNC(LEAST(in_start_date, in_end_date)); 
    p_end_date := TRUNC(GREATEST(in_start_date, in_end_date)); 

    -- 5/7 * (Number of days between monday of the week containing the start date 
    --   and monday of the week containing the end date) 
    -- + LEAST(day of week for end date, 5) 
    -- - LEAST(day of week for start date, 5) 
    p_working_days := (TRUNC(p_end_date, 'IW') - TRUNC(p_start_date, 'IW')) * 5/7 
        + LEAST(p_end_date - TRUNC(p_end_date, 'IW') + 1, 5) 
        - LEAST(p_start_date - TRUNC(p_start_date, 'IW') + 1, 5); 

    IF in_date_list IS NOT NULL THEN 
    FOR i IN 1 .. in_date_list.COUNT LOOP 
     IF in_date_list(i) >= p_start_date AND in_date_list(i) < p_end_date THEN 
     p_working_days := p_working_days - 1; 
     END IF; 
    END LOOP; 
    END IF; 

    RETURN p_working_days; 
END; 
/

@STaefi具有如何的數組傳遞給過程的例子。還有其他例子,如:「How to pass List from java to Oracle Procedure?」。