如何使用CR LF字符分解字符串?

时间:2013-12-10 17:34:42

标签: sql sql-server

我有一个地址字符串,我需要分解为4个字段Add1Add2 ...

我需要使用CHAR(13)+CHAR(10)作为分隔符。该字符串看起来像text1CRLFtext2CRLFtext3。我应该有以下内容:

add1 = text1 (SUBSTRING(field, 0, CHARINDEX(CHAR(13)+CHAR(10),field))
add2 = text2
add3 = text3

但是我在填充其余字段时遇到问题(如何计算CRLF之间的长度)。

这是在MS SQL服务器上。

这是我想出来的

DECLARE @document VARCHAR(64);
SELECT @document = 'we
want
the
world
now';

SELECT addr1 = SUBSTRING(@document, 1, CHARINDEX(CHAR(13)+CHAR(10),@document)-1)
SELECT addr2 = SUBSTRING(@document, CHARINDEX(CHAR(13)+CHAR(10),@document)+2, CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document)+2)-1-(CHARINDEX(CHAR(13)+CHAR(10),@document)+1))
SELECT addr3 = SUBSTRING(@document, CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document)+2)+2, CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document)+2)+2)-1-(CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document)+2)+2-1))
SELECT addr4 = SUBSTRING(@document, CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document)+2)+2)+2, CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document)+2)+2)+2)-1-(CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document)+2)+2)+2-1))
SELECT addr5 = SUBSTRING(@document, CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document)+2)+2)+2)+2, LEN(@document)-CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document,CHARINDEX(CHAR(13)+CHAR(10),@document)+2)+2)+2)-1)

现在我需要将其转换为处理四种不同场景的视图 - 当字符串只有一个CRLF时,当它有两个或更多CRLF时,最多4个。

2 个答案:

答案 0 :(得分:2)

假设总是有< = 4行,你可以在PARSENAME使用这个技巧:

DECLARE @add VARCHAR(4000) = 'My Name Is _____
123 4th St. W.
Newark, NJ
10104';

;WITH x(a) AS
(
  SELECT REPLACE(REPLACE(@add, '.', '$'),CHAR(13)+CHAR(10),'.')
)
SELECT add1 = REPLACE(PARSENAME(a,4),'$','.'), 
       add2 = REPLACE(PARSENAME(a,3),'$','.'), 
       add3 = REPLACE(PARSENAME(a,2),'$','.'), 
       add4 = REPLACE(PARSENAME(a,1),'$','.') 
FROM x;

.无法自然地出现在数据中,或者当它已经是分隔符(例如IP地址和四部分名称)时,这就不那么混乱了。

另一种方法是创建一个有序的分割函数:

CREATE FUNCTION [dbo].[SplitStrings_Ordered]
(
    @List       NVARCHAR(MAX),
    @Delimiter  NVARCHAR(255)
)
RETURNS TABLE
AS
    RETURN (SELECT [Index] = ROW_NUMBER() OVER (ORDER BY Number), Item 
    FROM (SELECT Number, Item = SUBSTRING(@List, Number, 
      CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number)
     FROM (SELECT ROW_NUMBER() OVER (ORDER BY s1.[object_id])
      FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2) AS n(Number)
      WHERE Number <= CONVERT(INT, LEN(@List))
      AND SUBSTRING(@Delimiter + @List, Number, LEN(@Delimiter)) = @Delimiter
    ) AS y);
GO

现在你可以说(给定上面给出的@add):

SELECT a1 = [1], a2 = [2], a3 = [3], a4 = [4] 
FROM dbo.SplitStrings_Ordered(@add, CHAR(13) + CHAR(10)) AS s
PIVOT (MAX(Item) FOR [Index] IN ([1],[2],[3],[4])) AS p; 
GO

如果信息在表格中,没问题:

DECLARE @add TABLE(ID INT IDENTITY(1,1), [address] VARCHAR(4000));

INSERT @add([address]) VALUES('My Name Is ______
221 3rd St.
Newark, NJ
10104'),
('Another name is...
345 Bruins Blvd.
Boston, MA
01251');

SELECT ID, a1 = [1], a2 = [2], a3 = [3], a4 = [4] 
FROM @add AS a
CROSS APPLY dbo.SplitStrings_Ordered(a.[address], CHAR(13) + CHAR(10)) AS s
PIVOT (MAX(s.Item) FOR s.[Index] IN ([1],[2],[3],[4])) AS p; 
GO

答案 1 :(得分:1)

尝试这样的事情:

Declare @MyString varchar(200) = 'text1CRLFtext2CRLFtext3'
Declare @individual varchar(20) = null

WHILE LEN(@MyString) > 0
BEGIN
    IF PATINDEX('%CRLF%',@MyString) > 0
    BEGIN
        SET @individual = SUBSTRING(@MyString, 0, PATINDEX('%CRLF%',@MyString))
        SELECT @individual

        SET @MyString = SUBSTRING(@MyString, LEN(@individual + 'CRLF') + 1,
                                                     LEN(@MyString))
    END
    ELSE
    BEGIN
        SET @individual = @MyString
        SET @MyString = NULL
        SELECT @individual
    END
END