2011-02-01 4 views
0

나는 문자열을 가지고있다. SQL 서버 문자열 문자열은

d

는 변수이므로 1, 3, 20, 될 수 ... 등

나는 D의 값을 알고 있지만, 제가 모르는의 문자열을 얻는 방법이다 원래 문자열 d 용어입니다.

나는이 시도 :

@L = '' 
SET @ColumnNo = 0 
WHILE @ColumnNo <= @d 
BEGIN 
    SET @L = @L + ' ' + SUBSTRING(@TempCol, 1, CHARINDEX(',',@TempCol)-1) 
    SET @TempCol = REPLACE (@TempCol, LTRIM(RTRIM(@L)) ,'') 
    Set @ColumnNo = @ColumnNo + 1 
    PRINT @L 
END 

을하지만 예상되는 결과를 얻을하는 방법을 모르겠어요.

+0

'@ L'은 처음으로 '@ L'로 초기화되고 'L'은 무엇입니까? –

+0

죄송합니다. @ L이 아니기 때문에 잘못 썼습니다. 연결하려고 시도했지만 성공하지 못했습니다. @L = ''와 같이 초기화됩니다. – cMinor

+0

기본적으로 문자열'@TempCol = 'item1, item2, ...'에서 첫 번째'@d' 항목을 포함하는 부분 문자열을 추출하려고합니다. 그게 맞습니까? –

답변

1
DECLARE @TempCol varchar(max), @d int, @p int, @Result varchar(max); 
SET @TempCol = 'item1,item2,itemA,itemB,item#,item$'; 
SET @d = 3; 

SET @p = 1; 

WHILE @d > 0 AND @p > 0 BEGIN 
    SET @p = CHARINDEX(',', @TempCol, @p); 
    IF @p > 0 SET @p = @p + 1; 
    SET @d = @d - 1; 
END; 

IF @p = 0 
    SET @Result = @TempCol 
ELSE 
    SET @Result = SUBSTRING(@TempCol, 1, @p - 2); 

SELECT @Result; 

기본적으로, 루프 그냥 검색을 자를 최종 위치. 루프는 이후에 부분 문자열이 으로 추출됩니다.

@d을 너무 크게 지정하면 결과는 모두 @TempCol이되며, 그렇지 않은 경우 원하는 수의 항목이 생성됩니다.

1

필요한 기능은 분할 기능입니다 (하단에 표시). 주어진 점에 조립 된 문자열을 원하는 경우

With SplitItems As 
    (
    Select Position, Value 
     , Row_Number() Over (Order By Position) As ItemNum 
    From dbo.udf_Split(@TempCol, ',') 
    ) 
Select Value 
From SplitItems 
Where ItemNum <= @d 

당신은 간단 할 것 :

With SplitItems As 
    (
    Select Position, Value 
     , Row_Number() Over (Order By Position) As ItemNum 
    From dbo.udf_Split(@TempCol, ',') 
    ) 
Select ',' + Value 
From SplitItems 
Where ItemNum <= @d 
Order By ItemNum 
For Xml Path('') 

분할 기능 :

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
Create FUNCTION [dbo].[udf_Split] 
( 
    @DelimitedList nvarchar(max) 
    , @Delimiter nvarchar(2) = ',' 
) 
RETURNS TABLE 
AS 
RETURN 
    (
    With CorrectedList As 
     (
     Select Case When Left(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End 
      + @DelimitedList 
      + Case When Right(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End 
      As List 
      , Len(@Delimiter) As DelimiterLen 
     ) 
     , Numbers As 
     (
     Select TOP(Coalesce(DataLength(@DelimitedList)/2,0)) Row_Number() Over (Order By c1.object_id) As Value 
     From sys.columns As c1 
      Cross Join sys.columns As c2 
     ) 
    Select CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen As Position 
     , Substring (
        CL.List 
        , CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen  
        , CharIndex(@Delimiter, CL.list, N.Value + 1)       
         - (CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen) 
        ) As Value 
    From CorrectedList As CL 
     Cross Join Numbers As N 
    Where N.Value <= DataLength(CL.List)/2 
     And Substring(CL.List, N.Value, CL.DelimiterLen) = @Delimiter 
    ) 
+0

하나의 질문은 동적 SQL을 사용하기 때문에 어떻게 저장 프로 시저에서이 UDF를 사용할 수 있습니까 ??, 전화를 걸었지만 오류가 있습니까 ?? 저장 프로 시저에서 루프 만 사용하는 방법이 있습니까? – cMinor

+0

@darkcminor - 동적 SQL을 사용하여 정확히 무엇을 (그리고 왜)? 분할 된 UDF를 자주 재사용 할 수 있도록 영구적으로 만들 수 있습니다. 첫 번째 쿼리 만 작성하거나 어셈블해야합니다. – Thomas