create FUNCTION [dnt_split] ( @splitstring NVARCHAR(4000), @separator CHAR(1) = ',' ) RETURNS @splitstringstable TABLE ( [item] NVARCHAR(200) ) AS BEGIN DECLARE @currentindex INT DECLARE @nextindex INT DECLARE @returntext NVARCHAR(200) SELECT @currentindex=1 WHILE(@currentindex<=datalength(@splitstring)/2) BEGIN SELECT @nextindex=charindex(@separator,@splitstring,@currentindex) IF(@nextindex=0 OR @nextindex IS NULL) SELECT @nextindex=datalength(@splitstring)/2+1 SELECT @returntext=substring(@splitstring,@currentindex,@nextindex-@currentindex) INSERT INTO @splitstringstable([item]) VALUES(@returntext) SELECT @currentindex=@nextindex+1 END RETURN END
上面版本,最多支持4000個字符,客戶說選太多項目時會丟失數據,分析函數,直接把nvarchar(4000)改成Text,可以支持更長的字符串,自信滿滿的在客戶機子上運行,居然有異常,跟蹤代碼如果只輸入
1216,‘,’,返回結果是12,艹,輸入‘1216,’,','顯示正常,不應該啊,仔細看代碼有/2部分,猜測可能是nvarchar計算長度問題,去掉除以/2,如下所示,正常。
ALTER FUNCTION [dbo].[dnt_split] ( @splitstring TEXT, @separator CHAR(1) = ',' ) RETURNS @splitstringstable TABLE ( [item] VARCHAR(200) ) AS BEGIN DECLARE @currentindex INT DECLARE @nextindex INT DECLARE @returntext VARCHAR(200) SELECT @currentindex=1 WHILE(@currentindex<=datalength(@splitstring)) BEGIN SELECT @nextindex=charindex(@separator,@splitstring,@currentindex) IF(@nextindex=0 OR @nextindex IS NULL) SELECT @nextindex=datalength(@splitstring)+1 SELECT @returntext=substring(@splitstring,@currentindex,@nextindex-@currentindex) INSERT INTO @splitstringstable([item]) VALUES(@returntext) SELECT @currentindex=@nextindex+1 END RETURN END
使用過程中發現如果超出4000長度的話,split依然會有問題,將
@splitstring TEXT改成
@splitstring varchar(max)正常
ALTER FUNCTION [dbo].[dnt_split] ( @splitstring varchar(max), @separator CHAR(1) = ',' ) RETURNS @splitstringstable TABLE ( [item] VARCHAR(200) ) AS BEGIN DECLARE @currentindex INT DECLARE @nextindex INT DECLARE @returntext VARCHAR(200) SELECT @currentindex=1 WHILE(@currentindex<=datalength(@splitstring)) BEGIN SELECT @nextindex=charindex(@separator,@splitstring,@currentindex) IF(@nextindex=0 OR @nextindex IS NULL) SELECT @nextindex=datalength(@splitstring)+1 SELECT @returntext=substring(@splitstring,@currentindex,@nextindex-@currentindex) INSERT INTO @splitstringstable([item]) VALUES(@returntext) SELECT @currentindex=@nextindex+1 END RETURN END