在SQL Server 2008中模仿没有自定义函数的STRING_SPLIT

时间:2016-05-06 17:24:26

标签: sql sql-server sql-server-2008 tsql

有人多次询问,但不是这样。

我在SQL Server 2008上,没有STRING_SPLIT功能(如2016年)。

查询返回以下行,请参阅下面的单个示例行。您在下面看到的bald实际上是一个字段,因此一个varchar列完全包含它:

Appple|10|admin|845687|Apr|26|11:32:29|2016|AwesomeApplication.zip

我希望通过管道|字符进行拆分。

我无法为此编写CTE或自定义函数。

我必须使用内置字符串函数(如CHARINDEXPATINDEX)在一个select语句中将各个竖线分隔元素提取到不同的列中。

有人有任何想法吗?

3 个答案:

答案 0 :(得分:6)

DECLARE @Result Table(Value varchar(50))
DECLARE @x XML
SELECT @X = CAST('<A>' + REPLACE(@StringList, '|', '</A><A>') + '</A>' AS XML)

INSERT INTO @Result
SELECT t.value('.', 'varchar(50)') as inVal
FROM @X.nodes('/A') AS x(t)

这将创建一个包含一列(Value)的表。管道分隔字符串中的每个拆分值都将在此表中创建一条新记录。然后你就可以加入它了。如果不清楚或者它在SQL 2008上不起作用,请告诉我。

如果需要,您可以增加varchar的大小 - 您可以修改查询以拆分不同的值(逗号分隔等)。

答案 1 :(得分:0)

ALTER FUNCTION [dbo].[split] 
(
    @string varchar(max), 
    @separator varchar(1) -- longer separator is also possible
)
RETURNS 
@result TABLE (keyword varchar(max) )
AS
BEGIN
declare @pos int=0, @res varchar(100)
while len(@string)>0
begin
set @pos=CHARINDEX(@separator, @string+@separator,0)
select @res=left(@string,@pos),@string=SUBSTRING(@string,@pos+1,100)
insert @result values(@res)
end
    RETURN 
END

答案 2 :(得分:0)

问这个问题已经有很长时间了,尽管OP想要一个非功能性的解决方案,但这是唯一的答案指出我为我编写代码的正确方向的帖子,所以我认为我在这里分享我的解决方案。

它做什么

此代码检查master db兼容模式并创建适当的_my_string_split函数。如果string_split存在,这只是一个包装器。 如果没有,它将使用Stan

中建议的方法accepted answer

现在,无论我在哪里运行代码,创建函数后,我所需要做的就是使用master.dbo._my_string_split,例如:

SELECT * FROM master.dbo._my_string_split('Hello|World!','|')

代码

USE master
IF OBJECT_ID('dbo._my_string_split') IS NOT NULL DROP FUNCTION [dbo].[_my_string_split]
GO

DECLARE @sqlCode NVARCHAR(MAX);
IF 130 <= (SELECT compatibility_level FROM sys.databases WHERE name = DB_NAME()) 
    SET @sqlCode = '
    --- 130+ string_split exists
    CREATE FUNCTION [dbo].[_my_string_split]
    (
        @string nvarchar(max),
        @separator nvarchar(1)
    )
    RETURNS
    @result TABLE ([Value] nvarchar(max) )
    BEGIN   

        INSERT INTO @result
            SELECT [Value] FROM string_split(@string,@separator)

        RETURN

    END
'
ELSE
  SET @sqlCode = '
    --- before 130: string_split does not exists
    CREATE FUNCTION [dbo].[_my_string_split]
    (
        @string nvarchar(max),
        @separator nvarchar(1)
    )
    RETURNS
    @result TABLE ([Value] nvarchar(max) )
    BEGIN

        INSERT INTO @result
            SELECT [Value]=t.value(''.'', ''varchar(max)'')
            FROM (SELECT x=(CAST((''<A>'' + REPLACE(@string, @separator, ''</A><A>'') + ''</A>'') AS XML))) a
            CROSS APPLY a.x.nodes(''/A'') AS x(t)

        RETURN

    END
'

PRINT @sqlCode
EXEC sp_sqlexec @sqlCode

希望其他人会发现这很有用。