TSQL解析具有4个分隔符的字符串

时间:2016-11-15 11:47:33

标签: tsql split delimiter

我正在尝试解析此字符串:

' 200 | 50 | jo.th@xxx.com | 09 \ 23 \ 2016 | 07:00:00'

分为5列,我感到很沮丧。

分隔符是pipe |

这些字段没有修复,所以我需要使用charindex才能找到分隔符的位置?

请帮忙 感谢

3 个答案:

答案 0 :(得分:3)

另一种选择如下。这可以融入TVF甚至是Cross Apply

Declare @String varchar(max) = '200|50|jo.th@xxx.com|09\23\2016|07:00:00'

Select Pos1 = xDim.value('/x[1]','varchar(max)')
      ,Pos2 = xDim.value('/x[2]','varchar(max)')
      ,Pos3 = xDim.value('/x[3]','varchar(max)')
      ,Pos4 = xDim.value('/x[4]','varchar(max)')
      ,Pos5 = xDim.value('/x[5]','varchar(max)')
      ,Pos6 = xDim.value('/x[6]','varchar(max)')
      ,Pos7 = xDim.value('/x[7]','varchar(max)')
      ,Pos8 = xDim.value('/x[8]','varchar(max)')
      ,Pos9 = xDim.value('/x[9]','varchar(max)')
 From (Select Cast('<x>' + Replace(@String,'|','</x><x>')+'</x>' as XML) as xDim) A

返回

enter image description here

  

编辑 - 在交叉申请中使用 - 易于扩展/收缩

Declare @YourTable table (ID int,SomeString varchar(max))
Insert Into @YourTable values
(1,'200|50|jo.th@xxx.com|09\23\2016|07:00:00'),
(2,'400|99|james.th@xxx.com|11\15\2016|09:00:00')

Select A.ID
      ,B.*
 From  @YourTable A
 Cross Apply (
                Select Pos1 = xDim.value('/x[1]','varchar(max)')
                      ,Pos2 = xDim.value('/x[2]','varchar(max)')
                      ,Pos3 = xDim.value('/x[3]','varchar(max)')
                      ,Pos4 = xDim.value('/x[4]','varchar(max)')
                      ,Pos5 = xDim.value('/x[5]','varchar(max)')
                      ,Pos6 = xDim.value('/x[6]','varchar(max)')
                      ,Pos7 = xDim.value('/x[7]','varchar(max)')
                      ,Pos8 = xDim.value('/x[8]','varchar(max)')
                      ,Pos9 = xDim.value('/x[9]','varchar(max)')
                 From (Select Cast('<x>' + Replace(A.SomeString,'|','</x><x>')+'</x>' as XML) as xDim) A
             ) B

返回

enter image description here

答案 1 :(得分:1)

首先,我找到每个分隔符的位置,然后使用它来分割你的字符串。像这样的东西;

DECLARE @TextString nvarchar(100); SET @TextString = '200|50|jo.th@xxx.com|09\23\2016|07:00:00'
DECLARE @FirstDelimiter int
DECLARE @SecondDelimiter int
DECLARE @ThirdDelimiter int
DECLARE @FourthDelimiter int

SET @FirstDelimiter = CHARINDEX('|',@TextString)
SET @SecondDelimiter =  CHARINDEX('|',@TextString,@FirstDelimiter+1)
SET @ThirdDelimiter =  CHARINDEX('|',@TextString,@SecondDelimiter+1)
SET @FourthDelimiter =  CHARINDEX('|',@TextString,@ThirdDelimiter+1)

最终查询;

SELECT
@TextString Main_String
,SUBSTRING(@TextString,1,@FirstDelimiter-1) First_String
,SUBSTRING(@TextString,@FirstDelimiter+1,(@SecondDelimiter-@FirstDelimiter)-1) Second_String
,SUBSTRING(@TextString,@SecondDelimiter+1,(@ThirdDelimiter-@SecondDelimiter)-1) Third_String
,SUBSTRING(@TextString,@ThirdDelimiter+1,(@FourthDelimiter-@ThirdDelimiter)-1) Fourth_String
,SUBSTRING(@TextString,@FourthDelimiter+1,LEN(@TextString)-@FourthDelimiter) Fifth_String

结果集;

Main_String                                 First_String    Second_String   Third_String    Fourth_String   Fifth_String
200|50|jo.th@xxx.com|09\23\2016|07:00:00    200             50              jo.th@xxx.com   09\23\2016      07:00:00

答案 2 :(得分:0)

我使用以下命令将delimnated值转换为一组表行(通常用于在存储过程参数中传递多个值,然后可以将其连接起来),pivoting可以将其转换为列。

(与SQL Server 2005及更高版本兼容)

DECLARE @Input varchar(MAX)
DECLARE @Delim char(1)

SET @Input = '200|50|jo.th@xxx.com|09\23\2016|07:00:00' 
SET @Delim = '|'

DECLARE @VALUES TABLE (ColNo INT, [Param] varchar(MAX))

DECLARE @ChrInd INT
DECLARE @Piece varchar(MAX)
DECLARE @ColNo INT
SET @ColNo = 1
SELECT @ChrInd = 1

WHILE @ChrInd > 0
    BEGIN
        SELECT @ChrInd = CHARINDEX(@Delim,@Input)

        IF @ChrInd > 0
            SELECT @Piece = LEFT(@Input,@ChrInd - 1)
        ELSE
            SELECT @Piece = @Input

        INSERT INTO @VALUES(ColNo, [Param]) VALUES(@ColNo, @Piece)
        SELECT @Input = RIGHT(@Input,LEN(@Input) - @ChrInd)

        IF LEN(@Input) = 0 BREAK

        SET @ColNo = @ColNo + 1 
    END

--SELECT AS ROWS
SELECT * FROM @VALUES 

--SELECT AS COLUMNS
SELECT * FROM
(
    SELECT ColNo, [Param] FROM @VALUES
) src
PIVOT(
    MAX([Param])
    FOR ColNo IN ([1],[2],[3],[4],[5])
) AS pvt

结果

ColNo       Param
--------------------------------------------------------------------------
1           200
2           50
3           jo.th@xxx.com
4           09\23\2016
5           07:00:00


1         2         3               4           5         
--------- --------- --------------- ----------- ----------
200       50        jo.th@xxx.com   09\23\2016   07:00:00