decode 문장 이해불가.. 0 19 1,594

by 신성철 [2012.10.29 16:01:34]


ORACEL 9i 입니다.
DECODE  절 관련해서 질문 드립니다.

APPLICATION DISABLEBIND 관련해서...
   
--> WHERE  A.JEPUM_CODE = DECODE('' , '',  A.JEPUM_CODE, '')  

위의 WHERE 절이 질의가 안되는건지..데이타가 안나옵니다.

제 생각에는 
 
 --->   WHERE A.JEPUM_CODE = A.JEPUM_CODE
 
 와 같은 쿼리 결과가 나와야 될것 같은데요.

실제로 WHERE A.JEPUM_CODE = A.JEPUM_CODE
이문장으로 대치하고 쿼리해보면 결과값이나옵니다...
 


참고로....

SELECT DECODE('','','AAAA','') FROM DUAL;

하면 'AAAA'라는 결과값을 가져옵니다.


  
 
by 아발란체 [2012.10.29 16:09:17]
SELECT DECODE('' , '', A.JEPUM_CODE, '') FROM
위 구문은
SELECT A.JEPUM_CODE FROM
와 같은 말입니다.

즉 DECODE를 쓰나 않쓰나 동일한 결과가 나옵니다.

SELECT DECODE('' , '', A.JEPUM_CODE, '') FROM
설명은
첫번째 값이 두번째 값과 같으면 세번째 값을 출력해라
첫번째 값이 두번째 값과 다르면 네번째 값을 출력해라
인데
쓰신 구문은 첫번째 값 ''와 두번째 값 ''가 항상 같기 때문에 세번째 값을 출력합니다.


by 신성철 [2012.10.29 16:17:23]

아발란체님 댓글 감사드립니다.
제가 이해한것도 님의 말씀과 같아요
그렇다면 SELECT 문이아닌.... WHERE 에 들어갔다면

WHERE  A.JEPUM_CODE = DECODE('' , '',  A.JEPUM_CODE, '')   이문장은.
WHERE A.JEPUM_CODE = A.JEPUM_CODE 과 같은 의미 일테고
그렇다면 모든데이타가 나와야 될텐데
데이타가 한건도 안나오게 됩니다.

그래서 질문 드렸습니다....


by 아발란체 [2012.10.29 16:52:37]

오홍, ㅠ,.ㅠ 그렇군요. 제가 이해력이....
아래거 돌려보시고 어떻게 나오는지 확인가능할까요?

WITH A(JEPUM_CODE, F2, F3) AS (
    SELECT '1', 1, 3 FROM DUAL UNION ALL
    SELECT '', 2, 3 FROM DUAL UNION ALL
    SELECT NULL, 3, 3 FROM DUAL
)
SELECT * FROM A WHERE A.JEPUM_CODE = DECODE('', '', A.JEPUM_CODE, NULL)


by 마농 [2012.10.29 17:33:45]

버그일듯.


by 신성철 [2012.10.29 18:24:24]

WITH A(JEPUM_CODE, F2, F3) AS (
    SELECT '1', 1, 3 FROM DUAL UNION ALL
    SELECT '', 2, 3 FROM DUAL UNION ALL
    SELECT NULL, 3, 3 FROM DUAL
)
SELECT * FROM A WHERE A.JEPUM_CODE = DECODE('', '', A.JEPUM_CODE, NULL)

이문장 9i 에선 안먹히는 구문인거 같네요~

by 마농 [2012.10.29 18:37:07]

