2011-03-02 2 views
2

필자는 proc에 전달 된 매개 변수를 기반으로 Oracle 테이블에서 레코드를 검색하고 편집 할 수있는 웹 양식을 제공합니다. 여기에 내 데이터의 :오라클 nvl where 절에 이상한 결과가 표시됩니까?

CAE_SEC_ID SEC_CODE APPR_STATUS 
1   ABC1  100 
2   ABC2  100 
3   ABC3  101 
4   (null) 101 
5   (null) 102 
6   ABC4  103 

그리고 여기 where 절입니다 :

매개 변수의 값이있는 경우에만 일치하는 레코드를 반환해야 매개 변수에 NVL을 사용
select foo 
    from bar 
where CAE_SEC_ID = NVL(p_cae_sec_id,CAE_SEC_ID) 
    and Upper(SEC_CODE) like '%' || Upper(NVL(p_sec_code,SEC_CODE)) || '%' 
    and APPR_STATUS = NVL(p_appr_status, APPR_STATUS) 

, 모든 기록을 경우의 없음 매개 변수에는 값이 있습니다. 모든 꽤 표준 또는 그렇게 나는 생각했다. 그러나 매개 변수 값없이 검색을 수행하면 쿼리에서 null SEC_CODE 레코드가 반환되지 않습니다. 즉, 레코드 1, 2, 3 및 6 만 반환됩니다. 위의 where 절에 SEC_CODE 값이 null 인 레코드가 있어야합니까?

답변

4

아니요.

데이터베이스의 SEC_CODE가 null이므로 UPPER (SEC_CODE)가 null이므로 LIKE 일치 또는 IS NULL 이외의 다른 비교에서는 실패합니다. 기술적으로는 FALSE 라기보다는 UNKNOWN이지만 테스트를 통과하기에는 충분하지 않습니다.

7

테이블의 SEC_CODE 값이 NULL 인 것은 문제입니다. 즉 UPPER(sec_code)이 NULL이고, 두 번째 조건, 그것은 아무것도처럼되지 않습니다

NULL 아무것도 같고 아무것도하지 불평등없는 것처럼
and NULL LIKE '%%' 

로 단순화 것을 의미한다. 대부분의 경우, 당신은 P_SEC_CODE이 NULL 인 경우 모든 행을 반환하지만 P_SEC_CODE이 NULL이 아닌 경우 여전히 필터를 적용합니다

and (Upper(SEC_CODE) like '%' || Upper(NVL(p_sec_code,SEC_CODE)) || '%' or 
    (sec_code is null and p_sec_code is null)) 

같은 것을 원한다.

3

NULL = NULLNULL으로 계산되며 이는 true이 아니므로 이러한 행은 반환되지 않습니다. 내가 제대로 요구 사항을 이해한다면, 당신은 단지 매개 변수가 null과 다른 경우 필터링 할, 그래서 필터가 더 명확하게하기 위해이 같은 쿼리를 다시 작성합니다 :

select foo from bar 
where (p_cae_sec_id is null or CAE_SEC_ID = p_cae_sec_id) 
and (p_sec_code is null or Upper(SEC_CODE) like '%' || Upper(p_sec_code) || '%') 
and (p_appr_status is null or APPR_STATUS = p_appr_status) 

지금 null로 p_sec_code 매개 변수를합니다 설정 SEC_CODE 열의 값을 무시하고 모든 행을 반환합니다.

select foo from bar 
where (CASE WHEN p_cae_sec_id is null THEN 'Y' 
      WHEN CAE_SEC_ID = p_cae_sec_id THEN 'Y' 
        ELSE 'N' 
        END)='Y' 
and (CASE WHEN p_sec_code is null THEN 'Y' 
      WHEN Upper(SEC_CODE) like '%' || Upper(p_sec_code) || '%' THEN 'Y' 
        ELSE 'N' 
        END)='Y' 
and (CASE WHEN p_appr_status is null THEN 'Y' 
        WHEN APPR_STATUS = p_appr_status THEN 'Y' 
       ELSE 'N' 
       END)='Y' 

는 콘크리트 확인하고 성능을 향상시키기 위해 같은

0

우리는 또한 요른의 쿼리를 작성할 수 있습니다.

+0

흥미로운 점은 왜 이것이 성능을 향상시키는 지 자세히 설명해 주시겠습니까? –

관련 문제