2016-02-27 48 views
0

我有这样我的存储过程:错误在合并声明中T-SQL

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语句试图UPDATE或DELETE相同比一次多排 。当目标行匹配多个源 行时会发生这种情况。 MERGE语句不能多次更新/删除目标表的同一行。细化ON子句以确保目标行 至多匹配一个源行,或使用GROUP BY子句将源行分组为 。

如何解决此问题?

问候

白菊

+1

确保'source'中的值是唯一的。 –

+0

您是否尝试过使用Google搜索 –

+1

备注:您应该**不要**为存储过程使用'sp_'前缀。微软已经保留了这个前缀以供自己使用(参见*命名存储过程*)](http://msdn.microsoft.com/en-us/library/ms190669%28v=sql.105%29.aspx),以及你将来有可能冒着名字冲突的风险。 [这对你的存储过程性能也是不利的](http://www.sqlperformance.com/2012/10/t-sql-queries/sp_prefix)。最好只是简单地避免使用'sp_'并将其他内容用作前缀 - 或者根本没有前缀! –

回答

2

的问题是显而易见的:你一个生成具有多个值的源表相同uname

为什么你使用merge这个?我认为,一个简单的更新会做的,我不认为当你有多个相同的密钥在sourceupdate会返回一个错误:

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使用。

+0

如何用此代码更改我的存储过程 –