【问题标题】:Deleting *multiple* items from a comma delimted list in SQL从 SQL 中的逗号分隔列表中删除 *multiple* 项
【发布时间】:2012-06-03 06:12:45
【问题描述】:

我有一个遗留字段,其中包含一个逗号分隔的用户 ID 列表,我将在某个时候替换它,但现在我只需要维护它,我已经设置了一个触发器,所以当用户添加到组将其粘贴到列表中没问题,但是当用户被删除时,我需要一个触发器将其从列表中删除。我使用了这段代码,当你一次只删除一个成员时它工作得很好,但是我需要让它一次用于多次删除,我通常加入到已删除的表并繁荣,我不在但在这个例如它不会工作。

您能告诉我从触发器上的多个逗号分隔的字符串中删除多个用户 ID 的最佳方法吗?

这是当前的触发器。

DECLARE @MemberID int

SELECT @MemberID = MemberID FROM Deleted 

UPDATE MemberGroups SET MembersList = SUBSTRING(
REVERSE (SUBSTRING (REVERSE (REPLACE(',' + mgs.MembersList + ',', ',' + CAST(@MemberID AS varchar) + ',', ',') ) , 2, 8000) ), 2, 8000)
 FROM MemberGroups mgs
 WHERE ',' + mgs.MembersList + ',' LIKE (',%' + CAST(@MemberID AS Varchar) + '%,')

【问题讨论】:

    标签: sql-server tsql triggers


    【解决方案1】:

    如果您想稍微使用一下 Xml,可以将逗号分隔的值列表转换为 Xml,应用修改,然后重新创建列表。在我的示例中,我将字符串转换为格式良好的 Xml,使用 nodes 和 value 函数返回行集,加入 deleted 并保留剩余的成员 ID,使用 @987654324 重新创建字符串@。代码如下:

    --update the groups if the member list contains more then one item
    ;WITH results(GroupID, MemberID) AS (
    SELECT t.GroupID, t.MemberID FROM (
        SELECT GroupID, t.c.value('text()[1]', 'INT') AS MemberID
        FROM (SELECT GroupID, CONVERT(XML, '<ms><m>' + REPLACE(MemberList, ',', '</m><m>') + '</m></ms>') AS ms FROM MemberGroups) x
        CROSS APPLY x.ms.nodes('//m') AS t(c)
        ) t
    LEFT JOIN deleted d ON t.MemberID = d.MemberID
    WHERE d.MemberID IS NULL 
    ) UPDATE mg SET
        MemberList = SUBSTRING((SELECT ',' + CONVERT(VARCHAR(10), MemberID) FROM results WHERE GroupID = r.GroupID FOR XML PATH('')), 2, 8000)
    FROM MemberGroups mg
    INNER JOIN results r ON mg.GroupID = r.GroupID
    
    --update the groups if the member list contains one item only
    UPDATE mg SET 
        MemberList = NULL
    FROM MemberGroups mg
    INNER JOIN deleted d ON mg.MemberList = CONVERT(VARCHAR(10), d.MemberID)
    
    SELECT * FROM MemberGroups
    

    【讨论】:

    • 谢谢,一直在玩它,有一些问题,理想情况下我不想每次都做所有的成员组,因为还有另一个触发器可以正常化这些成员组,另外,如果由于某种原因从成员组中删除了所有成员,则此过程不会按预期清空字符串?我会继续玩它,感谢您的回复。
    【解决方案2】:

    在这种情况下我会怎么做:

    1. 将要删除的 ID 列表存储在名为 @todelete 的临时表中。
    2. 声明一个新列表。 @newlist varchar(max)
    3. 解析原始成员列表,将成员ID一一提取,放入@newlist。但是在插入时确保它不在@todelete 中。
    4. 将原成员列表的内容替换为@newlist 的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-13
      • 1970-01-01
      • 1970-01-01
      • 2018-08-27
      • 2012-04-19
      • 2017-03-17
      • 1970-01-01
      • 2018-08-07
      相关资源
      最近更新 更多