2017-04-26 3 views
1

DB関数に日付のalistを渡し、選択した日付が渡されるこれらの休日のリストに含まれるかどうかを比較する必要があります。私のDB機能は以下の通りです。この関数に入力パラメータとして動的休日のalistを渡し、START_DATEがその休日リストにも入るかどうかを確認する必要があります。Javaを使用してoracle db関数に日付リストを渡す

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

データベース機能に配列を渡すことには多くの方法があります。

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; 

まず、あなたのDBスキーマ内TABLEタイプを作成する必要があります。簡単なものは以下の通りです

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?"。

関連する問題