CREATE OR REPLACE FUNCTION FUN$_GETMONTH
RETURN VARCHAR2 IS
/***************************
*用途:根据当前日期,判断是上半月还是下半月,如果是下半月,则显示下月的上半月(201801001-21081015),如果是上半月,则显示本月的下半月
思路:先求出本月的对应几号和本月最后一天是几号
然后求出下个月,进行一一判断
*
********************************************/
V_RETURN VARCHAR2(20);--返回值20181001-20181015
V_DATE NUMBER;--当前日期对应的几号
V_MONTH NUMBER;--每个月的最后一天是几号,比如9月是30号
V_CURR_MONTH VARCHAR2(6);--本月的日期
V_NEXT_MONTH VARCHAR2(6);--下个月的日期
BEGIN
--当前日期对应的几号
SELECT TO_NUMBER(TO_CHAR((SYSDATE), 'DD')) INTO V_DATE FROM DUAL;
--取得每个月的最后一天是30 还是31 还是28 29
SELECT TO_NUMBER(TO_CHAR(LAST_DAY(SYSDATE), 'DD')) INTO V_MONTH FROM DUAL;
--获取下一个月201810
SELECT TO_CHAR(ADD_MONTHS(SYSDATE,1),'YYYYMM') INTO V_NEXT_MONTH FROM DUAL;
--获取本月个月201809
SELECT TO_CHAR((SYSDATE),'YYYYMM') INTO V_CURR_MONTH FROM DUAL;
--判断一个月是30天
IF V_MONTH =30 THEN
IF V_DATE<=15 THEN
V_RETURN :=V_CURR_MONTH||'16'||'-'||V_CURR_MONTH||'30';
ELSE
V_RETURN :=V_NEXT_MONTH||'01'||'-'||V_NEXT_MONTH||'15';
END IF;
--判断一个月31天
ELSIF V_MONTH =31 THEN
IF V_DATE<=15 THEN
V_RETURN :=V_CURR_MONTH||'16'||'-'||V_CURR_MONTH||'31';
ELSE
IF TO_NUMBER(TO_CHAR(TO_DATE(V_NEXT_MONTH,'YYYYMM'), 'MM')) = 2 then --下一个月是2月,上半月只有14天
V_RETURN :=V_NEXT_MONTH||'01'||'-'||V_NEXT_MONTH||'14';
else
V_RETURN :=V_NEXT_MONTH||'01'||'-'||V_NEXT_MONTH||'15';
END IF;
END IF;
--判断2月只有28天
ELSIF V_MONTH = 28 THEN
IF V_DATE<=14 THEN
V_RETURN :=V_CURR_MONTH||'15'||'-'||V_CURR_MONTH||'28';
ELSE
V_RETURN :=V_NEXT_MONTH||'01'||'-'||V_NEXT_MONTH||'15';
END IF;
--判断2月只有29天
ELSIF V_MONTH = 29 THEN
IF V_DATE<=14 THEN
V_RETURN :=V_CURR_MONTH||'01'||'-'||V_CURR_MONTH||'15';
ELSE
V_RETURN :=V_NEXT_MONTH||'15'||'-'||V_NEXT_MONTH||'29';
END IF;
END IF;
DBMS_OUTPUT.PUT_LINE('V_DATE:'||V_DATE);
DBMS_OUTPUT.PUT_LINE('V_RETURN:'||V_RETURN);
RETURN V_RETURN;
--异常,报错处理
EXCEPTION WHEN
OTHERS THEN
DBMS_OUTPUT.PUT_LINE('函数有误。');
RETURN NULL;
END;
/