1

我有一个只包含两列的表 - ListID 和 PersonID。当一个人在系统中与另一个人合并时,我要将“源”人的所有引用更新为对“目标”人的引用。

理想情况下,我想调用一些简单的东西

UPDATE MailingListSubscription
SET PersonID = @DestPerson
WHERE PersonID = @SourcePerson

但是,如果目标人员已经存在于此表中,并且与源人员具有相同的 ListID,则会创建重复条目。如何在不创建重复条目的情况下执行此操作?(ListID,PersonID为主键)

编辑:使用多个 ListID。如果 SourcePerson 分配给 ListID 1、2 和 3,而 DestinationPerson 分配给 ListID 3 和 4,则最终结果需要有四行 - DestinationPerson 分配给 ListID 1、2、3 和 4。

4

4 回答 4

3
--out with the bad
DELETE
FROM MailingListSubscription
WHERE PersonId = @SourcePerson
  and ListID in (SELECT ListID FROM MailingListSubscription WHERE PersonID = @DestPerson)

--update the rest (good)
UPDATE MailingListSubscription
SET PersonId = @DestPerson
WHERE PersonId = @SourcePerson
于 2008-09-25T19:00:42.003 回答
0

我必须同意大卫 B 的观点。删除所有不应该存在的旧东西,然后进行更新。

于 2008-09-25T19:08:39.503 回答
0

实际上,我认为你应该回去重新考虑你的数据库设计,因为你真的不应该像你提议的那样更改记录的主键 - 这意味着 PersonID 列实际上不是首先是一个合适的主键。

我的猜测是您的 PersonID 向您的用户公开,他们出于某种原因重新编号了他们的数据库,而您正在同步更改。这通常是一个糟糕的主意,因为它破坏了审计跟踪和时间一致性。在这些情况下,通常最好使用您自己的不变主键 - 通常是一个身份 - 并设置用户看到的 PersonID 作为其属性。这是额外的工作,但从长远来看会给你额外的一致性和稳健性。

一个好的经验法则是尽可能不向用户公开记录的主键,并且您应该在仔细考虑后才这样做。好吧,我承认我自己在很多场合都打破了这一点,但值得在你能做到的地方努力:-)

于 2008-09-25T19:12:59.260 回答
0

首先,您应该将 destperson 订阅到 SourcePerson 订阅的 Destperson 尚未订阅的所有列表。然后删除所有 SourcePersons 订阅。这将适用于多个 ListID。

Insert into MailingListSubscription
(
   ListID,
   PersonID
)
Select
   ListID,
   @DestPerson
From
   MailingListSubscription as t1
Where
   PersonID = @SourcePerson and
   Not Exists
   (
      Select *
      From MailingListSubscription as t2
      Where
         PersonID = @DestPerson and
         t1.ListID = t2.ListID
   )



Delete From MailingListSubscription
Where
   PersonID = @SourcePerson
于 2008-09-25T19:52:13.113 回答