2010-03-24 105 views
2

如何在SQL Server中分割字符串。SQL Server:分割操作

實施例:

輸入字符串:stack over flow

結果:

stack 
over 
flow 
+0

在數據庫中這樣做而不是使用客戶端語言的內置分割函數?你想解決什麼問題? – 2010-03-24 12:00:01

+0

重複的問題。你有沒有先檢查一下? - http://stackoverflow.com/questions/2647/split-string-in-sql – 2010-03-24 12:19:23

+0

雅,但該鏈接沒有標記爲答案。 – Geeth 2010-03-24 12:21:49

回答

10

如果您不能使用表值參數,請參閱:"Arrays and Lists in SQL Server 2008 Using Table-Valued Parameters" by Erland Sommarskog,那麼在SQL Server中有多種拆分字符串的方法。本文介紹了幾乎每一個方法的優點和缺點:

"Arrays and Lists in SQL Server 2005 and Beyond, When Table Value Parameters Do Not Cut it" by Erland Sommarskog

你需要創建一個分裂的功能。這是一個分裂的功能如何使用:

SELECT 
    * 
    FROM YourTable        y 
    INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value 

I prefer the number table approach to split a string in TSQL但也有許多方法來拆分在SQL Server中的字符串,見前面的鏈接,這說明各的優點和缺點。

對於數字表的方法來工作,你需要做的這一次表的設置,這將創建一個包含從1到10000行的表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表格設置,創建此分割功能:

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 

您現在可以輕鬆地拆分CSV字符串轉換成表格,並加入就可以了:

select * from dbo.FN_ListToTable(' ','stack over flow') 

OUTPUT:

ListValue 
------------------- 
stack 
over 
flow 

(3 row(s) affected) 
+0

+1爲建議的文章。 – 2010-03-24 12:17:39

-7

硬。真的很難 - Strin操縱和SQL ... BAD組合。存儲過程的C#/ .NET是一種方式,可以返回一個表定義的類型(表),每行一個項目。

2

常見的基於集合的解決方案,這種問題是使用一個數字表。

以下解決方案使用簡單的遞歸CTE即時生成數字表 - 如果需要使用更長的字符串,則應該用靜態數字表替換。

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); 
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 

創建上述功能並執行Belowe查詢來獲取你的結果。

Select * From Dbo.Split('Stack Over Flow',' ') 

建議:使用分隔符獲取拆分值。它更好。 (爲前。「棧,過,流」)

0

我知道這個問題是針對SQL Server 2008,但事情發展,以便與的SQL Server 2016開始爲什麼你需要,你可以做到這一點

DECLARE @string varchar(100) = 'Richard, Mike, Mark' 

SELECT value FROM string_split(@string, ',')