SQL Server:分割操作
如何在SQL Server中拆分string
例:
inputstring: stack over flow
结果:
stack over flow
如果您不能使用表值参数,请参阅Erland Sommarskog的“使用表值参数的SQL Server 2008中的数组和列表” ,然后在SQL Server中拆分string的方法很多。 本文涵盖了几乎所有方法的PRO和CON:
“SQL Server 2005及更高版本中的数组和列表,当表值参数不能削减”Erland Sommarskog
你需要创build一个拆分function。 这是如何使用拆分function:
SELECT * FROM YourTable y INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value
我更喜欢使用数字表格的方法来在TSQL中分割一个string,但是在SQL Server中有很多方法来拆分string,参见前面的链接,它解释了每个链接的PRO和CON。
要使数字表格方法起作用,您需要执行一次性表格设置,这将创build一个包含1到10,000行的表格的Numbers
:
SELECT TOP 10000 IDENTITY(int,1,1) AS Number INTO Numbers FROM sys.objects s1 CROSS JOIN sys.objects s2 ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)
Numbers表设置好后,创build这个分割函数:
CREATE FUNCTION [dbo].[FN_ListToTable] ( @SplitOn char(1) --REQUIRED, the character to split the @List string on ,@List varchar(8000)--REQUIRED, the list to split apart ) RETURNS TABLE AS RETURN ( ---------------- --SINGLE QUERY-- --this will not return empty rows ---------------- SELECT ListValue FROM (SELECT LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue FROM ( SELECT @SplitOn + @List + @SplitOn AS List2 ) AS dt INNER JOIN Numbers n ON n.Number < LEN(dt.List2) WHERE SUBSTRING(List2, number, 1) = @SplitOn ) dt2 WHERE ListValue IS NOT NULL AND ListValue!='' ); GO
您现在可以轻松地将一个CSVstring拆分成一个表格并join:
select * from dbo.FN_ListToTable(' ','stack over flow')
OUTPUT:
ListValue ------------------- stack over flow (3 row(s) affected)
这种问题常见的基于集合的解决scheme是使用数字表。
以下解决scheme使用简单的recursionCTE来即时生成数字表 – 如果需要使用更长的string,则应该用静态数字表replace。
DECLARE @vch_string varchar(max) DECLARE @chr_delim char(1) SET @chr_delim = ' ' SET @vch_string = 'stack over flow' ;WITH nums_cte AS ( SELECT 1 AS n UNION ALL SELECT n+1 FROM nums_cte WHERE n < len(@vch_string) ) SELECT n - LEN(REPLACE(LEFT(s,n),@chr_delim,'')) + 1 AS pos ,SUBSTRING(s,n,CHARINDEX(@chr_delim, s + @chr_delim,n) -n) as ELEMENT FROM (SELECT @vch_string as s) AS D JOIN nums_cte ON n <= LEN(s) AND SUBSTRING(@chr_delim + s,n,1) = @chr_delim OPTION (MAXRECURSION 0);
CREATE FUNCTION [dbo].[Split] ( @List varchar(max), @SplitOn nvarchar(5) ) RETURNS @RtnValue table ( Id int identity(1,1), Value nvarchar(max) ) AS BEGIN While (Charindex(@SplitOn,@List)>0) Begin Insert Into @RtnValue (value) Select Value = ltrim(rtrim(Substring(@List,1,Charindex(@SplitOn,@List)-1))) Set @List = Substring(@List,Charindex(@SplitOn,@List)+len(@SplitOn),len(@List)) End Insert Into @RtnValue (Value) Select Value = ltrim(rtrim(@List)) Return END
创build以上function并执行下面的查询以获得您的结果。
Select * From Dbo.Split('Stack Over Flow',' ')
build议:使用分隔符来获取拆分值。 好多了。 (例如“堆叠,结束,stream动”)
我知道这个问题是为SQL Server 2008,但事情发展,所以从SQL Server 2016开始,你可以做到这一点
DECLARE @string varchar(100) = 'Richard, Mike, Mark' SELECT value FROM string_split(@string, ',')
硬。 真的很难 – Strin操纵和SQL … BAD组合。 一个存储过程的C#/ .NET是一种方式,可以返回一个表定义types(表)每行一个项目。