5

MovieMovieRole、およびの 3 つのテーブルがありActorます。MovieRole映画と俳優を関連付ける多対多のテーブルですが、テーブルでの俳優の役割も定義します。俳優は映画内で複数の役割を持つことができるため、MovieRoleは 3 つの列を持つテーブルです。

MovieId int
ActorId int
RoleName varchar(100)

MovieIdと だけに一意の制約を設定する代わりに、ActorId3 つのフィールドすべてに適用します。したがって、エディ・マーフィーが出演し、同じ役を演じる映画はあり得ません。しかし、エディ・マーフィは、別の役割 (「ナッティ・プロフェッサー」の「プロフェッサー・クランプ」、「バディ・ラブ」) を持っている場合、同じ映画に 2 回関連付けることができます。

問題は、 table に多くの重複があることActorです。したがって、「Edward Murphy」という名前の参加者と「Eddie Murphy」という名前の別の参加者がいて、どちらも「Professor Klump」と同じ映画に関連付けられている可能性があります。また、「Edward Murphy」は「Norbit」に関連付けられている可能性がありますが、「Coming to America」には関連付けられておらず、「Eddie Murphy」はその逆です。

俳優とその映画の役割の関連付けをマージするストアド プロシージャを作成する必要があります。これが行うべきことは、2 つのアクター ID を送信することです。1 つはプライマリ アクター レコードで、もう 1 つは削除予定です。削除予定の俳優の映画の役割の関連付けは、主要な俳優に関連付ける必要があります。

私が持っているストアド プロシージャは、削除予定のアクターが主要なアクターとの役割の衝突がない場合にのみ機能します。したがって、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 に答える