by 준이파파 [SQL Query] [2019.01.07 14:16:08]
같은 오라클DB이고 완전 동일한 소스인데
개발쪽 톰캣에선 정상적으로 되는데
운영쪽 제우스 환경에선 ORA-01861: literal does not match format string 에러가납니다.
SELECT YMD, JUMIN_TOTAL, BUSINO_TOTAL, BUBINO_TOTAL, EMAIL_TOTAL, CELL_TOTAL, TEL_TOTAL, CARD_TOTAL FROM( SELECT B.YMD, NVL(SUM(A.JUMIN_CNT), 0) AS JUMIN_TOTAL, NVL(SUM(A.BUSINO_CNT), 0) AS BUSINO_TOTAL, NVL(SUM(A.BUBINO_CNT), 0) AS BUBINO_TOTAL, NVL(SUM(A.EMAIL_CNT), 0) AS EMAIL_TOTAL, NVL(SUM(A.CELL_CNT), 0) AS CELL_TOTAL, NVL(SUM(A.TEL_CNT), 0) AS TEL_TOTAL, NVL(SUM(A.CARD_CNT), 0) AS CARD_TOTAL FROM ( SELECT TO_CHAR(TRUNC(TO_DATE(#{year}||'-'||#{month}, 'YYYY-MM'), 'MM') + LEV - 1, 'YYYY-MM') AS YM, TO_CHAR(TRUNC(TO_DATE(#{year}||'-'||#{month}, 'YYYY-MM'), 'MM') + LEV - 1, 'YYYY-MM-DD') AS YMD FROM (SELECT LEVEL AS LEV FROM DUAL CONNECT BY LEVEL <![CDATA[ <= ]]> TO_CHAR(LAST_DAY(#{year}||'-'||#{month}||'-01'), 'DD')) ) B LEFT OUTER JOIN MC_PERSONAL_DATA A ON TO_CHAR(A.REG_DT, 'YYYY-MM-DD') = B.YMD WHERE B.YM = TO_CHAR(SYSDATE, 'YYYY-MM') GROUP BY B.YMD ) T1 ORDER BY YMD
to_date에서 yyyy-mm같이 다 명시해줬는데...
인데 딱히 문제될게 없어보이는데 에러가나네요
뭐가 문제일까요?
LAST_DAY(날짜) 하셔야 하는데 LAST_DAY(문자) 하셨네요.
여가서 문자가 날짜로 자동형변환 됩니다.
자동형변환시 포멧이 맞지 않아 에러 발생
#{year} 와 #{month} 가 너무 많이 사용되네요.
최초 한번만 사용해서 날짜 변환한뒤 변환된걸 계속 사용하는 방식으로 바꾼다면
소스도 간결해지고 last_day 에서와 같은 실수도 줄일 수 있습니다.
날짜 변환 외에 고칠 부분이 상당히 많네요.
1. 불필요한 함수 사용도 많구요.
2. 년월 조건 받이놓고선 sysdate 조건은 왜 주는지?
- 년월 조건이 현재년월 조건이라면 굳이 연월 조건 없이 sysdate 만 이용하면 됩니다.
3. a 테이블 조인 검색시 REG_DT 가공하는 것도 문제네요.
- a 를 가공하지 않도록 조건을 변경해 주세요.
SELECT b.ymd , NVL(jumin_total , 0) AS jumin_total , NVL(busino_total, 0) AS busino_total , NVL(bubino_total, 0) AS bubino_total , NVL(email_total , 0) AS email_total , NVL(cell_total , 0) AS cell_total , NVL(tel_total , 0) AS tel_total , NVL(card_total , 0) AS card_total FROM (SELECT TO_CHAR(ym + LEVEL - 1, 'yyyy-mm-dd') ymd FROM (SELECT TRUNC(sysdate, 'mm') ym FROM dual) -- FROM (SELECT TO_DATE(#{year}||#{month}, 'yyyymm') ym FROM dual) CONNECT BY LEVEL <= LAST_DAY(ym) - ym + 1 ) b LEFT OUTER JOIN (SELECT TO_CHAR(reg_dt, 'yyyy-mm-dd') ymd , SUM(jumin_cnt ) AS jumin_total , SUM(busino_cnt) AS busino_total , SUM(bubino_cnt) AS bubino_total , SUM(email_cnt ) AS email_total , SUM(cell_cnt ) AS cell_total , SUM(tel_cnt ) AS tel_total , SUM(card_cnt ) AS card_total FROM mc_personal_data WHERE reg_dt >= TRUNC(sysdate, 'mm') AND reg_dt < ADD_MONTHS(TRUNC(sysdate, 'mm'), 1) GROUP BY TO_CHAR(reg_dt, 'yyyy-mm-dd') ) a ON b.ymd = a.ymd ORDER BY ymd ;