我写了下面的代码,但我没有得到预期的输出:
SQL> select TO_CHAR(TO_CHAR(sysdate,'MM')-1,'DD-MM-YYYY') AS PREV_MON_FIRST,
TO_CHAR(TO_CHAR(sysdate,'MM'),'DD-MM-YYYY')-1 AS PREV_MON_LAST from dual;
select TO_CHAR(TO_CHAR(sysdate,'MM')-1,'DD-MM-YYYY') AS PREV_MON from dual
*
ERROR at line 1:
ORA-01481: invalid number format model
缺少"DD"和"YYYY"值是正确的,但是当我尝试仅检索月份时,它也显示了相同的错误
您可以使用以下解决方案:
SELECT
TRUNC(LAST_DAY(ADD_MONTHS(sysdate, -2))) + 1 AS first_date,
TRUNC(LAST_DAY(ADD_MONTHS(sysdate, -1))) AS last_date
FROM dual
如果格式适合您的需求,则仅使用TO_CHAR
选择上个月的第一天YYYYMMDD
很容易:
SQL> select (to_char(sysdate, 'yyyymm') - 1) || '01' first_day
2 from dual;
FIRST_DAY
------------------------------------------
20180701
SQL>
但是,最后一天 - 我不知道。
通常的方法是有效的,但涉及其他功能:
SQL> select trunc(add_months(sysdate, -1), 'mm') first_day,
2 trunc(sysdate, 'mm') - 1 last_day
3 from dual;
FIRST_DAY LAST_DAY
---------- ----------
2018-07-01 2018-07-31
SQL>
对于LAST_DAY,这里是使用月份值hard_code而不使用 add_months,trunc,to_date 的查询
select to_char(sysdate,'yyyy')||
to_char(sysdate,'mm')-1||
case when to_char(sysdate,'mm')-1 in (1,3,5,7,8,10,12) THEN 31
when to_char(sysdate,'mm')-1 in (4,6,9,11) THEN 30
when mod(to_char(sysdate,'yyyy'),4)=0 and to_char(sysdate,'mm')-1=2 THEN 29
when mod(to_char(sysdate,'yyyy'),4)!=0 and to_char(sysdate,'mm')-1=2 THEN 28
end
from dual
如果我从字面上理解你的问题,一个解决方案是
CREATE OR REPLACE FUNCTION MY_LAST_DAY RETURN TIMESTAMP AS
next_run_date TIMESTAMP;
return_date_after TIMESTAMP := SYSTIMESTAMP - INTERVAL '100' DAY;
BEGIN
LOOP
DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING('FREQ=DAILY;INTERVAL=1;BYMONTHDAY=-1', NULL, return_date_after, next_run_date);
EXIT WHEN EXTRACT(MONTH FROM next_run_date) = EXTRACT(MONTH FROM SYSTIMESTAMP);
return_date_after := next_run_date;
END LOOP;
RETURN return_date_after;
END;
/
CREATE OR REPLACE FUNCTION MY_FIRST_DAY RETURN TIMESTAMP AS
next_run_date TIMESTAMP;
return_date_after TIMESTAMP := SYSTIMESTAMP - INTERVAL '100' DAY;
BEGIN
LOOP
DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING('FREQ=DAILY;INTERVAL=1;BYMONTHDAY=1', NULL, return_date_after, next_run_date);
EXIT WHEN EXTRACT(MONTH FROM next_run_date) = EXTRACT(MONTH FROM SYSTIMESTAMP);
return_date_after := next_run_date;
END LOOP;
RETURN return_date_after;
END;
/
它返回上个月的第一个和最后一个日期,而不使用TO_DATE
(或TO_TIMESTAMP
(、TRUNC
或ADD_MONTHS
但我希望你同意你的问题相当愚蠢。
对于LAST_DAY,这里是使用月份值hard_code而不使用 add_months,trunc,to_date 的查询
选择 to_char(sysdate,'yyyy'(|| to_char(系统日期,"毫米"(-1|| 当to_char(系统日期,'mm'(-1 英寸 (1,3,5,7,8,10,12( 然后 31 当 to_char(sysdate,'mm'(-1 IN (4,6,9,11( 则 30 当 mod(to_char(sysdate,'yyyy'(,4(=0 且 to_char(sysdate,'mm'(-1=2 则 29 当 mod(to_char(sysdate,'yyyy'(,4(!=0 和 to_char(sysdate,'mm'(-1=2 则 28 结束 从双
用于处理 1 月和闰年的新查询:
Select Decode(to_char(sysdate,'mm'(,1,to_char(sysdate,'yyyy'(-1 ,to_char(sysdate,'yyyy'((|| 解码(to_char(sysdate,'mm'(,1,12, to_char(sysdate,'mm'(-1(|| 当 to_char(系统日期,'mm'(-1 英寸 (1,3,5,7,8,10,0( 然后 31 时的情况 当to_char(系统日期,'mm'(-1 英寸 (4,6,9,11( 然后 30 当 to_char(sysdate,'mm'(-1=2 AND MOD(to_char(sysdate,'yyyy'(,4(!=0 AND MOD(to_char(sysdate,'yyyy'(,400(!=0 则 29 其他 28 结束 从双