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;
常用函数--不同时间粒度循环取数之sp_Utl_ComboTime
最新推荐文章于 2020-09-17 21:58:00 发布