2016-02-27 54 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

如何用此代碼更改我的存儲過程 –