Replace values in a CSV string

后端 未结 4 1207
忘了有多久
忘了有多久 2021-01-25 08:22

I have a list of products in comma separated fashion and since the item list was replaced with new product items, I am trying to modify this CSV list with new product item list.

4条回答
  •  青春惊慌失措
    2021-01-25 09:14

    Thanks for this question - I've just learned something new. The following code is an adaptation of an article written by Rob Volk on exactly this topic. This is a very clever query! I won't copy all of the content down here. I have adapted it to create the results you're looking for in your example.

    CREATE TABLE #nums (n INT)
    DECLARE @i INT 
    SET @i = 1
    WHILE @i < 8000 
    BEGIN
        INSERT #nums VALUES(@i)
        SET @i = @i + 1
    END
    
    
    CREATE TABLE #tmp (
      id INT IDENTITY(1,1) not null,
      plist VARCHAR(MAX) null
    )
    
    INSERT INTO #tmp
    VALUES('10,11,15,17,19'),('22,34,44,25'),('5,6,8,9')
    
    CREATE TABLE #tmpprod (
      oldid INT NULL,
      newid INT NULL
    )
    
    INSERT INTO #tmpprod VALUES(5, 109),(9, 110),(10, 111),(15, 112),(19, 113),(30, 114),(34, 222),(44, 333)
    
    ;WITH cte AS (SELECT ID, NULLIF(SUBSTRING(',' + plist + ',' , n , CHARINDEX(',' , ',' + plist + ',' , n) - n) , '') AS prod
        FROM #nums, #tmp
        WHERE ID <= LEN(',' + plist + ',') AND SUBSTRING(',' + plist + ',' , n - 1, 1) = ',' 
        AND CHARINDEX(',' , ',' + plist + ',' , n) - n > 0)
    UPDATE t SET plist = (SELECT CAST(CASE WHEN tp.oldid IS NULL THEN cte.prod ELSE tp.newid END AS VARCHAR) + ',' 
                FROM cte LEFT JOIN #tmpprod tp ON cte.prod = tp.oldid
                WHERE cte.id = t.id FOR XML PATH(''))
    FROM #tmp t WHERE id = t.id
    
    UPDATE #tmp SET plist = SUBSTRING(plist, 1, LEN(plist) -1)
    WHERE LEN(plist) > 0 AND SUBSTRING(plist, LEN(plist), 1) = ','
    
    SELECT * FROM #tmp
    DROP TABLE #tmp
    DROP TABLE #tmpprod
    DROP TABLE #nums
    

    The #nums table is a table of sequential integers, the length of which must be greater than the longest CSV you have in your table. The first 8 lines of the script create this table and populate it. Then I've copied in your code, followed by the meat of this query - the very clever single-query parser, described in more detail in the article pointed to above. The common table expression (WITH cte...) does the parsing, and the update script recompiles the results into CSV and updates #tmp.

提交回复
热议问题