我有我的存储过程:
create procedure [dbo].[Sp_AddPermission]
@id nvarchar(max)
as
declare @words varchar(max), @sql nvarchar(max)
set @words = @id
set @sql = 'merge admin AS target
using (values (''' + replace(replace(@words,';','),('''),'-',''',') + ')) AS source(uname, [add], [edit], [delete], [view],Block)
on target.uname = source.uname
when matched then update set [add] = source.[add], [edit] = source.[edit], [delete] = source.[delete], [view] = source.[view], [Block]=source.[Block];'
exec(@sql);
执行时,会显示以下错误:
MERGE语句尝试更多地更新或删除同一行 不止一次。当目标行匹配多个源时会发生这种情况 行。 MERGE语句不能更新/删除目标的同一行 表多次。优化ON子句以确保目标行 匹配最多一个源行,或使用GROUP BY子句进行分组 源行。
如何解决这个问题?
此致
白菊
答案 0 :(得分:2)
问题很明显:您为同一uname
生成了一个包含多个值的源表。
为什么要使用merge
?我认为只需进行简单的更新,当update
中有多个相同的密钥时,我认为source
不会返回错误:
update t
set [add] = source.[add],
[edit] = source.[edit],
[delete] = source.[delete],
[view] = source.[view],
[Block]=source.[Block]
from target t join
(values(. . . )) s(uname, [add], [edit], [delete], [view],Block)
on t.uname = s.uname;
但是,你可以通过为更新选择一个任意行来解决这个问题(这就是上面所做的):
update t
set [add] = source.[add],
[edit] = source.[edit],
[delete] = source.[delete],
[view] = source.[view],
[Block]=source.[Block]
from target t join
(select s.*,
row_number() over (partition by uname order by uname) as seqnum
from (values(. . . )) s(uname, [add], [edit], [delete], [view],Block)
) s
on t.uname = s.uname and s.seqnum = 1;
当然,这种方法也可以与merge
一起使用。