[DB2] 문자열의 몇번째 구분자 정보 얻어오기/변경하기

Programming/Database 2010.08.11 댓글 Joshua95
특정 구분자로 나눠진 스트링에서 해당 구분자의 몇번째 값을 가져오라고 할때나, 몇번째 값을 변경하라고 할때 사용하는 함수를 작성했습니다. 그런데, 이게 여러번 호출되면 성능이 느려지는 문제가 있군요.
여튼 향후에 적절하게 사용할 때가 있을 듯 하여 올립니다.

첫번째 Get 계열 함수는 이전 게시물의 fnGetElements 함수를 사용해서 쉽게 구현이 되었고,
두번째 Set 계열 함수는 이래저래 막노동 끝에 구현되었습니다.
단발로 얻어오거나 수정할때 유용할 함수 일 겁니다. 단 앞에서 얘기한 것처럼 여러개를 얻어오고, 변경할 경우 성능적 이슈가 있으므로 자제하시길.

-- 문자열에서 특정 Delimeter의 요청된 index 번째 값을 반환한다.
-- 'BodyText의 3번째 파라미터 값을 가져오라' 는 식으로 사용하는 함수
CREATE FUNCTION fnGetStringToken( TargetString_ VARGRAPHIC(256), TargetIndex_ INT, Delimiter_ VARGRAPHIC(1))
RETURNS VARCHAR(256)
BEGIN ATOMIC
    RETURN
    SELECT ELEMENT FROM
    (
        SELECT ROW_NUMBER() OVER() AS idx, CAST(t.elem AS VARCHAR(256)) AS element
        FROM TABLE ( fnGetElements(TargetString_, Delimiter_) ) AS t(elem)   
    ) t
    WHERE t.idx = TargetIndex_;
END;


-- 문자열에서 특정 Delimeter로 구분된 파라미터의 값을 변경하여 반환한다.
-- 'BodyText'의 3번째 파라미터 값을 'xxx'로 변경하라' 는 식으로 사용되는 함수
CREATE FUNCTION fnSetStringToken( TargetText_ VARGRAPHIC(256), TargetIndex_ INT, TargetValue_ VARGRAPHIC(256), Delimiter_ VARGRAPHIC(1))
RETURNS VARCHAR(256)

BEGIN ATOMIC
     DECLARE SourceText_      VARGRAPHIC(15000);
     DECLARE Index_         INT DEFAULT 0;
     DECLARE Len_             INT DEFAULT 0;
     DECLARE Pos_             INT DEFAULT 1;
     DECLARE FindPos_         INT DEFAULT 0;
     DECLARE PreStr_          VARGRAPHIC(256) DEFAULT  '';
     DECLARE PostStr_         VARGRAPHIC(256) DEFAULT  '';
     DECLARE Token_            VARGRAPHIC(15000) DEFAULT  '';

    IF (TargetText_ IS NULL) THEN
        RETURN '';
    END IF;
   
    IF (TargetIndex_ <= 0) THEN
        RETURN TargetText_;
    END IF;
   
    SET SourceText_ = TargetText_;
    SET Len_ = LENGTH(SourceText_);
   
    WHILE ((Index_ < TargetIndex_) AND (Pos_ > 0))
    DO
        SET Pos_ = LOCATE(Delimiter_, SourceText_);
        SET FindPos_ = FindPos_ + Pos_;
        SET Token_         = LEFT(SourceText_, Pos_ - 1);
        SET SourceText_    = RIGHT(SourceText_, Len_ - Pos_);
        SET Len_         = LENGTH(SourceText_);
        SET Index_ = Index_ + 1;
    END WHILE;
   
    IF (FindPos_ <> 0) AND (FindPos_ > length(Token_)) AND (FindPos_ <= length(TargetText_)) THEN
        SET PreStr_ = LEFT(TargetText_, FindPos_ - length(Token_) - 1);
        SET PostStr_ = RIGHT(TargetText_, length(TargetText_) - FindPos_ + 1);
 
        RETURN  PreStr_ || TargetValue_ || PostStr_;--
    ELSE
        RETURN  '';--
    END IF;
END;

댓글