이런현상에대해 어느부분을 확인 해봐야하는건가요 ?.. 1 17 3,487

by 푸르른 [Oracle 기초] [2016.08.29 14:57:47]


select * from table

where to_char(NVL(DT,TO_DATE(SYSDATE,'YYYYMMDD')),'YYYYMMDD') <= SYSDATE

위에 구분은 로컬환경과 TOAD에서는 잘돌아 갑니다

하지만 운영환경에서 포멧오류 가 나는데요  <= TO_CHAR(SYSDATE,'YYYYMMDD')로 하면 잘돌아가구요

 

위 첫번째 쿼리는  개발DB+로컬환경 /개발DB 토드/운영DB 토드 / 운영DB +로컬 에서 잘돌아가나

반영후 운영에서 돌리면 오류가 납니다 어떤이유에서 오류가 나는걸까요

잘모르겠네요 ㅠ 아 디비는 ORACLE입니다

-----------------------------------------

select * from table

where to_char(NVL(DT,TO_DATE('19000101','YYYYMMDD')),'YYYYMMDD') <= SYSDATE

급하게 적느라 잘못적었네요 죄송합니다 ...ㅠ

-------------------------------------\

ora 01861 에러 코드입니다.

 

 

 

by jkson [2016.08.29 15:12:20]

운영에서 돌릴 때 dt가 null인 데이터가 있나보네요.

운영DB 토드에서는 오류가 안나셨다면 다른 where 조건에 의해서 dt가

null인 데이터가 제거된 것이 아닐까 싶네요.

다른 조건 다 지우시고 해당 조건만 남긴채 돌리시면 토드에서도 오류날 겁니다.

오류 내용을 적어주시면 더 정확할 것 같은데 아마도 ORA-01858일 것 같네요.

dt가 date형 컬럼이라면 nvl(dt,sysdate) <= sysdate 그냥 이렇게 해주시는 게 나을 것 같네요.

혹시나 dt가 index 컬럼에 해당한다면 (dt <= sysdate or dt is null) 이게 더 맞을 것 같구요.

(null조건 때문에 좀 애매하네요. 어차피 null 조건 때문에 full table access 할 것 같은데.. ㅋ

변경하시고 실행계획 보세용~)


by 푸르른 [2016.08.29 15:30:33]

운영db에서 붙어서 쿼리를 날리나 개발db에서 쿼리를 날리나 오류는 안나고 동일한 결과가 나와요

toad에서 날리는경우 프로잭트에서 날리는경우 모두 정상동작합니다

소스를 운영반영후  운영에서 돌리면 오류가 나구요

지식이 없어서 요점을 콕찍어 물어보질 못하겠네요 하하..ㅠ


by jkson [2016.08.29 15:31:36]

똑같은 조회조건으로 입력하셨는데도 운영에 올렸을 경우에만 난다구요? 뭔가 이상한데요..;


by 푸르른 [2016.08.29 15:38:11]

 

사실상 개발 서버에는 데이터가 없어서 운영디비에 붙어 쿼리를 날리고 확인하는데

운영 소스를 반영하면

토드에서 운영디비로 쿼리 날려로확인고 개발소스로도 확인했던 쿼리가 포맷에러가 나는데 정확한

에러문구(코드)은 기억이 안나네요 ㅠㅠㅠ


by jkson [2016.08.29 15:41:06]

정확히 동일한 조건으로 조회했는지가 중요할 것 같아요. 특히나 운영 DB라면 데이터 변동도 계속 되고 있을 상황이라 조회하는 시간에 dt가 null인 데이터가 있었다면 오류났을 것이고 없었다면 오류가 나지 않았을 것 같네요. 일단은 올바른 쿼리로 바꾸시는 게 급선무일 것 같네요. dt 컬럼 데이터 형에 따라서 쓸데 없는 to_date와 to_char 함수를 없애세요.


by 푸르른 [2016.08.29 15:59:04]

답변 감사합니다 ..

정확히 동일 완벽히 동일조건의 쿼리 가 날라가고 있습니다 사용자수가 없는것을 확인했고 데이터가 일치하는상태였습니다 ㅠ


by 마농 [2016.08.29 15:24:17]

형변환을 완벽하게 거꾸로 하고 있는 쿼리입니다.
  TO_DATE 는 문자를 날짜로 바꾸는 함수인데. 날짜를 날짜로 바꾸고 있고
  TO_CHAR 를 이용해 날짜를 문자로 바꾼 뒤에 문자를 날짜와 비교하고 있네요.
DT 항목의 데이터 형이 뭘까요? (Date / Varchar2)
DT 항목의 데이터 값의 저장형식은 뭘까요? (년월일만 / 시분초까지)


by jkson [2016.08.29 15:30:40]

마농님 위에 쿼리처럼 nvl(dt,sysdate) <= sysdate 이런 조건이라면 null 조건인 것도 다 나와야하니까 그냥 or로 풀지말고 조건 그대로 놔두는 게 나은 거죠? 혹시 다른 방법 있을까요?


by 푸르른 [2016.08.29 15:41:04]

