常用函数--不同时间粒度循环取数之sp_Utl_ComboTime

来源:互联网 发布:db2存储过程动态sql 编辑:程序博客网 时间:2024/05/16 17:56
CREATE OR REPLACE FUNCTION sp_Utl_ComboTime(
    iTime            DATE,          -- 输入时间
    iAdmBeginTime DATE,         -- 输入偏移开始时间
    iAdmEndTime     DATE,       -- 输入偏移结束时间
    iTimeSectFlag INTEGER,    -- 步长
    iComboFlag       INTEGER, -- 偏移标志, 0: 加偏移开始时间; 非0: 加偏移结束时间
    oTime OUT     DATE           -- 输出时间
) RETURN INTEGER
AS
    tTime         VARCHAR2(50);   -- 工作时间
    v_ErrM        VARCHAR2(200);
BEGIN
    -- 判断TimeStatFlag, 为tTime赋值


    -- 时段: 步长为小时
    IF iTimeSectFlag = 1 THEN
        tTime := TO_CHAR(iTime, 'YYYY-MM-DD HH24:MI:SS');
    END IF;


    -- 小时: 步长为小时
    IF iTimeSectFlag = 2 THEN
        tTime := TO_CHAR(iTime, 'YYYY-MM-DD HH24:')||'00:00';
    END IF;




    -- 半小时: 步长为半小时不用处理时间
    -- format的时候已经搞定了
    IF iTimeSectFlag = 10 THEN
        tTime := TO_CHAR(iTime, 'YYYY-MM-DD HH24:MI:SS');
    END IF;


    -- 天: 步长为天, 偏移为小时
    IF iTimeSectFlag = 3 THEN
        IF iComboFlag = 0 THEN
            tTime := TO_CHAR(iTime, 'YYYY-MM-DD')||' '||TO_CHAR(iAdmBeginTime, 'HH24:MI:SS');
        ELSE
            IF iAdmBeginTime >= iAdmEndTime THEN
                tTime := TO_CHAR(iTime + 1, 'YYYY-MM-DD')||' '||TO_CHAR(iAdmEndTime, 'HH24:MI:SS');
            ELSE
                tTime := TO_CHAR(iTime, 'YYYY-MM-DD')||' '|| TO_CHAR(iAdmEndTime, 'HH24:MI:SS');
            END IF;
        END IF;
    END IF;


    -- 周: 步长为周, 步长为1天, 范围为iTime到周日起始、结束时间已经在sp_Utl_FormatTime中修正,
    -- 在此不需要做任何处理。
    IF iTimeSectFlag = 4 THEN
        tTime := TO_CHAR(iTime, 'YYYY-MM-DD HH24:MI:SS');
    END IF;


    -- 月: 步长为月, 偏移为天
    IF iTimeSectFlag = 6 THEN
        IF iComboFlag = 0 THEN
            tTime := TO_CHAR(iTime, 'YYYY-MM-')||TO_CHAR(iAdmBeginTime, 'DD HH24:MI:SS');
        ELSE
            IF iAdmBeginTime >= iAdmEndTime THEN
                tTime := TO_CHAR(ADD_MONTHS(iTime, 1), 'YYYY-MM-')||TO_CHAR(iAdmEndTime, 'DD HH24:MI:SS');
            ELSE
                tTime := TO_CHAR(iTime,'YYYY-MM-')||TO_CHAR(iAdmEndTime, 'DD HH24:MI:SS');
            END IF;
        END IF;
    END IF;


    -- 统计步长为季度
    IF iTimeSectFlag = 7 THEN
        DECLARE
            cStep CONSTANT   INTEGER := 3;
            tMonthTime       INTEGER;
            tMonthAdm        INTEGER;
            tStep            INTEGER;
            tMonth           CHAR(2);
            tAdmBeginTime    DATE;
            tAdmEndTime      DATE;
        BEGIN
            tAdmBeginTime := iAdmBeginTime;
            tAdmEndTime := iAdmEndTime;
            tMonth := TO_NUMBER(TO_CHAR(iTime, 'MM'));


            --计算起始时间
            IF iComboFlag = 0 THEN
                tStep := ROUND((tMonth + 1) / cStep) - 1;
                tMonthAdm := TO_NUMBER(TO_CHAR(tAdmBeginTime, 'MM'));
                tMonth := tStep * cStep + tMonthAdm;
                tTime := TO_CHAR(iTime, 'YYYY-') || '01' || TO_CHAR(tAdmBeginTime, '-DD HH24:MI:SS');
            ELSE  --计算结束时间
                IF (iAdmBeginTime < iAdmEndTime) THEN
                    tStep := ROUND((tMonth + 1) / cStep) - 1;
                    tMonthAdm := TO_NUMBER(TO_CHAR(tAdmEndTime, 'MM'));
                    tMonth := tStep * cStep + tMonthAdm;
                ELSE
                    tStep := ROUND((tMonth + 1) / cStep) - 1;
                    tMonthAdm := TO_NUMBER(TO_CHAR(tAdmEndTime, 'MM')) + cStep;
                    tMonth := tStep * cStep + tMonthAdm;
                END IF;
                tTime := TO_CHAR(iTime, 'YYYY-') || '01' || TO_CHAR(tAdmEndTime, '-DD HH24:MI:SS');
            END IF;
            tTime := TO_CHAR(ADD_MONTHS(TO_DATE(tTime, 'YYYY-MM-DD HH24:MI:SS'), tMonth - 1), 'YYYY-MM-DD HH24:MI:SS');
        END;
    END IF;


    -- 统计步长为半年
    IF iTimeSectFlag = 8 THEN
        DECLARE
            cStep CONSTANT   INTEGER := 6;
            tMonthTime       INTEGER;
            tMonthAdm        INTEGER;
            tStep            INTEGER;
            tMonth           CHAR(2);
            tAdmBeginTime    DATE;
            tAdmEndTime      DATE;
        BEGIN
            tAdmBeginTime := iAdmBeginTime;
            tAdmEndTime := iAdmEndTime;
            tMonth := TO_NUMBER(TO_CHAR(iTime, 'MM'));


            --计算起始时间
            IF iComboFlag = 0 THEN
                tStep := ROUND((tMonth + 2) / cStep) - 1;
                tMonthAdm := TO_NUMBER(TO_CHAR(tAdmBeginTime, 'MM'));
                tMonth := tStep * cStep + tMonthAdm;
                tTime := TO_CHAR(iTime, 'YYYY-') || '01' || TO_CHAR(tAdmBeginTime, '-DD HH24:MI:SS');
            ELSE  --计算结束时间
                IF (iAdmBeginTime < iAdmEndTime) THEN
                    tStep := ROUND((tMonth + 2) / cStep) - 1;
                    tMonthAdm := TO_NUMBER(TO_CHAR(tAdmEndTime, 'MM'));
                    tMonth := tStep * cStep + tMonthAdm;
                ELSE
                    tStep := ROUND((tMonth + 2) / cStep) - 1;
                    tMonthAdm := TO_NUMBER(TO_CHAR(tAdmEndTime, 'MM')) + cStep;
                    tMonth := tStep * cStep + tMonthAdm;
                END IF;
                tTime := TO_CHAR(iTime, 'YYYY-') || '01' || TO_CHAR(tAdmEndTime, '-DD HH24:MI:SS');
            END IF;
            tTime := TO_CHAR(ADD_MONTHS(TO_DATE(tTime, 'YYYY-MM-DD HH24:MI:SS'), tMonth - 1), 'YYYY-MM-DD HH24:MI:SS');
        END;
    END IF;


    -- 统计步长为年
    IF iTimeSectFlag = 9 THEN
        IF iComboFlag = 0 THEN
            tTime := TO_CHAR(iTime, 'YYYY-')||TO_CHAR(iAdmBeginTime, 'MM-DD HH24:MI:SS');
        ELSE
            IF iAdmBeginTime >= iAdmEndTime THEN
                tTime := TO_CHAR(ADD_MONTHS(iTime, 12), 'YYYY-')|| TO_CHAR(iAdmEndTime, 'MM-DD HH24:MI:SS');
            ELSE
                tTime := TO_CHAR(iTime, 'YYYY-')||TO_CHAR(iAdmEndTime, 'MM-DD HH24:MI:SS');
            END IF;
        END IF;
    END IF;


    -- 统计步长为旬
    IF iTimeSectFlag = 5 THEN
        IF iComboFlag = 0 THEN
            IF TO_NUMBER(TO_CHAR(iTime,'DD')) <= 10 THEN
               tTime := TO_CHAR(iTime,'YYYY-MM-') || '01 00:00:00';
            ELSIF TO_NUMBER(TO_CHAR(iTime,'DD')) <= 20 THEN
               tTime := TO_CHAR(iTime,'YYYY-MM-') || '11 00:00:00';
            ELSE
               tTime := TO_CHAR(iTime,'YYYY-MM-') || '21 00:00:00';
            END IF;
        ELSE
            IF TO_NUMBER(TO_CHAR(iTime,'DD')) < 10 THEN
               tTime := TO_CHAR(iTime,'YYYY-MM-') || '01 00:00:00';
            ELSIF TO_NUMBER(TO_CHAR(iTime,'DD')) < 20 THEN
               tTime := TO_CHAR(iTime,'YYYY-MM-') || '11 00:00:00';
            ELSIF TO_NUMBER(TO_CHAR(iTime,'DD')) < 30 THEN
               tTime := TO_CHAR(iTime,'YYYY-MM-') || '21 00:00:00';
            ELSE
               tTime := TO_CHAR(ADD_MONTHS(iTime,1),'YYYY-MM-') || '01 00:00:00';
            END IF;
        END IF;
    END IF;






    oTime := TO_DATE(tTime, 'YYYY-MM-DD HH24:MI:SS');


    RETURN 0;


EXCEPTION
    WHEN OTHERS THEN
        v_ErrM := SUBSTR(SQLERRM, 1, 200);
        DBMS_OUTPUT.PUT_LINE(v_ErrM);
        RETURN 1;
END sp_Utl_ComboTime;
0 0