我有一个地址字符串,我需要分解为4个字段Add1
,Add2
...
我需要使用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个。
答案 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