반응형
스크립트 변환을 이용한 문자열 분리


한대성

MS SQL Server MVP

에이디컨설팅 책임 컨설턴트 | SQLLeader.com 운영자


Question
[A]가 [B제품]을 발송하였다.
[A]가 [C 제품]을 [D] 에게 판매하였다.
[B]가 [K지역]에서 [A]에게 물품을 구매하였다

이런식입니다;;;
앞에 category열이 발송/판매/거래 등의 의미로 구분할수 있지만, 실제 저 텍스트를 분석해서 테이블로 밀어넣고 분석해야 합니다.

문자열에서 위처럼 [] 토큰 등으로 구분가능합니다. 다만, 순서가 다를수 있습니다
현재 분석할수 있는 자료는 아래처럼 테이블로 데이터를 정리한게 있습니다.

10 [주체] [제품]
20 [주체] [제품] [대상]

문자열 파싱하는데 스크립트 작업이 필요할텐데..저 데이터 정의 테이블을 어떻게 끌고와서
응용해야될지 모르겟습니다.


(우선 제가 질문의 의도를 정확히 이해 했는지 확신을 못하겠습니다. 만약 잘못 짚었다면 그냥 다음 내용을 참고만 하시기 바랍니다.^^)

다음과 같은 처리 방식을 생각해 보겠습니다.

우선, 입력되는 문자열 데이터에서 [..] 형태의 토큰을 분리해 내는 작업을 먼저 수행합니다.

이를 구현하기 위해서는 스크립트 변환 요소를 이용해서 입력된 문자열을 이용해서 이를 분리하는 기능을 구현합니다.


단순히 토큰만 분리해 내는 것이 아니라 분석 대상 자료와 비교를 해야 합니다.

하지만, 어떤 경우에는 다음과 같이
     
[주체] [제품] [대상]

으로 입력이 될 수 있지만 
     
[주체] [대상] [제품]

또는
     
[대상] [주체] [제품]

형식으로 입력이 될 수도 있을 것입니다.


이에 대한 처리를 위해서 저는 다음과 같은 (단순 & 무식한) 방법을 생각해 보았습니다.

『토큰을 정렬해서 출력하고, 분석 대상 또한 정렬한 후 비교하자. 』 입니다.


예를 들어,

       [B] [K지역]에서 [A]에게 물품을 구매하였다.

[B] [K지역] [A] 라고 토큰이 분리되겠지만, 이를 [A] [B] [K지역] 이라고 정렬해서 출력한다는 것입니다.


주체와 제품, 대상이 서로 성격이 다른 데이터(예를 들어, 사람 이름과 지역 명, 제품 명 등)인 경우에는 서로 동일한 데이터가 거의 없기 때문에 이와 같이 정렬을 해서 비교를 하여도 잘못된 비교를 할 확률이 낮지 않을까라고 가정해봤습니다.


여기까지가 저 혼자의 망상(^^)으로 만들어 낸 시나리오이고, 이를 바탕으로 다음과 같은 스크립트 변환 작업을 작성해 봤습니다.

(이것 짜서 올리면 저의 프로그래밍 실력이 뽀록(!)나기에 많이 고민하다가 그냥 참고하시고 잘 변형해서 사용하시라고..)


데이터 읽어오는 부분이나 분석 대상 테이블과의 비교는 조회 변환 등을 참고해서 구현해 보시고 스크립트 변환 부분만을 올립니다.





Imports System

Imports System.Data

Imports System.Math

Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper

Imports Microsoft.SqlServer.Dts.Runtime.Wrapper

 

Public Class ScriptMain

    Inherits UserComponent

 

    Public Overrides Sub 입력0_ProcessInputRow(ByVal Row As 입력0Buffer)

 

        Row.ParseStr = StringExtraction(Row.context, "[", "]")

 

    End Sub

 

 

    Public Function StringExtraction(ByVal sExpression As String, _

                                    ByVal sNearFrontString As String, _

                                    ByVal sNearBackString As String, _

                                    Optional ByVal oCompareMethod As CompareMethod = CompareMethod.Text) As String

 

        Dim Result(10) As String

        Dim ResultSeed As Integer = 0

        Dim tmpString As String

        Dim StartPoint As Integer

        Dim EndPoint As Integer

        Dim ResultStr As String

        Dim i As Integer, j As Integer

 

        Try

 

            '입력값 유효성 판단

            If sExpression.Length = 0 Or sExpression Is Nothing Then Exit Try

            If sNearFrontString.Length = 0 Or sNearFrontString Is Nothing Then Exit Try

            If sNearBackString.Length = 0 Or sNearBackString Is Nothing Then Exit Try

 

            For i = 1 To sExpression.Length

                StartPoint = InStr(sExpression, sNearFrontString, oCompareMethod)

                If StartPoint <= 0 Then Exit For

 

                tmpString = Mid(sExpression, StartPoint)

                EndPoint = InStr(sExpression, sNearBackString, oCompareMethod)

                Result(ResultSeed) = Mid(sExpression, StartPoint, EndPoint - StartPoint + 1)

                sExpression = Mid(sExpression, EndPoint + 1)

                i = i + EndPoint

                ResultSeed += 1

            Next

 

            '결과 데이터 정렬

 

            For i = 0 To ResultSeed - 1

                For j = i + 1 To ResultSeed - 1

                    If Result(j) < Result(i) Then

                        tmpString = Result(i)

                        Result(i) = Result(j)

                        Result(j) = tmpString

 

                    End If

                Next

            Next

 

            '결과 데이터 준비

            ResultStr = Result(0)

            For i = 1 To ResultSeed - 1

                ResultStr += "," + Result(i)

            Next

 

 

        Catch ex As Exception

            ResultStr = ""

 

        End Try

 

        Return ResultStr

 

    End Function

 

 

 

End Class




반응형

+ Recent posts