2010-03-24 3 views
2

Как разбить строку на SQL Server.SQL Server: операция разделения

Пример:

Входная строка: stack over flow

Результат:

stack 
over 
flow 
+0

Зачем вам нужно сделать это в базе данных вместо использования встроенной функции split вашего клиента? Какую проблему ты пытаешься решить? –

+0

Duplicate вопрос. Вы сначала это выяснили? - http://stackoverflow.com/questions/2647/split-string-in-sql –

+0

ya, но эта ссылка не была помечена как ответ. – Geeth

ответ

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, см предыдущей ссылки, объясняющие плюсы и минусы каждого из них.

Для метода Числа таблицы для работы, вы должны сделать это один раз настройки таблицы, которая будет создавать таблицу Numbers, которая содержит строки от 1 до 10000:

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

ВЫХОД:

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

(3 row(s) affected) 
+0

+1 для предлагаемых статей. –

-7

Hard. Действительно сложно - сочетание Strin Manipulation и 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',' ') 

Предложение: использовать разделитель для получения значения split. лучше. (Напр. Стек, Over, Flow ')

0

Я знаю, этот вопрос был для SQL Server 2008, но вещи эволюционируют так, начиная с SQL Server 2016 вы можете сделать это

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

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