급하게 적느라 잘못적은부분이 있어 수정했습니다...하하..
DT 항목의 데이터 형이 뭘까요? (Date / Varchar2)

-->date 형입니다
DT 항목의 데이터 값의 저장형식은 뭘까요? (년월일만 / 시분초까지

-> 년원일 시분초 입니다,.

 


by 마농 [2016.08.29 15:48:16]

말씀 드렸던 대로 데이터 형을 맞춰주질 않았기 때문에 나는 에러입니다.
이 에러는 해당 쿼리가 수행되는 환경에 따라 다르게 동작합니다.
에러가 날 수도 있고 안날 수도 있습니다.


오늘 날짜보다 작은거 조회하는 거네요.
jkson 님 방법 대로 하면 됩니다.
  WHERE NVL(dt, sysdate) <= sysdate
시분초 제끼고 오늘날짜 전체로 하려면(현재시각 이후더라도 오늘날짜이면 조회)
  WHERE NVL(TRUNC(dt, 'dd'), sysdate) <= sysdate


by 푸르른 [2016.08.29 16:10:34]

두분다 답변 감사합니다 ..ㅠㅠ

 

혹시 jdbc 버전이나 드라이버 문제에서 생기는 부분일수 있나요 ?


by 마농 [2016.08.29 16:33:52]

자꾸 다른 소리 하시는구요.

자료형을 일치시키지 않은 채 함수를 사용하거나 값을 비교해서 그렇습니다.

이 경우 자료형을 맞추기 위해 묵시적 형변환을 시도하게 됩니다.

형변환 시도 시에 날짜 포멧을 지정하지 못하기 때문에 세션 기본 설정을 따라가게 됩니다.

이 때 형식이 운좋게 일치하면 에러 안나구요, 일치하지 않으면 에러납니다.

명시적으로 형변환을 해주는게 맞습니다.


by 푸르른 [2016.08.29 16:44:47]

운좋게 일치해서 테스트 환경에선 오류가 안났던거군요

답변감사합니다 명시적으로 형변환  명심하겠습니다 ^^;


by jkson [2016.08.29 16:32:19]

다시 올려주신 쿼리를 보니


to_char(NVL(DT,TO_DATE('19000101','YYYYMMDD')),'YYYYMMDD') <= SYSDATE


제일 바깥 to_char를 붙이신 이유는 truncate 때문인가요?


그렇다면 마농님 답변의  WHERE NVL(TRUNC(dt, 'dd'), sysdate) <= sysdate를 쓰셔야할 것 같구요.

 

위에 쿼리상으로는 to_char가 쓸데없이 씌워졌지만 서버 날짜형이 yyyy-mm-dd 인 게 맞다면 자동

변환되면서 문제가 생기지 않는 쿼리예요. 그래서 토드에서는 오류가 안 났겠죠.

말씀하신 것처럼 jdbc 버전에 따라서 쿼리 자동변환시 좌측 우측을 다른 형식으로 인지했다면

오류가 날수도 있겠네요. 로컬환경과 실제 운영 jdbc 환경 비교해보세요.


by jkson [2016.08.29 17:01:48]

똑같은 운영 DB에서, 똑같은 조회 조건으로 로컬에서는 오류가 안 나고 실제 운영 환경에서는

오류가 났다고 하셔서 jdbc쪽 문제일 수도 있겠다 생각하고 검색해보니

http://blog.naver.com/cchhooo21/110189135884

http://finkle.tistory.com/115

이런 글들도 있네요. 여튼 jdbc 환경도 비교해보시구요.

결론적으로는 형비교시에 양쪽 포맷이 달라서 나는 오류입니다.

마농님 말씀대로 평소에 명시적 형변환이 가능하게 쿼리 만드시구요^^;


by 푸르른 [2016.08.29 17:31:40]

 

네 답변 감사합니다 ㅎㅎ 그냥 넣어도 되는 쿼리들 무심하게 지나갔는데

제가 찾아본 결과는 nls_database_parameters 의 설정들과

nls_session_parameters 의 설정들이 달라서 날수도 있다고 생각하는데 이건 아닐까요?

답변 정말감사합니다

오늘도 많은것들을 배웠습니다 ㅠㅠ


by 마농 [2016.08.29 17:44:09]

NLS_DATE_FORMAT 에 영향을 받습니다.
Database 나 Instance 레벨에서 정의된 포멧도 있지만
결국은 Session 레벨에서 정의된 포멧을 따르게 됩니다.
각 유저별로 접속할 때 다르게 설정하면서 접속하기도 하며
각 사용툴(오렌지/토드/디벨로퍼 등) 별로도 다르게 설정하기도 합니다.
웹서버에서 다르게 설정할 수도 있겠지요.
이 설정값을 변경하여 오류를 잡는 것은 잠재적인 위험을 않고 가는 거죠.
서버를 변경하거나, 웹서버를 바꾸거나, 사용 툴을 바꾸거나... 등등
이런 외적인 환경요소에 영향을 받지 않도록 쿼리를 작성하는게 맞습니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입