假设我有一个包含字段Managers
和Id
的表Name
。另一个表Accounts
包含字段Id
和Name
。这两个表的关系在多对多表ManagedAccounts
中定义,其复合键为ManagerId
和AccountId
。因此,您可以在某个帐户中拥有多个经理,但该帐户上不能有多个相同的经理。
现在,我有一个名为MergeAccounts的存储过程,它以逗号分隔的varchar的形式接收Manager Id和Manager ID列表。它目前看起来很像这样:
create procedure MergeAccounts @managerId nvarchar(12), @mergedManagers nvarchar(max) as declare @reassignment nvarchar(max)
set @reassignment='update ManagedAccounts set ManagerId='+@managerId+' where ManagerId in ('+@mergedManagers+')'
exec sp_executesql @reassignment
由于两个经理可能在同一个帐户上,它会给我一个错误,说我违反了我在该表上的复合键。如何构建我的代码以简单地删除任何冗余行而不考虑订单?
答案 0 :(得分:1)
更改动态SQL以首先删除任何潜在的冲突。然后进行更新。在交易中包装所有内容。
(顺便说一下,我会通过创建一个从逗号分隔的列表中返回一个表的表值函数来完全避免使用动态SQL ...这非常有用,你可以找到一个像你已编写过的函数谷歌吧)
set @reassignment='
BEGIN TRAN;
BEGIN TRY
DELETE m1
FROM ManagedAccounts m1
JOIN ManagedAccounts m2 ON m1.AccountId = m2.AccountId
WHERE m2.ManagerId = ' + @managerId + '
AND m1.ManagerId IN (' + @mergedAccounts + ')
UPDATE ManagedAccounts SET ManagerId=' + @managerId + ' WHERE ManagerId IN (' + @mergedManagers + ')
COMMIT;
END TRY
BEGIN CATCH
ROLLBACK;
END CATCH;';