SQL Server: операция разделения

Как разбить строку на SQL Server.

Пример:

Строка ввода: stack over flow

Результат:

 stack over flow 

если вы не можете использовать параметры табличного значения, см. «Массивы и списки в SQL Server 2008 с использованием табличных значений » Эрлэля Соммарскога , тогда есть много способов разделить строку на SQL Server. В этой статье рассматриваются PRO и CON практически для каждого метода:

«Массивы и списки в SQL Server 2005 и Beyond, когда параметры значения таблицы не разрезают» Эрланд Соммарког

Вам нужно создать функцию split. Вот как можно использовать функцию разделения:

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

Я предпочитаю подход таблицы чисел для разделения строки в TSQL, но существует множество способов разделить строки в SQL Server, см. Предыдущую ссылку, в которой объясняются PRO и CON каждого из них.

Для того, чтобы метод Numbers Table работал, вам нужно выполнить эту настройку одной временной таблицы, которая создаст таблицу Numbers которая содержит строки от 1 до 10 000:

 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 настроена, создайте эту функцию split:

 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) 

Общим решением на основе набора для такого рода проблем является использование таблицы чисел.

В следующем решении используется простой рекурсивный 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); 
 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 

Создайте выше функцию и выполните запрос ниже, чтобы получить свой результат.

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

Предложение: используйте разделитель для получения значения split. лучше. (например, «Stack, Over, Flow»)

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

 DECLARE @string varchar(100) = 'Richard, Mike, Mark' SELECT value FROM string_split(@string, ',') 

Жесткий. Действительно сложно – сочетание Strin Manipulation и SQL … BAD. C # / .NET для хранимой процедуры является способом, может возвращать таблицу определенного типа (таблица) с одним элементом в строке.

Давайте будем гением компьютера.