【问题标题】:Stored Procedure to Insert comma seperated values as multiple records将逗号分隔值作为多条记录插入的存储过程
【发布时间】:2014-08-04 12:33:35
【问题描述】:

请帮助我创建一个接受逗号分隔值并作为多行插入的存储过程。

所以一个参数@Name 将包含值A、B、C,而另一个参数@Id 将包含值1、2、3

插入后的表格值如下:

Name     Id  
------------
A         1 
A         2 
A         3 
B         1 
B         2 
B         3 
C         1 
C         2 
C         3 

如何编写一个可以插入逗号分隔值的存储过程,如上所示。此外,如果表已经包含一个 Name,id 对,例如,如果 A,2 已经存在于表中,那么它不应该插入。

我使用的是 SQL Server 2005。提前致谢。

【问题讨论】:

标签: sql sql-server sql-server-2005


【解决方案1】:

这样的?

DECLARE @var1   VARCHAR(100)='A,B,C';
DECLARE @var2   VARCHAR(100)='1,2,3';

WITH rep1(name, delim) AS
(
    SELECT @var1 name, ',' delim

    UNION ALL

    SELECT LEFT(name, CHARINDEX(delim, name, 1) - 1) name, delim
    FROM rep1
    WHERE (CHARINDEX(delim, name, 1) > 0)

    UNION ALL

    SELECT RIGHT(name, LEN(name) - CHARINDEX(delim, name, 1)) name, delim
    FROM rep1
    WHERE (CHARINDEX(delim, name, 1) > 0)
)
,rep2(id, delim) AS
(
    SELECT @var2 id, ',' delim

    UNION ALL

    SELECT LEFT(id, CHARINDEX(delim, id, 1) - 1) id, delim
    FROM rep2
    WHERE (CHARINDEX(delim, id, 1) > 0)

    UNION ALL

    SELECT RIGHT(id, LEN(id) - CHARINDEX(delim, id, 1)) id, delim
    FROM rep2
    WHERE (CHARINDEX(delim, id, 1) > 0)
)
INSERT #table
(Name
,ID)
SELECT
 r1.name
,r2.id
FROM rep1 r1
CROSS JOIN rep2 r2
LEFT JOIN #table t
ON r2.id=t.id
AND t.name=r1.name
WHERE (CHARINDEX(r1.delim, r1.name, 1) = 0)
AND (CHARINDEX(r2.delim, r2.id, 1) = 0)
AND t.name IS NULL
ORDER BY r1.name
,r2.id
OPTION (MAXRECURSION 0);

【讨论】:

    【解决方案2】:

    这里我们将逗号分隔成行

    IF OBJECT_ID('tempdb..#Temp') IS NOT NULL
            DROP TABLE #Temp
    
        IF OBJECT_ID('tempdb..#NewTemp') IS NOT NULL
            DROP TABLE #NewTemp
    
        Declare  @Testdata table ( name Varchar(max), Data varchar(max))
        insert @Testdata select 'A', '1,2,3'
        insert @Testdata select 'B', '1,2,3'
        insert @Testdata select 'C', '1,2'
        insert @Testdata select 'A', '1,2,3,4'
        insert @Testdata select 'C', '1,2,3,4,5'
    
        ;with tmp(name, DataItem, Data) as (
        select name, LEFT(Data, CHARINDEX(',',Data+',')-1),
            STUFF(Data, 1, CHARINDEX(',',Data+','), '')
        from @Testdata
        union all
        select name, LEFT(Data, CHARINDEX(',',Data+',')-1),
            STUFF(Data, 1, CHARINDEX(',',Data+','), '')
        from tmp
        where Data > ''
        )
    

    然后插入到临时表中

    select DISTINCT name, DataItem INTO #Temp
    from    tmp WHERE   EXISTS (Select DISTINCT name,DataItem from tmp)
    order by name
    

    这里我们控制 Duplicates 的输入,我们可以观察到组合不会像 (A,1),(B,1) 这样重复,即使它们是多个

    CREATE TABLE #NewTemp(name Varchar(max), Data varchar(max))
    INSERT INTO #NewTemp (name,Data)
    Select name,DataItem from #Temp
    
    Select * FROM #NewTemp
    

    【讨论】:

      【解决方案3】:

      您可以创建一个用户定义的函数,用于将逗号分隔的值拆分为如下行 这个函数是如何工作的以及更多关于它的信息可以找到here

      CREATE FUNCTION dbo.Split
      (
       @RowData nvarchar(2000),
       @SplitOn nvarchar(5)
      )
      RETURNS @RtnValue table
      (
       Id int identity(1,1),
       Data nvarchar(100)
      )
      AS
      BEGIN
       Declare @Cnt int
       Set @Cnt = 1
       DECLARE @index INT
       SET @index = Charindex(@SplitOn,@RowData)
       While (@index>0)
       Begin
       Insert Into @RtnValue (data)
        Select
       Data = ltrim(rtrim(Substring(@RowData,1,@index-1)))
      
       Set @RowData = Substring(@RowData,@index+1,len(@RowData))
       Set @Cnt = @Cnt + 1
       SET @index = Charindex(@SplitOn,@RowData)
       End
      
       Insert Into @RtnValue (data)
       Select Data = ltrim(rtrim(@RowData))
      
       Return
      END
      

      创建此功能后,您可以将其用于您的要求,如下所示

      declare @Name VARCHAR(30) 
      declare @Id VARCHAR(30) 
      
      SET @Name = 'A,B,C'
      SET @Id = '1,2,3'
      
      select A.Data,B.Data FROM dbo.Split(@name,',') A ,dbo.Split(@id,',') B
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-29
        • 1970-01-01
        相关资源
        最近更新 更多