我有一个相当复杂的存储过程(至少对我来说),它需要处理前端的多种情况。
前端正在传递2个具有类似值的参数
@Levelmarker= (1234515-564546-65454,4654342-154658-56767,5465489-546549-65456)
这些是逗号分隔的GUIDS。
@`UserNameId= (5797823-65432143-65451213)
在前端输入此数据的用户的GUID
这些值需要转到具有以下结构的表中:
CREATE TABLE LevelTable
(
LevelId uniqueidentifier NOT NULL
LevelMarker uniqueidentiriet NOT NULL
UserName uniqueidentifier NOT NULL
);
我希望值像这样进入表:
LevelId Levelmarker UserName
--------------------------------------------------------
NEWID() 1234515-564546-65454 5797823-654321-65451
NEWID() 4654342-154658-56767 5797823-654321-65451
NEWID() 5465489-546549-65456 5797823-654321-65451
以下是存储过程应处理的方案。
一旦将levelmarkers
插入表中,如果同一用户返回并想要添加其他Levelmarkers
,则前端将传递旧值和新值:(1234515-564546-65454,4654342-154658-56767,5465489-546549-65456,1332245-9852135-7841265)
。
我的存储过程应该认识到表中已经有前三个Levelmarkers
,并且应该只插入新的三个。
如果同一用户决定从以前删除值,以两个值为例,则前端将向我传递值(1234515-564546-65454,4654342-154658-56767)
。存储过程应识别出用户已删除了两个值,并应从表中删除相同的值,并保留未删除的值。
如果用户删除一些值并插入新值,则存储过程应识别出要删除的值并插入新值。
解决此问题的最佳方法是什么?
答案 0 :(得分:3)
我认为,您可以使用string_split()
和merge
语句在单个查询中完成此操作:
merge leveltable t
using (
select value levelmarker, @UserNameId username
from string_split(@LeveMarker, ',')
) s
on (s.levelmarker = t.levelmarker and s.username = t.username)
when not matched by target
then insert (leveid, levelmarker, username)
values (newid(), s.levelmarker, s.username)
when not matched by source
then delete
在using
子句中,我们将@LevelMarker
参数拆分为新行,并关联给定的@UserNameId
。然后,merge
语句检查目标表中是否已存在每种组合,并相应地创建或删除行。