多个CSV拆分存储过程

时间:2015-02-18 11:02:37

标签: c# sql sql-server sql-server-2008

我想使用列ID, UserName, Age将用户详细信息保存到我的表中。

我对存储过程的输入将采用这种格式(即CSVUserName,CSVAge。)

'ABC,XYZ,MNO', '12,34,22'

我的存储过程是

CREATE PROC [dbo].[PROCabc]
(@valueListA text, @valueListb text) 
AS 
    DECLARE @posA INT = 0, @lenA INT = 0, @valueA varchar(8000),
            @posb INT = 0, @lenb INT = 0, @valueb varchar(8000)

    WHILE CHARINDEX(',', @valueListA, @posA+1) and CHARINDEX(',', @valueListB, @posB+1)>0
    BEGIN
         set @lenA = CHARINDEX(',', @valueListA, @posA+1) - @posA
         set @valueA = SUBSTRING(@valueListA, @posA, @lenA)

         set @lenb = CHARINDEX(',', @valueListb, @posb+1) - @posb
         set @valueb = SUBSTRING(@valueListb, @posb, @lenb)

         INSERT INTO USERDETAILS (Name, Age)
         VALUES(@valueA, @valueb)

         set @posA = CHARINDEX(',', @valueListA, @posA+@lenA) +1
         set @posb = CHARINDEX(',', @valueListb, @posb+@lenb) +1
   END

这是对的吗?或者我们还有另一种方法可以简化它。

1 个答案:

答案 0 :(得分:0)

您可以使用XML格式将CSV转换为行,以简化解决方案。它也具有良好的可读性。我在里面写了逻辑。

 CREATE PROC [dbo].[PROCabc]
    (@valueListA VARCHAR(MAX), @valueListb VARCHAR(MAX)) 
    AS    
    BEGIN 

        ;WITH NAME AS
        (
            -- Convert to rows and bring row number in the order of default order
            SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 0))RNO,
            LTRIM(RTRIM(Split.a.value('.', 'VARCHAR(100)'))) 'NAMES' 
            FROM  
            (                   
                 SELECT CAST ('<M>' + REPLACE(@valueListA, ',', '</M><M>') + '</M>' AS XML) AS Data         
            ) AS A 
            CROSS APPLY Data.nodes ('/M') AS Split(a)
        )
        ,AGE AS
        (
            SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 0))RNO,
            LTRIM(RTRIM(Split.a.value('.', 'VARCHAR(100)'))) 'AGES' 
            FROM  
            (                    
                 SELECT CAST ('<M>' + REPLACE(@valueListb, ',', '</M><M>') + '</M>' AS XML) AS Data         
            ) AS A 
            CROSS APPLY Data.nodes ('/M') AS Split(a)
        )
        -- Since we have same order of Row number, we join to get the data for each Age for corresponding Name
        INSERT INTO USERDETAILS (Name, Age)
        SELECT N.NAMES,A.AGES
        FROM NAME N
        JOIN AGE A ON N.RNO=A.RNO

    END