SQLServer LEN함수의 잘못된 사용 내 밥줄

 S/W개발을 하다보면 늘 하던대로 해서 문제가 없던 것인데, 문제가 발생해서 당혹케하는
경우가 가끔 있다. 한 두번의 project가 아닌 몇 년간에 걸쳐 10개 이상의 프로젝트에서
적용을 했었는데 문제가 없던 것이 갑자기 문제가 생기는 경우, 이전의 것을 그대로 사용한
것에는 전혀 관심을 두지 않을 것이다. 문제가 발생한 프로젝트에서 수정되거나 추가된
부분을 보기 마련인데 여기서 time-consuming problem이 발생한다. 

 원인을 알고 나면 정말로 당연한 문제인데, 그것을 찾기 전까지는 과도한 믿음이 오히려
더 큰 cost를 발생할 수 있으니, 단정은 하지 말고 접근해야 할 것 같다.

(현상)
사용자에게 복수개의 input을 받아 처리하는 곳에서 입력된 값이 정상적으로 처리되지 않음.

*프로세스
1. 입력받은 값들을 구분자 row구분자 column구분자로 연결하여 하나의 string으로 웹서버에 전달.
2. 웹서버에서는 해당 값에 대한 validation없이 SQLServer의 stored procedure로 전달.
3. stored procedure에서는 해당 값을 parsing하는 user function을 통하여 table형태로
   돌려 받고 각 값들을 검증 후 입력


(원인)
입력된 data들이 상기 #3 프로세스에서 잘못 parsing되어 검증 프로세스를 통과하지 못하고 버려짐.
이는 parsing시 잘못된 len함수의 사용으로부터 기인함.
!!!LEN함수는 trailing space를 counting하지 않는다!!!

*예제 소스
-------------------------------------------------------------------------------
......(생략)
    IF CHARINDEX(@strDelim, @strText) > 0 BEGIN 
        SET @strValue = SUBSTRING(@strText,1, CHARINDEX(@strDelim,@strText)-1) 

        INSERT @retArray (IDX, VALUE) VALUES (@intIDX, @strValue)

        SET @iStrike = LEN(@strValue) + @iDelimlength 
        SET @intIDX = @intIDX + 1 
        SET @strText = LTrim(Right(@strText,LEN(@strText) - @iStrike)) 
        --!!!위의 구문이 잘못되었음 LEN함수는 trailing space는 count하지 않으므로
       
--@strText에 trailing space가 존재할 시 LEN(@strText)는 원하는 값을 return하지 않음.
    END
    ELSE BEGIN 
        SET @strValue = @strText 
       
        INSERT @retArray (IDX, VALUE) VALUES (@intIDX, @strValue) 

        SET @bContinue = 0 
    END 
......(생략)
-------------------------------------------------------------------------------


(해결)
LEN을 사용하지 않고 STUFF함수를 사용하여 처리
-------------------------------------------------------------------------------
......(생략)
   
        IF @v_intPosition > 0 BEGIN
            SET @v_strValue = SUBSTRING(@pi_strBuffer, 1, @v_intPosition-1)
   
            INSERT @retArray(IDX, VALUE)
                      VALUES(@v_intInx, @v_strValue)
   
            SET @v_intInx = @v_intInx + 1
            SET @pi_strBuffer = STUFF(@pi_strBuffer, 1, @v_intPosition+@v_intDelimiterLen, '' )
            --!!STUFF함수를 통하여 처리된 buffer만 삭제처리.
        END
        ELSE BEGIN
            SET @v_strValue = @pi_strBuffer
   
            INSERT @retArray(IDX, VALUE)
                      VALUES(@v_intInx, @v_strValue)
   
            SET @v_bContinue = 0
        END
    END
   
......(생략)
-------------------------------------------------------------------------------


[그림]BOL에서 LEN과 STUFF함수 설명


트랙백

이 글과 관련된 글 쓰기 (트랙백 보내기)
TrackbackURL : http://dialup.egloos.com/tb/963730 [도움말]

덧글

덧글 입력 영역