안녕하세요!
큐ㅓ리를 짜다가 막히는 부분이 있어서 문의글 남깁니다 ㅠㅠ
A 테이블 칼럼에 길이 칼럼이 있는데 varchar2거든요...?
여기서 숫자값만 뽑아내어 범위조회하려 하는데요
select *
from (
select to_number(길이)
from (
select 길이
from A
where not regexp_like(길이,'[^0-9.^0-9]')
)
) where 길이>='1000'
위같ㅇ 쿼리 짰는데 실행하니 수치가 부적합하는 오류가 발생합니다ㅠㅠ
찾아보니까 묵시적형변환때문일거라는 얙가 많던데 아무리 봐도 잘 모르겠습니다 ㅠㅠㅠ도와쥬세요..
아 그리고 해당 길이칼럼에는 소숫점도 존재합니다..!
regexp_like(길이,'[^0-9.^0-9]') 는 잘 못 사용된 정규식이네요.
^0-9 을 두번 사용했지만 대괄호 안에서의 두번 사용은 무의미합니다.
^ 은 대괄호 안 문자들의 전체 부정을 의미합니다.
따라서 두번째 사용한 ^ 은 부정이 아닌 그냥 문자일 뿐이구요.
해석하면 숫자(0-9)랑 쩜(.)이랑 눈섭(^)이 아닌 문자죠.
따라서 쩜이 두번 들어가거나 눈섭이 들어간 문자가 걸러지지 않겠네요.
이런 오류 데이터를 숫자로 치환하면 에러나구요.
길이 >= '1000' 이조건은
길이 >= 1000 이렇게 바꿔야 의미상 맞습니다.
그런데 이 조건은 서브쿼리 안으로 파고들 가능성이 높구요.
이렇게 되면 오류자료 제외시키기 전에 이 조건이 먼저 수행될 수도 있습니다.
그러면 걸러지지 않은 오류자료로 인해 숫자에러 발생됩니다.
서브쿼리 안의 SELECT 절에 ROWNUM 을 추가해 보세요.
그러면 조건 침투가 안됩니다.
사용자가 작성한 쿼리 그대로 실행되지 않고
좀더 효율적인 쿼리로 변경하여 실행하려고 노력합니다.
이를 쿼리 변환이라고 하고요, 쿼리 변환은 여러가지 형태로 나타납니다.
위의 경우는 제가 표현을 잘못 했네요.
조건절이 안으로 침투하는게 아니라
서브쿼리가 밖으로 합쳐지는 뷰머징 입니다.
ROWNUM 은 뷰머징을 방지하는 여러 기법중 하나입니다.
실제 수행이 어떻게 되는지는 실행계획을 확인하셔야 합니다.
http://wiki.gurubee.net/pages/viewpage.action?pageId=26745078