SQL Server中超过4个部分的parsename的替代方法

时间:2019-06-17 06:35:27

标签: sql sql-server sql-server-2008

我正在尝试将,分开的记录拆分为单独的列。

我有2个问题,

如果我有4个以上的值,则第一个返回的值比parsename返回NULL

2nd如果我有'。'比我的行还返回Null。

这是我所做的查询,并且运行正常。

   declare @t table (items varchar(50))

   insert into @t values ('Apple,banana,mango,pineapple')

   select * from @t

   SELECT 
   PARSENAME(REPLACE(items,',','.'),4) Col1,
   PARSENAME(REPLACE(items,',','.'),3) Col2,
   PARSENAME(REPLACE(items,',','.'),2) Col3,
   PARSENAME(REPLACE(items,',','.'),1) Col4
   FROM @t

但是此查询返回null。

   declare @t table (items varchar(50))

   insert into @t values ('Apple.,banana,mango,pineapple')

   select * from @t

   SELECT 
   PARSENAME(REPLACE(items,',','.'),4) Col1,
   PARSENAME(REPLACE(items,',','.'),3) Col2,
   PARSENAME(REPLACE(items,',','.'),2) Col3,
   PARSENAME(REPLACE(items,',','.'),1) Col4
   FROM @t

因为'。'

另外,如果我在项目列中添加另一个水果,它将返回Null。

所以我的问题是,如果parsename不起作用,如何将逗号分隔的项目拆分到不同的列中?

3 个答案:

答案 0 :(得分:0)

这是对我有用的功能:

CREATE FUNCTION [dbo].[Split](
@str VARCHAR(MAX),
@delimiter CHAR(1)
)
RETURNS @returnTable TABLE (idx INT PRIMARY KEY IDENTITY, item VARCHAR(8000))
AS
BEGIN
DECLARE @pos INT
SELECT @str = @str + @delimiter
WHILE LEN(@str) > 0 
    BEGIN
        SELECT @pos = CHARINDEX(@delimiter,@str)
        IF @pos = 1
            INSERT @returnTable (item)
                VALUES (NULL)
        ELSE
            INSERT @returnTable (item)
                VALUES (SUBSTRING(@str, 1, @pos-1))
        SELECT @str = SUBSTRING(@str, @pos+1, LEN(@str)-@pos)       
    END
RETURN
END

这是最终结果:

declare @t table (items varchar(50))

INSERT INTO @t VALUES ('Apple.,banana,mango,pineapple,Cherry')

select 
(select item from fn_split(items,',') a where idx in (1)) as col1,
(select item from fn_split(items,',') a where idx in (2)) as col2,
(select item from fn_split(items,',') a where idx in (3)) as col3,
(select item from fn_split(items,',') a where idx in (4)) as col4,
(select item from fn_split(items,',') a where idx in (5)) as col5
 from @t

答案 1 :(得分:0)

创建以下函数,它会像 ParseName 一样工作,但是对于带有任何分隔符的任意数量的部分:

create FUNCTION GetStringParts(@SplittedString nvarchar(300), @Part int, @SplitChar nvarchar(1))
Returns nvarchar(300)

as
begin
if(@Part < 1)
        return '';
    declare @Index int = 1, @Result nvarchar(300) = @SplittedString, @PatIndexResult int
    while @Index < @Part
    begin
        set @PatIndexResult = PATINDEX('%' + @SplitChar + '%', @Result)
        if(@PatIndexResult = 0)
            return '';
        set @Result = SUBSTRING(@Result, @PatIndexResult + 1, len(@Result));
        set @Index = @Index + 1;
    end
    set @PatIndexResult = PATINDEX('%' + @SplitChar + '%', @Result);
    if(@PatIndexResult = 0)
        return @Result;
    return substring(@Result, 0, patindex('%' + @SplitChar + '%', @Result));
end

答案 2 :(得分:-1)

在应用如下所示的其他功能之前,尝试用''替换(。)-

DECLARE @t TABLE (items VARCHAR(50))

INSERT INTO @t VALUES ('Apple.,banana,mango,pineapple')

SELECT 
PARSENAME(REPLACE(REPLACE(items,'.',''),',','.'),4) Col1,
PARSENAME(REPLACE(REPLACE(items,'.',''),',','.'),3) Col2,
PARSENAME(REPLACE(REPLACE(items,'.',''),',','.'),2) Col3,
PARSENAME(REPLACE(REPLACE(items,'.',''),',','.'),1) Col4
FROM @t

AS(。)是PARSENAME的保留字符,您可以应用两次替换将(。)保留在输出中。首先隐藏(。)具有不寻常的字符集,最后将不寻常的字符再次替换为(。),如下所示-

DECLARE @t TABLE (items VARCHAR(50))

INSERT INTO @t VALUES ('Apple.,banana,mango,pineapple')

SELECT 
REPLACE(PARSENAME(REPLACE(REPLACE(items,'.','##@@##'),',','.'),4),'##@@##','.') Col1,
REPLACE(PARSENAME(REPLACE(REPLACE(items,'.','##@@##'),',','.'),3),'##@@##','.') Col2,
REPLACE(PARSENAME(REPLACE(REPLACE(items,'.','##@@##'),',','.'),2),'##@@##','.') Col3,
REPLACE(PARSENAME(REPLACE(REPLACE(items,'.','##@@##'),',','.'),1),'##@@##','.') Col4
FROM @t