Replace values in a CSV string

后端 未结 4 1248
忘了有多久
忘了有多久 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:25

    Assuming SQL Server 2005 or better, and assuming order isn't important, then given this split function:

    CREATE FUNCTION [dbo].[SplitInts]
    (
       @List       VARCHAR(MAX),
       @Delimiter  CHAR(1)
    )
    RETURNS TABLE
    AS
       RETURN ( SELECT Item FROM ( SELECT Item = x.i.value('(./text())[1]', 'int') FROM 
                ( SELECT [XML] = CONVERT(XML, '' + REPLACE(@List, @Delimiter, '') 
                  + '').query('.') ) AS a CROSS APPLY [XML].nodes('i') AS x(i)
              ) AS y WHERE Item IS NOT NULL
       );
    GO
    

    You can get this result in the following way:

    ;WITH x AS
    (
        SELECT id, item, oldid, [newid], rn = ROW_NUMBER() OVER
        (PARTITION BY id ORDER BY PATINDEX('%,' + RTRIM(s.Item) + ',%', ',' + t.plist + ','))
        FROM #tmp AS t CROSS APPLY dbo.SplitInts(t.plist, ',') AS s
        LEFT OUTER JOIN #tmpprod AS p ON p.oldid = s.Item
    )
    SELECT DISTINCT id, STUFF((SELECT ',' +RTRIM(COALESCE([newid], Item)) 
        FROM x AS x2 WHERE x2.id = x.id
        FOR XML PATH(''), TYPE).value('.[1]', 'varchar(max)'), 1, 1, '') 
    FROM x;
    

    Note that the ROW_NUMBER() / OVER / PARTITION BY / ORDER BY is only there to try to coerce the optimizer to return the rows in that order. You may observe this behavior today and it can change tomorrow depending on statistics or data changes, optimizer changes (service packs, CUs, upgrade, etc.) or other variables.

    Long story short: if you're depending on that order, just send the set back to the client, and have the client construct the comma-delimited list. It's probably where this functionality belongs anyway.

提交回复
热议问题