맨 먼저 다음 기사를 읽고, 문자열 분리 (및 수행하지 않을 이유)에 대해 논의하고 피할 수없는 경우 수행 할 방법의 성능을 비교하십시오.
- 피 구분 된 목록을 문자열 곳으로 :
이 세 기사의 결말은 (경우에 링크는 지금까지 죽은 될)입니다 가능하면 목록을 저장해야하는 경우 표가 훨씬 더 좋습니다.
- 수행해야 할 경우 CLR이 가장 확장 가능하고 정확한 방법입니다.
- 분할 할 특수 XML 문자가 없다는 것을 확신 할 수 있다면 구분 된 문자열을 XML로 변환 한 다음 XQuery를 사용하여 개별 항목을 올바르게 가져올 수 있습니다.
- 그렇지 않으면 교차 결합을 사용하여 집계 테이블을 만드는 것이 나머지 중 가장 좋습니다.
모두가 CLR을 사용하고, 특별한 XML 문자를 보장 할, 그래서에 대한 분할 방법은 수 있기 때문에 가장 다재다능한 방법은 마지막 :
CREATE FUNCTION [dbo].[Split]
(
@List NVARCHAR(MAX),
@Delimiter NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING AS
RETURN
( WITH N1 AS (SELECT N FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1), (1)) n (N)),
N2(N) AS (SELECT 1 FROM N1 a CROSS JOIN N1 b),
N3(N) AS (SELECT 1 FROM N2 a CROSS JOIN N2 b),
N4(N) AS (SELECT 1 FROM N3 a CROSS JOIN N3 b),
cteTally(N) AS
( SELECT 0 UNION ALL
SELECT TOP (DATALENGTH(ISNULL(@List,1))) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM n4
),
cteStart(N1) AS
( SELECT t.N+1
FROM cteTally t
WHERE (SUBSTRING(@List,t.N,1) = @Delimiter OR t.N = 0)
)
SELECT Item = SUBSTRING(@List, s.N1, ISNULL(NULLIF(CHARINDEX(@Delimiter,@List,s.N1),0)-s.N1,8000)),
Position = s.N1,
ItemNumber = ROW_NUMBER() OVER(ORDER BY s.N1)
FROM cteStart s
);
지금 당신은 당신의 분할 기능을 가지고
DECLARE @ActivityID AS VARCHAR(MAX) = 'BKR394859607,MTP293840284,SPN489620586';
SELECT Item,
NewID = LEFT(Item, 3)
FROM dbo.Split(@ActivityID, ',');
당신에게 제공합니다 :
Item NewID
-----------------------------
BKR394859607 BKR
MTP293840284 MTP
SPN489620586 SPN
을, 당신은 당신의 첫 번째 문자열을 분할 할 수 있습니다
그럼 당신은 FOR XML PATH()
를 사용하여이를 다시 연결할 수 있습니다 자세한 내용은
DECLARE @ActivityID AS VARCHAR(MAX) = 'BKR394859607,MTP293840284,SPN489620586';
SELECT STUFF((SELECT ',' + LEFT(Item, 3)
FROM dbo.Split(@ActivityID, ',')
FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 1, '');
을이 작품 this answer를 볼 방법에. , 구분 된 문자열을 구축하기보다는 그런
CREATE TYPE dbo.StringList AS TABLE (Value VARCHAR(MAX));
테이블 구축 : 다음
DECLARE @Activity dbo.StringList;
INSERT @Activity (Value)
VALUES ('BKR394859607'), ('MTP293840284'), ('SPN489620586');
을
최적의 솔루션은 아마도 문자열 목록을 저장하는 사용자 정의 테이블 형식을 가지고하는 것입니다 당신은 고통스럽지 않은 분할을 피하고, 각 개별 기록을 쉽게 조작 할 수 있습니다. 당신이 정말로 새로운 구분 된 문자열을 얻을 필요 않은 경우
는, 당신은 위와 동일한 논리를 사용할 수 있습니다
DECLARE @Activity dbo.StringList;
INSERT @Activity (Value)
VALUES ('BKR394859607'), ('MTP293840284'), ('SPN489620586');
SELECT STUFF((SELECT ',' + LEFT(Value, 3)
FROM @Activity
FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 1, '');
당신이 구분 된 목록 대신 임시 테이블, 테이블 변수 나 테이블 반환 매개 변수를 사용할 수 –
항상 처음 세 글자 수 있습니까? 이것을 문자열로 처리하려면 먼저 테이블로 분할 한 다음 처음 세 문자를 제외하고 모두 제거한 다음 다시 모두 구분 된 목록으로 다시 밀어 넣어야합니다. –
예 접두사는 항상 처음 세 글자입니다. 또한 SQL Server 2014를 사용하고 있습니다. – GnisPL