2017-04-26 75 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?”。