Programming/Database

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

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

첫번째 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;