Sql server 在SQL中从逗号删除列表中删除*多个*项

Sql server 在SQL中从逗号删除列表中删除*多个*项,sql-server,tsql,triggers,Sql Server,Tsql,Triggers,我有一个遗留字段,其中包含一个逗号分隔的userID列表,我将在某个时候替换它,但现在我只需要维护它,我已经设置了一个触发器,因此当用户添加到组时,它会将其粘贴到列表中没有问题,但是当用户被删除时,我需要一个触发器将其从列表中删除。我使用了这段代码,当您一次只删除一个成员时,这段代码可以很好地工作,但是我需要让它在一次删除多个成员时工作,我通常会加入已删除的表并发出砰的一声,我不在,但在这种情况下它不会工作 您能告诉我从触发器上的多个逗号分隔字符串中删除多个userID的最佳方法吗 这是当前的触

我有一个遗留字段,其中包含一个逗号分隔的userID列表,我将在某个时候替换它,但现在我只需要维护它,我已经设置了一个触发器,因此当用户添加到组时,它会将其粘贴到列表中没有问题,但是当用户被删除时,我需要一个触发器将其从列表中删除。我使用了这段代码,当您一次只删除一个成员时,这段代码可以很好地工作,但是我需要让它在一次删除多个成员时工作,我通常会加入已删除的表并发出砰的一声,我不在,但在这种情况下它不会工作

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

这是当前的触发器

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) + '%,')

在这种情况下,我会做什么:

将要删除的ID列表存储在名为@todelete的临时表中。 声明一个新列表@新列表varcharmax 解析原始成员列表,逐个提取成员ID,放入@newlist。但在插入时,请确保它不存在于@todelete中。 将原始成员列表的内容替换为@newlist的内容。
在这种情况下,我会做什么:

将要删除的ID列表存储在名为@todelete的临时表中。 声明一个新列表@新列表varcharmax 解析原始成员列表,逐个提取成员ID,放入@newlist。但在插入时,请确保它不存在于@todelete中。 将原始成员列表的内容替换为@newlist的内容。
如果您想使用Xml,可以将逗号分隔的值列表转换为Xml,应用修改,然后重新创建列表。在我的示例中,我将字符串转换为格式良好的Xml,使用节点和值函数返回行集,使用deleted连接并保留其余的成员ID,然后使用FOR Xml PATH重新创建字符串。代码如下:

--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

如果您想使用Xml,可以将逗号分隔的值列表转换为Xml,应用修改,然后重新创建列表。在我的示例中,我将字符串转换为格式良好的Xml,使用节点和值函数返回行集,使用deleted连接并保留其余的成员ID,然后使用FOR Xml PATH重新创建字符串。代码如下:

--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

谢谢,我一直在玩它,它有一些问题,理想情况下我不想每次都做所有的成员组,因为有另一个触发器触发这些成员组的正常化,而且如果由于某种原因从成员组中删除了所有成员,这个过程不会像预期的那样清空字符串?我会继续玩它,感谢你的回复。谢谢,一直在玩它,它有一些问题,理想情况下我不想每次都玩所有的成员组,因为有另一个触发器触发这些成员组的正常化,此外,如果由于某种原因从membergroup中删除了所有成员,则此过程不会按预期清空字符串?我会继续玩,谢谢你的回应。