字符串拆分仅返回第一个条目

时间:2017-03-22 12:31:19

标签: sql sql-server split

我正在尝试仅为内部使用创建一个过程,您可以在其中添加由逗号分隔的标记字符串。

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE AddService
    @ServiceName AS VARCHAR(MAX),
    @Location AS VARCHAR(MAX),
    @Description AS VARCHAR(MAX),
    @PermissionType AS INT,
    @Tags AS VARCHAR(MAX)
AS
BEGIN
    DECLARE @ServiceId AS INT

    INSERT INTO Services(NAME,LOCATION,DESCRIPTION,PERMISSIONTYPE) VALUES(@ServiceName,@Location,@Description,@PermissionType)
    SET @ServiceId = (SELECT SCOPE_IDENTITY())

    DECLARE @TagSplit TABLE(ID INT IDENTITY(1,1),DATA VARCHAR(MAX))
    INSERT @TagSplit VALUES(SUBSTRING(@Tags,0,CHARINDEX(',',@Tags)))

    WHILE EXISTS(SELECT * FROM @TagSplit)
    BEGIN
       DECLARE @TempId AS INT
       DECLARE @Tag AS VARCHAR(MAX)

       SET @TempId = (SELECT TOP 1 ID FROM @TagSplit)
       SET @Tag = (SELECT TOP 1 DATA FROM @TagSplit)

       INSERT INTO Tags VALUES(@ServiceId,@Tag)

       DELETE FROM @TagSplit WHERE ID = @TempId
    END
END
GO

但是,当我查看我的"标签"表,给定@Tags字符串" some,thing"只有"一些"是添加,但不是"事情"。我想我可能只是误解了如何在SQL中进行正确的字符串拆分。

这是无法正常工作的部分:

WHILE EXISTS(SELECT * FROM @TagSplit)
BEGIN
    DECLARE @TempId AS INT
    DECLARE @Tag AS VARCHAR(MAX)

    SET @TempId = (SELECT TOP 1 ID FROM @TagSplit)
    SET @Tag = (SELECT TOP 1 DATA FROM @TagSplit)

    INSERT INTO Tags VALUES(@ServiceId,@Tag)

    DELETE FROM @TagSplit WHERE ID = @TempId
END

任何帮助?

1 个答案:

答案 0 :(得分:2)

尝试使用Jeff Moden的CSV Splitter表值函数

create function [dbo].[delimitedsplit8K] (
      @pstring varchar(8000)
    , @pdelimiter char(1)
  )
returns table with schemabinding as
 return
  with e1(N) as (
    select 1 union all select 1 union all select 1 union all 
    select 1 union all select 1 union all select 1 union all 
    select 1 union all select 1 union all select 1 union all select 1
  )
  , e2(N) as (select 1 from e1 a, e1 b)
  , e4(N) as (select 1 from e2 a, e2 b)
  , ctetally(N) as (
    select top (isnull(datalength(@pstring),0)) 
      row_number() over (order by (select null)) from e4
  )
  , ctestart(N1) as (
    select 1 union all
    select t.N+1 from ctetally t where substring(@pstring,t.N,1) = @pdelimiter
  )
  , ctelen(N1,L1) as (
    select s.N1,
      isnull(nullif(charindex(@pdelimiter,@pstring,s.N1),0)-s.N1,8000)
    from ctestart s
  )
 select itemnumber = row_number() over(order by l.N1)
      , item       = substring(@pstring, l.N1, l.L1)
   from ctelen l
;
go

拆分字符串参考:

然后你的程序就变成了这个:

CREATE PROCEDURE AddService
    @ServiceName AS VARCHAR(MAX),
    @Location AS VARCHAR(MAX),
    @Description AS VARCHAR(MAX),
    @PermissionType AS INT,
    @Tags AS VARCHAR(MAX)
AS
BEGIN
    set nocount, xact_abort on;

    DECLARE @ServiceId AS INT;

    INSERT INTO Services(NAME,LOCATION,DESCRIPTION,PERMISSIONTYPE) 
    VALUES(@ServiceName,@Location,@Description,@PermissionType)

    SET @ServiceId = (SELECT SCOPE_IDENTITY());

    insert into tags
    select @ServiceId, s.Item
    from [dbo].[delimitedsplit8K](@Tags,',') s;
end
go
相关问题