如何更新在另一个表中作为外键引用的表的主键?

时间:2010-05-12 12:21:50

标签: c# sql

假设一个

Table "Person" having 
    "SSN",
    "Name",
    "Address"

和另一个

Table "Contacts" having
    "Contact_ID",
    "Contact_Type",
    "SSN" (primary key of Person)
同样

Table "Records" having
    "Record_ID",
    "Record_Type",
    "SSN" (primary key of Person)

现在我希望在我更改或更新SSN in person表时,相应地在其他2个表中更改。

  1. 如果有人可以帮我解决这个问题
  2. 或如何传递表的外键约束

5 个答案:

答案 0 :(得分:8)

只需将ON UPDATE CASCADE添加到外键约束中。

答案 1 :(得分:5)

优选地,表的主键永远不会改变。如果您希望更改SSN,则应使用不同的主键,并将SSN作为人员表中的普通数据列。如果进行此更改已经太晚了,可以将ON UPDATE CASCADE添加到外键约束中。

答案 2 :(得分:4)

如果你有改变的PK,你需要查看表格设计,使用代理PK,就像身份一样。

在你的问题中,你有一个Person表,它可能是许多表的FK。在这种情况下,ON UPDATE CASCADE会出现一些严重问题。我正在处理的数据库有超过300个引用(FK)到我们的等效表,我们跟踪一个人在每个不同表中所做的各种工作。如果我在Person表中插入一行,然后再尝试将其删除(它不会在任何其他表中使用,它是新的)删除将失败并显示Msg 8621, Level 17, State 2, Line 1 The query processor ran out of stack space during query optimization. Please simplify the query.因此我可以'假设当你在PK上获得许多FK时,ON UPDATE CASCADE会起作用。

我永远不会像SSN那样制作敏感数据PK。医疗保健公司过去常常这样做,并且由于隐私而进行了痛苦的转换。我希望你没有一个Web应用程序,并且有一个名为SSN的GET或POST变量,其中包含实际值!或者在每个报告上显示SSN,或者您是否会粉碎所有旧的打印报告,并限制查看每个报告的人员的访问权限等。

答案 3 :(得分:1)

好吧,假设SSN是Person表的主键,我当然会(在一个事务中):

  • 使用新的SSN创建一个全新的行,复制旧行中的所有其他详细信息。
  • 更新其他表中的列以指向新行。
  • 删除旧行。

现在这实际上是一个很好的例子,说明为什么你不应该使用真实数据作为表交叉引用,如果数据可以改变的话。如果您使用人工柱将它们绑在一起(并且只将SSN存储在一个地方),那么您就不会遇到问题。

答案 4 :(得分:1)

级联更新和删除使用起来非常危险。如果您有一百万个子记录,最终可能会出现严重的锁定问题。您应该编写更新和删除代码。

如果可以避免,你绝不应该使用有可能改变的PK。您也不应该将SSN用作PK,因为它永远不会以未加密的方式存储在您的数据库中。从来没有,除非你的公司喜欢被起诉,因为它们是造成身份盗窃事件的原因。这不是一个耸肩的设计缺陷,因为这是遗产,我们没有时间来解决。这是一个设计缺陷,如果有人窃取您的备份磁带或以其他方式从系统中取出ssns(大多数此类盗窃都是内部BTW),可能会破坏您的公司。这是一个迫切的问题 - 必须解决现在的设计缺陷。

SSN也是一个糟糕的候选者,因为它会发生变化(例如,当人们成为身份盗用的受害者时,人们就会改变它们。)加上整数PK的性能会比9位PK更快。