我有3个表,Movie
,MovieRole
和Actor
。 MovieRole
是一个涉及电影和演员的多对多表,但它也定义了演员在桌面上的角色。因为actor可能在电影中有多个角色,MovieRole
是一个包含3列的表:
MovieId int
ActorId int
RoleName varchar(100)
我们不是仅对MovieId
和ActorId
设置唯一约束,而是在所有三个字段中都有。因此,不可能有一部电影,其中Eddie Murphy在其中并具有相同的角色。但如果Eddie Murphy扮演不同的角色(“Klump教授”,“The Nutty Professor”中的“Buddy Love”),他可以两次联合同一部电影。
问题是我们在表Actor
中有很多重复项。所以可能有一个名为“爱德华墨菲”的参与者和另一个名为“艾迪墨菲”的参与者,他们两个都可以与“克伦普教授”相同的电影联系在一起。而“爱德华墨菲”可能与“诺比特”有关,但与“来到美国”无关,反之亦然“艾迪墨菲”。
我需要创建一个存储过程,将actor和它们的影片角色关联合并在一起。它应该做的是发送两个演员ID,一个是主要演员记录,一个是删除。 slated-for-delete actor中的电影角色关联必须与主要角色相关联。
存储过程只有在slated-for-delete actor与主actor没有任何角色冲突时才有效。因此,如果s-f-d演员在电影B中并且主要演员在电影A中,那么它很好。或者如果s-f-d演员在电影A中但是角色不同,我们都很好。但是如果两个演员都在同一个角色中扮演同一个角色,那么我会遇到这个约束。
如何构建解决该意外事件的查询或存储过程? 我一直在寻找完成这项工作的方法,看起来像使用游标会做到这一点虽然每个人都说尽量避免使用游标。有没有办法在不使用游标的情况下完成我想要的东西?
现在,sproc的基本要点是这样的:
alter procedure RoleMerge @ActorA int, @ActorB int as
update MovieRole set ActorId=@ActorA where ActorId=@ActorB
delete from Actor where Id=@ActorB
答案 0 :(得分:2)
首先,如果ActorId
从@ActorB
更改为@ActorA
,则会删除违反约束的行:
alter procedure RoleMerge @ActorA int, @ActorB int as
begin
delete MovieRole
from MovieRole as M
where
ActorId = @ActorB and
exists (
select *
from MovieRole as M1
where
M1.ActorId = @ActorA and M1.MovieId = M.MovieId and
M1.RoleName = M.RoleName
)
update MovieRole set ActorId = @ActorA where ActorId = @ActorB
delete from Actor where Id = @ActorB
end
答案 1 :(得分:0)
你不需要光标。只是MovieID的附加条款。像这样的东西:
update MovieRole set ActorId=@ActorA where ActorId=@ActorB
and MovieID not in (select MovieID from MovieRole where ActorId=@ActorA)
希望这会有所帮助
编辑:
我终于有了这个工作:)。 我注意到它已被回答,但以防万一有人对替代解决方案感兴趣:)。 以下是我提出的建议:
update a set a.ActorId = b.ActorId
from MovieRole a
left join MovieRole b
on a.MovieId = b.MovieId and a.ActorID = @ActorB and b.ActorID = @ActorA
where a.RoleName <> b.RoleName