Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 SQL Server:拆分操作_Sql Server 2008_Split - Fatal编程技术网

Sql server 2008 SQL Server:拆分操作

Sql server 2008 SQL Server:拆分操作,sql-server-2008,split,Sql Server 2008,Split,如何在SQL Server中拆分字符串 例如: 输入字符串:堆栈溢出 结果: stack over flow 很难。真的很难操作和SQL。。。糟糕的组合。C/.NET对于存储过程来说是一种方法,它可以返回一个表定义的类型表,每行一项。如果不能使用表值参数,请参阅:,那么在SQL Server中有很多方法可以拆分字符串。本文介绍了几乎每种方法的优缺点: 您需要创建一个拆分函数。这就是拆分函数的使用方式: SELECT * FROM YourTable

如何在SQL Server中拆分字符串

例如:

输入字符串:堆栈溢出

结果:

stack
over
flow

很难。真的很难操作和SQL。。。糟糕的组合。C/.NET对于存储过程来说是一种方法,它可以返回一个表定义的类型表,每行一项。

如果不能使用表值参数,请参阅:,那么在SQL Server中有很多方法可以拆分字符串。本文介绍了几乎每种方法的优缺点:

您需要创建一个拆分函数。这就是拆分函数的使用方式:

SELECT
    *
    FROM YourTable                               y
    INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value
但是在SQLServer中有很多方法可以分割字符串,请参见前面的链接,其中解释了每种方法的优缺点

要使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)
设置数字表后,创建此拆分函数:

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 
输出:

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

(3 row(s) affected)

对于这类问题,一种常见的基于集合的解决方案是使用数字表

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);
下面的解决方案使用一个简单的递归CTE动态生成numbers表——如果需要处理更长的字符串,应该用静态numbers表替换

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);
创建上述函数并执行Belowe查询以获得结果

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

建议:使用分隔符获取拆分值。这样更好。例如“Stack,Over,Flow”

我知道这个问题是针对SQL Server 2008的,但事情会不断发展,所以从SQL Server 2016开始,您可以这样做

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

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

为什么需要在数据库中执行此操作,而不是使用客户端语言的内置剥离功能?你想解决什么问题?重复的问题。你先查过了吗是的,但那个链接并没有被标记为答案。
DECLARE @string varchar(100) = 'Richard, Mike, Mark'

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