With 구문의 컬럼 알리아스는 11g 부터 되구요.
9i에서는 Select 절에 알리아스 주셔야 합니다.
WITH a AS
(
SELECT '1' jepum_code, 1 f2, 3 f3 FROM dual


by 손님 [2012.10.30 08:51:39]
9i에 맞게 아래와같이 수정후 쿼리해보니.....
첫번째 row 만 가져오네요..두번째 , 3번째row 는 못 가져 옵니다.

WITH A AS (
    SELECT '1'   jepum_code , 1 , 3 FROM DUAL UNION ALL
    SELECT ''    jepum_code , 2 , 3 FROM DUAL UNION ALL
    SELECT NULL  jepum_code , 3 , 3 FROM DUAL
)
SELECT * FROM A WHERE A.JEPUM_CODE = DECODE('', '', a.JEPUM_CODE, NULL)

by 마농 [2012.10.30 09:14:23]

그럼 결과는 정상입니다.


by 신성철 [2012.10.30 09:23:54]

마농님 그럼 결과가 정상이라면 
DECODE('', '', a.JEPUM_CODE, NULL) 이런문장은 사용하면 안된다는건데..

어플리케이션 ( 파워빌더) 에서...
WHERE A.JEPUM_CODE = DECODE( :arg_jepum, :arg_jepum', a.JEPUM_CODE, :arg_jepum)

이렇게 작성후 아규먼트로  '' 를 넘기면 조회가 안된다는 이야기가 되는데요..
이게좀 문제가 있네요..

by 마농 [2012.10.30 09:41:41]
위에 올리신건 이상하네요. 이렇게 하는게 맞겠죠.
WHERE A.JEPUM_CODE = DECODE( :arg_jepum, '', a.JEPUM_CODE, :arg_jepum)
또는 이렇게...
WHERE A.JEPUM_CODE = NVL( :arg_jepum, a.JEPUM_CODE)
하지만 이렇게 사용할 때 주의사항은 컬럼에 널이 포함되면 안나온다는 것이죠.
널포함 컬럼에 조건을 주려면 위와 같이 하시면 안됩니다.
다음과 같이 하세요.
WHERE (:arg_jepum IS NULL OR A.JEPUM_CODE = :arg_jepum)



by 신성철 [2012.10.30 10:05:14]

WHERE A.JEPUM_CODE = DECODE( :arg_jepum, '', a.JEPUM_CODE, :arg_jepum)
이렇게 해도 결과는 마찬가지 인거아닌가요?

아규먼트로 '' 를 넘긴다면 결국
DECODE('', '', a.JEPUM_CODE, '') 이걸로 쿼리할테고 그럼 데이타가 안나오니까요....

by 마농 [2012.10.30 10:25:51]
위의 테스트 예제 3건 중 널이 아닌 1건은 나오지요.
해당 항목에 널이 포함되지 않는다면 위처럼 사용해도 됩니다.
하지만 테스트 예제에서 처럼 널이 들어있다면 위처럼 사용해서는 안되겠지요.
여기까지는 정상적인 상황에서의 얘기이구요.
님께서 안된다고 하신 상황이 정상적이지 않은 버그의 상황이라면 앞의 얘기는 모두 헛수고지요.
버그에는 답이 없죠.

by 신성철 [2012.10.30 10:29:02]
 

이거  해깔리네요
결론적으로 제가 궁금햇던 것은

1번
A.JEPUM_SIZE = DECODE(:ARG_JEPUM_SIZE , '',  A.JEPUM_SIZE, :ARG_JEPUM_SIZE)

2번
A.JEPUM_SIZE = DECODE( '' , '',  A.JEPUM_SIZE, :ARG_JEPUM_SIZE)

1번으로 쿼리해서 아규먼트를 넘기면 데이타 조회됨
2번으로 직접 아규먼트가 아닌 '' 로 직접 쿼리를 날리면 조회가 안됨.

요 두가지 차이 입니다.
오라클 옵티마이저( 맞나요?)  가 1번은 쿼리를 일단 받아들인 후 아규먼트를 받아들어셔 쿼리하니까 되고
2번은 옵티마이저가 바로 쿼리문 분석해서 이건 아니다 싶어서 걸러버리는 머 이런차인건지....
ㅡㅡ.


by 마농 [2012.10.30 10:29:35]

우선 지금의 상황이 정상적인 오류인지? 버그인지 판단하셔야 합니다.
그리고, 해당 오류 혹은 버그를 피할 수 있는 다른 방법으로 코드를 바꾸셔야 하겠지요.


by 신성철 [2012.10.30 10:35:39]

마농님 감사합니다..
좀더 연구해봐야겠네요.. ㅡㅡ

참고로...메신저 사용하신다면...실례가 안되시면...등록 부탁드려도 될까요?
ppung1@nate.com

by 마농 [2012.10.30 10:36:09]

지금 제시 하신 2번 쿼리도 직접 '' 을 대입했다 하셨지만 뒤에는 아규먼트가 있네요..
두서 없이 글을 써서 그런것인지? 계속 틀린 글이 올라오니 쉽사리 판단이 서질 않습니다.
정말로 안된다면 버그이겠지만...
뭔가 실수하신게 아닌지 의심이 들기도 하구요..
(지금까지 올라온 글들이 앞뒤가 안맞는 부분과 틀린 부분들이 눈에 많이 띠어서요)

일단 해당 컬럼에 널이 들어 있는지요? 그렇다면 위와 같은 코드는 틀린 코드입니다.
다르게 바꿔어 사용해야 맞겠지요...


by 마농 [2012.10.30 13:11:20]

다른 조건 다 빼고 그조건 하나만으로 테스트하신것 정말 맞죠?
일단 결과가 나와야 하는 것이 정상입니다.
결과가 안나온다면 버그입니다.
패치를 하시던지, 버전업을 하시던지 해야 하겠지만...
여의치 않다면 버그가 발생하지 않는 다른 방식으로 코드를 변경하셔야겟지요.
참고로 '' 은 Null 입니다.
WHERE a.jepum_size = NVL(:arg_jepum_size, a.jepum_size) -- Not Null 일때
WHERE a.jepum_size LIKE :arg_jepum_size||'%' -- 문자타입일때
-- 널과 상관 없이...
WHERE (:arg_jepum_size IS NULL OR a.jepum_size = :arg_jepum_size)


by 신성철 [2012.10.30 13:42:10]
 

마농님....
제가 자꾸 이랫다 저랫다 햇던 이유가 있네요
제가 테스트를 하면서 실제 테이블 데이타로도 테스트 하다가...
WITH 구문으로도 테스트를 하다가 했거든요
어쨋든 똑같은 결과값이 나와야 되는거같은데  아닌가 봅니다.

-----실제 테이블 적용데이타 -----
 - 쿼리 안나옵니다
 - 실제로  JEPUM_SIZE 는 NULL 데이타는 없습니다.
 -- 쿼리를  다음처럼 NVL처리하면 됩니다
     JEPUM_SIZE = DECODE( NVL('','') ,NVL('',''),  A.JEPUM_SIZE, '')

SELECT  A.MA_ILJA,
A.MA_WGT,
A.MA_DANGA,
A.GONG_AMT,
  A.JEPUM_SIZE,
  LENGTH(A.JEPUM_SIZE) 
  FROM SMDHP.SM_MA    A
 WHERE A.JEPUM_SIZE = DECODE( '' ,'',  A.JEPUM_SIZE, '') 
 
 -- WITH 절로 가공데이타 -----
    -  쿼리결과가 나옵니다. (맨마지막 NULL 인것 빼고 2개의 ROW 가 질의결과 나옵니다.)
 
 WITH A AS (
    SELECT  '1'    JEPUM_SIZE , 1 COL1, 1 COL2 FROM DUAL UNION ALL 
    SELECT  '    ' JEPUM_SIZE , 1 COL1, 2 COL2 FROM DUAL UNION ALL   
    SELECT NULL    JEPUM_SIZE , 1 COL1, 3 COL2 FROM DUAL
)
SELECT A.JEPUM_SIZE , COL1, COL2 FROM A
WHERE  A.JEPUM_SIZE = DECODE( '' ,'',  A.JEPUM_SIZE, '')   

====================================================================
똑같은 버전의 오라클인데...
두개의 질의(실제데이타 기준, WITH절 기준)   에서 ...

1번 질의(실제데이타) 에서 데이타가 안나오는것이  이해안되고

2번 질의는 또 데이타가 나오는거도 이상하네요


by 신성철 [2012.10.30 13:43:06]

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