5

我有 3 张桌子、MovieMovieRoleActorMovieRole是一个多对多表,将电影和演员联系起来,但它也定义了演员在桌子上的角色。因为演员可能在一部电影中扮演多个角色,MovieRole所以是一个包含 3 列的表:

MovieId int
ActorId int
RoleName varchar(100)

MovieId我们没有对和有唯一约束,ActorId而是在所有三个字段中都有它。所以不可能有一部电影里埃迪墨菲在里面并且扮演同样的角色。但是,如果埃迪·墨菲扮演不同的角色(“Klump 教授”、“疯子教授”中的“Buddy Love”),他可以将同一部电影关联两次。

问题是我们在 table 中有很多重复项Actor。因此,可能有一个名为“Edward Murphy”的参与者和另一个名为“Eddie Murphy”的参与者,并且他们都可能与“Professor Klump”相关联。而“爱德华墨菲”可能与“诺比特”相关联,但与“来到美国”无关,反之亦然“艾迪墨菲”。

我需要创建一个将演员及其电影角色关联合并在一起的存储过程。它应该做的是发送两个演员 ID,一个是主要演员记录,一个是要删除的。预定删除演员中的电影角色关联必须与主要演员相关联。

我的存储过程仅在 slated-for-delete 演员与主要演员没有任何角色冲突时才有效。因此,如果 sfd 演员在电影 B 中,而主要演员在电影 A 中,则效果很好。或者如果 sfd 演员在电影 A 中但扮演不同的角色,我们都很好。但如果两位演员在同一部电影中扮演相同的角色,我就会遇到这种限制。

如何构建一个查询或存储过程来解决该意外事件?我一直在寻找完成这项工作的方法,似乎使用游标可以做到这一点,尽管每个人都说尽可能避免使用游标。有没有办法在不使用光标的情况下完成我想要的?

现在,sproc 的基本要点是这样的:

alter procedure RoleMerge @ActorA int, @ActorB int as

update MovieRole set ActorId=@ActorA where ActorId=@ActorB

delete from Actor where Id=@ActorB
4

2 回答 2

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
于 2013-09-18T19:24:06.067 回答
0

你不需要光标。只是 MovieID 的 where 中的附加子句。像这样的东西:

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
于 2013-09-18T19:18:17.527 回答