2015-11-26 35 views
1

我的记录如下,它是固定长度。每个数据之间都有空格。如何在SQL Server 2012中拆分字符串?

123 870503-23-5370 021 456 830503-23-5371 031 789 870103-11-5372 041 654 870501-23-5373 051 321 880503-12-5374 061 987 870803-23-5375 071 109 870508-06-5376 081 174 810503-03-5377 091 509 870103-01-5378 101 687 870501-12-5379 131 

通过使用SQL Server 2012的存储过程,我想下面把它分解:

123 870503-23-5370 021 
456 830503-23-5371 031 
789 870103-11-5372 041 
654 870501-23-5373 051 
....... 
+2

谷歌:“SQL Server的分裂” –

回答

0

我创建了一个循环遍历每个迭代集,直到达到字符串的长度。使用你的榜样值的测试

CREATE PROCEDURE [dbo].[SplitMyFunkyText] @Source nvarchar(MAX) 
AS 
    DECLARE @Results AS TABLE(Part NVARCHAR(22)) 
    DECLARE @I INT = 1 

    WHILE @I < LEN(@Source) 
    BEGIN 
     INSERT INTO @Results 
      SELECT SUBSTRING(@Source, @I, 22) 

     SET @I = @I + 23 
    END 

    SELECT * FROM @Results 
GO 

这里:

DECLARE @Source AS NVARCHAR(230) 

SET @Source = '123 870503-23-5370 021 456 830503-23-5371 031 789 870103-11-5372 041 654 870501-23-5373 051 321 880503-12-5374 061 987 870803-23-5375 071 109 870508-06-5376 081 174 810503-03-5377 091 509 870103-01-5378 101 687 870501-12-5379 131' 

EXEC SplitMyFunkyText @Source 

以下是测试结果:

123 870503-23-5370 021 
456 830503-23-5371 031 
789 870103-11-5372 041 
654 870501-23-5373 051 
321 880503-12-5374 061 
987 870803-23-5375 071 
109 870508-06-5376 081 
174 810503-03-5377 091 
509 870103-01-5378 101 
687 870501-12-5379 131 

按你的第二个问题:然后酿是到存储过程中“如果我的拆分记录不在固定位置“

您最初表示”固定长度“,这很容易。

CREATE PROCEDURE [dbo].[SplitMyFunkyText] 
    @Source nvarchar(MAX) 
AS 
    DECLARE @Results AS TABLE(Part NVARCHAR(22)) 

    DECLARE @I INT = 1 
    DECLARE @NextLength INT = -1 
    DECLARE @SubPart1 NVARCHAR(20) 
    DECLARE @SubPart2 NVARCHAR(20) 
    DECLARE @SubPart3 NVARCHAR(20) 

    WHILE @I < LEN(@Source) 
    BEGIN 
     -- GET 1st SubPart ----------------------------------- 
     SET @NextLength = CHARINDEX(' ',@Source,@I) 

     IF @NextLength > 0 
      SET @SubPart1 = SUBSTRING(@Source, @I, @NextLength - @I) 
     ELSE 
      SET @SubPart1 = SUBSTRING(@Source, @I, LEN(@Source)) 

     SET @I = @I + LEN(@SubPart1) + 1; 

     -- GET 2st SubPart ----------------------------------- 
     SET @NextLength = CHARINDEX(' ',@Source,@I) 

     IF @NextLength > 0 
      SET @SubPart2 = SUBSTRING(@Source, @I, @NextLength - @I) 
     ELSE 
      SET @SubPart2 = SUBSTRING(@Source, @I, LEN(@Source)) 

     SET @I = @I + LEN(@SubPart2) + 1; 

     -- GET 3st SubPart ----------------------------------- 
     SET @NextLength = CHARINDEX(' ',@Source,@I) 

     IF @NextLength > 0 
      SET @SubPart3 = SUBSTRING(@Source, @I, @NextLength - @I) 
     ELSE 
      SET @SubPart3 = SUBSTRING(@Source, @I, LEN(@Source)) 

     SET @I = @I + LEN(@SubPart3) + 1; 

     INSERT INTO @Results 
      SELECT @SubPart1 + ' ' + @SubPart2 + ' ' + @SubPart3 
    END 

    SELECT * FROM @Results 
GO 

这里是一个更精简版本,随着3组非定长字段的工作:为了记录不固定长度的下面会,只要它在与空间的3组之间的工作

CREATE PROCEDURE [dbo].[SplitMyFunkyText] 
    @Source nvarchar(MAX) 
AS 
    DECLARE @Results AS TABLE(Part NVARCHAR(255)) 

    DECLARE @I INT = 1 
    DECLARE @Start INT = 1 

    WHILE @I > 0 
    BEGIN 
     SET @Start = @I 
     SET @I = CHARINDEX(' ',@Source, 1+CHARINDEX(' ',@Source, 1+CHARINDEX(' ', @Source, @I + 1))) 

     IF @I > 0 
      INSERT INTO @Results 
       SELECT SUBSTRING(@Source, @Start, @I - @Start) 
     ELSE 
      INSERT INTO @Results 
       SELECT SUBSTRING(@Source, @Start, LEN(@Source)) 
    END 

    SELECT * FROM @Results 
GO 
+0

喜唐,是的,这就是我需要的,只是一个问题,怎么样,如果我的分裂纪录是不是在固定的位置例如:123 870503-23-5370 021 456 6606249 031 789 870103-11-5372 041 – SiChiPan

+0

最后问题解决。谢谢唐。 – SiChiPan

+0

我刚刚发布了一个更紧凑的版本,可以在3个组中使用非固定长度的字段 - 请参阅答案的底部。 – Don