SQL Double Split

Posted in .NET Framework // Posted at 2013. 11. 13. 18:38
728x90

SQL에서 Split 함수 구현은 쉽게 찾을 수 있다. 그런데 프로젝트 진행 중, 내가 필요한 것은 더블 스플릿이다.

(더블 스필릿이라는 공식 명칭은 없다. 그냥 내 맘대로 붙여 먹은 이름이니 어디가서 들먹이면 안됨!)

 

즉 하나의 구분자로 문자들을 분리하고, 분리된 문자에는 또 다시 구분자가 있어 다시 스필릿 해야 하는 구조.

대략 다음과 같이...

 

: key1=value1,key2=value2,key3=value3

 

위 예시에서 첫번째 구분자는 콤마(,)이고 두번째 구분자는 이꼴(=)이다.

이 값을 차례대로 분리해서 테이블 형태로 반환하고 싶은 것이다.

 

과거 훌륭한 DBA로 부터 수급한 싱클 스플릿 함수 구현체에, 꾸역꾸역 더블 스플릿이 가능하도록 끼워넣었다.

사소하게 기뿌다 ^^;

 

ALTER FUNCTION [dbo].[UFN_DoubleSplit] (@STRMORE AS VARCHAR(8000),@STRDELIMETER1 AS VARCHAR(10),@STRDELIMETER2 AS VARCHAR(10)) 
RETURNS @RETURN_TABLE TABLE
(
    idx int identity(1,1)
,   strVALUE1 VARCHAR(500)
,   strVALUE2 VARCHAR(500)
)
AS
BEGIN
DECLARE
    @NINDEX   INT
, @NINDEX2  INT
,   @DEL_LENGTH INT
, @SUBSET  VARCHAR(100)
,   @STRVALUE1  VARCHAR(100)
,   @STRVALUE2  VARCHAR(100)
 
SET @DEL_LENGTH = LEN(@STRDELIMETER1)
 
WHILE LEN(@STRMORE) > 0
    BEGIN
   
        SET @NINDEX = CHARINDEX(@STRDELIMETER1, @STRMORE)
 
        IF (@NINDEX = 0)
        BEGIN      
   SET @NINDEX2 = CHARINDEX(@STRDELIMETER2, @STRMORE)
   SET @STRVALUE1 = SUBSTRING(@STRMORE, 0, @NINDEX2)
   SET @STRVALUE2 = SUBSTRING(@STRMORE, @NINDEX2 + 1, LEN(@STRMORE))      
   INSERT @RETURN_TABLE (strVALUE1,strVALUE2) VALUES (@STRVALUE1,@STRVALUE2)
   RETURN
        END       
        ELSE IF (@NINDEX = 1)
        BEGIN
   SET @STRMORE = SUBSTRING(@STRMORE, @DEL_LENGTH + 1, LEN(@STRMORE))
   CONTINUE
        END
 
        SET @SUBSET = SUBSTRING(@STRMORE, 0, @NINDEX)
        SET @NINDEX2 = CHARINDEX(@STRDELIMETER2, @SUBSET)
        SET @STRVALUE1 = SUBSTRING(@SUBSET, 0, @NINDEX2)
  SET @STRVALUE2 = SUBSTRING(@SUBSET, @NINDEX2 + 1, LEN(@SUBSET))                                               
        INSERT @RETURN_TABLE (strVALUE1,strVALUE2) VALUES (@STRVALUE1,@STRVALUE2) 
                 
        SET @STRMORE = SUBSTRING(@STRMORE, @NINDEX + @DEL_LENGTH, LEN(@STRMORE) - @NINDEX)   
    END
RETURN
END

 

 

2014.02.21 업데이트>>

이 글을 작성하고 난 뒤 'Double Split'를 프로젝트에 적용해서 잘 사용하던 중, Split 해야 할 또 하나의 값이 추가되어 버렸다.

 

즉,  Double Split 기준의 매개변수인 'key1=value1,key2=value2,key3=value3' 형태가 다음처럼 바뀌었다.

: key1=value1&value11,key2=value2&value22,key3=value3&value33

 

그렇다면, Triple Split를 다시 구현할 것인가???

이런.. 유연성이 전혀 없잖어. 또 다른 기준 값이 추가되면 역시 힘겹게 수정해야 한다. 사실 이 글에서 제시한 Split 구현이 그리 깔끔하거나 쉽게 확장가능한 코드가 아니다.

 

결국 XML형태로 매개변수를 입력 받고 파싱해서 테이블로 반환하기로 했다. 구현이 훨씬 깔끔해져 나중에 수정을 하려고 해도 쉽게 가능해 진다.

 

Double Split 이여 안녕~~

 

CREATE FUNCTION [dbo].[UFN_ConvertFromXmlToTable] (@XMLString AS NVARCHAR(MAX))
RETURNS @RETURN_TABLE TABLE
(
    idx int identity(1,1)
,   strValue1 VARCHAR(500)
,   strValue2 NVARCHAR(100)
,   intValue  BIGINT
)
AS
BEGIN
 declare @xml xml = cast(@XMLString as xml)
    
 INSERT @RETURN_TABLE (strValue1,strValue2,intValue)
  select
     x.value('data(@strValue1[1])', 'VARCHAR(500)')
   , x.value('data(@strValue2[1])', 'NVARCHAR(100)')
   , x.value('data((text())[1])', 'BIGINT')
   from
    @xml.nodes('/s') x(x)

RETURN
END

  

 그리고 이렇게 활용하면 된다.

SELECT * FROM dbo.[UFN_ConvertFromXmlToTable]('<s strValue1="1" strValue2="11">1000</s><s strValue1="2" strValue2="22">2000</s><s strValue1="3" strValue2="33">3000</s>')

 

 

'.NET Framework' 카테고리의 다른 글

ASP.NET SignalR  (0) 2013.12.06
maxConcurrentSessions in WCF  (0) 2013.11.21
Optimizing IIS Performance  (2) 2013.11.07
클라이언트의 동시 연결 수(maxconnection)  (0) 2013.11.06
비동기 프로그래밍에서의 메모리 누수  (0) 2013.11.06