/************************************************
*功能描述:
* 获取某一年的最大周次。
*
*算法描述:
* N/A
*
*修订记录:
* 修改时间 编辑人 修改大致描述
* 2017-03-29 何秋城 1.创建此函数
*
*入参出参描述:
* p_Year VARCHAR2 年份YYYY
*
*返回值描述:
* 最大周次
************************************************/
FUNCTION Get_Max_Year_Week(p_Year VARCHAR2) RETURN NUMBER IS
x_Week NUMBER;
l_Year VARCHAR2(4);
Ex_Error_Year EXCEPTION;
BEGIN
DECLARE
BEGIN
SELECT To_Char(To_Date(p_Year, 'YYYY'), 'YYYY')
INTO l_Year
FROM Dual;
EXCEPTION
WHEN OTHERS THEN
RAISE Ex_Error_Year;
END;
WITH Params AS
(SELECT l_Year AS Nf FROM Dual)
SELECT To_Char(To_Date(Pm.Nf || '-12-28', 'YYYY-MM-DD'), 'IW')
INTO x_Week
FROM Dual
LEFT JOIN Params Pm
ON 1 = 1;
RETURN x_Week;
EXCEPTION
WHEN Ex_Error_Year THEN
Dbms_Output.Put_Line('输入年份有误');
RAISE Ex_Week_Notfound;
WHEN OTHERS THEN
RAISE Ex_Week_Notfound;
END Get_Max_Year_Week;
/************************************************
*功能描述:
* 由周次获取指定周次的指定周几的日期。
*
*算法描述:
* N/A
*
*修订记录:
* 修改时间 编辑人 修改大致描述
* 2017-03-29 何秋城 1.创建此函数
*
*入参出参描述:
* p_Week VARCHAR2
* p_Number NUMBER - 1:周一
* 2:周二
* 3:周三
* 4:周四
* 5:周五
* 6:周六
* 7:周日
*
*返回值描述:
* 指定周次指定周几的日期
************************************************/
FUNCTION Get_Date_Fn(p_Week VARCHAR2, p_Number NUMBER) RETURN VARCHAR2 IS
x_Monday VARCHAR2(10);
--l_Max_Week NUMBER;
l_Interval_Year NUMBER; --相隔多少年
l_Interval_Week NUMBER := 0; --相隔多少周
l_Interval_Day NUMBER;
Ex_Beyond_Week EXCEPTION;
Ex_Below_Week EXCEPTION;
BEGIN
--输入周次小于当周最小周次
IF Substr(p_Week, 5, 2) < '01' THEN
RAISE Ex_Below_Week;
END IF;
--输入周次大于当年最大周次
IF Get_Max_Year_Week(Substr(p_Week, 1, 4)) < Substr(p_Week, 5, 2) THEN
RAISE Ex_Beyond_Week;
END IF;
CASE p_Number
WHEN 1 THEN
l_Interval_Day := 0;
WHEN 2 THEN
l_Interval_Day := 1;
WHEN 3 THEN
l_Interval_Day := 2;
WHEN 4 THEN
l_Interval_Day := 3;
WHEN 5 THEN
l_Interval_Day := 4;
WHEN 6 THEN
l_Interval_Day := 5;
WHEN 7 THEN
l_Interval_Day := 6;
END CASE;
--周次于当周比较
IF p_Week >= To_Char(SYSDATE, 'IYYYIW') THEN
--向后跨年(未来)
IF Substr(p_Week, 1, 4) > To_Char(SYSDATE, 'YYYY') THEN
l_Interval_Year := Substr(p_Week, 1, 4) - To_Char(SYSDATE, 'YYYY');
FOR i IN 1 .. l_Interval_Year LOOP
l_Interval_Week := l_Interval_Week +
Get_Max_Year_Week(Substr(p_Week, 1, 4) - i);
END LOOP;
SELECT To_Char(Trunc(SYSDATE +
(l_Interval_Week +
To_Number(Substr(p_Week, 5, 2)) -
To_Number(To_Char(SYSDATE, 'IW'))) * 7,
'IW') + l_Interval_Day,
'YYYY-MM-DD')
INTO x_Monday
FROM Dual;
ELSE
--同一年
SELECT To_Char(Trunc(SYSDATE +
(To_Number(p_Week) -
To_Number(To_Char(SYSDATE, 'IYYYIW'))) * 7,
'IW') + l_Interval_Day,
'YYYY-MM-DD')
INTO x_Monday
FROM Dual;
END IF;
ELSE
--向前跨年(过去)
IF Substr(p_Week, 1, 4) < To_Char(SYSDATE, 'YYYY') THEN
l_Interval_Year := To_Char(SYSDATE, 'YYYY') - Substr(p_Week, 1, 4);
FOR i IN 1 .. l_Interval_Year LOOP
l_Interval_Week := l_Interval_Week +
Get_Max_Year_Week(To_Char(SYSDATE, 'YYYY') - i);
END LOOP;
SELECT To_Char(Trunc(SYSDATE - (l_Interval_Week +
To_Number(To_Char(SYSDATE, 'IW')) -
To_Number(Substr(p_Week, 5, 2))) * 7,
'IW') + l_Interval_Day,
'YYYY-MM-DD')
INTO x_Monday
FROM Dual;
ELSE
--同一年
SELECT To_Char(Trunc(SYSDATE - (To_Number(To_Char(SYSDATE, 'IYYYIW')) -
To_Number(p_Week)) * 7,
'IW') + l_Interval_Day,
'YYYY-MM-DD')
INTO x_Monday
FROM Dual;
END IF;
END IF;
RETURN x_Monday;
EXCEPTION
WHEN Ex_Below_Week THEN
Dbms_Output.Put_Line('输出周次小于指定年份的最大周次');
RETURN 'E';
WHEN Ex_Week_Notfound THEN
Dbms_Output.Put_Line('未找到指定年份的最大周次');
RETURN 'E';
WHEN Ex_Beyond_Week THEN
Dbms_Output.Put_Line('输出周次大于指定年份的最大周次');
RETURN 'E';
WHEN OTHERS THEN
Dbms_Output.Put_Line('未找到指定周次的日期');
RETURN 'E';
END Get_Date_Fn;
Oracle获取指定周次的周几的日期
最新推荐文章于 2021-12-22 13:56:30 发布