修复数据库不一致 - ID字段

时间:2009-01-15 04:30:22

标签: sql sql-server database coldfusion

我继承了一个(微软?)SQL数据库,它在原始状态下并不是非常原始的。我还在尝试解决其中一些非常奇怪的问题 - 其中一个是不一致的ID条目。

在帐户表中,每个条目都有一个名为accountID的编号,该编号在其他几个表(注释,设备等)中引用。问题是,当只有大约7000个条目时,数字(由于某些随机原因) - 范围从大约-100000到+2000000。

在更改其他表格中的相应数字时,有没有什么好方法可以重新编号?在我看来,我也有ColdFusion,所以任何适用于SQL和/或我会接受的东西。

6 个答案:

答案 0 :(得分:4)

对于代理键,它们意味着没有意义,所以除非你确实遇到了数据库完整性问题(比如没有正确定义的外键约束)或者你的身份接近其数据类型的最大值,我会留下它们一个人并追逐其他一些影响较大的低水果。

答案 1 :(得分:2)

在这种情况下,听起来“为什么”是一个比“如何”更好的问题。 OP注意到有一个奇怪的问题需要修复,但没有说明为什么这是一个问题。这会引起问题吗?改变这些数字会产生什么积极影响?除非你最初对系统进行编程并准确理解为什么数字处于当前状态,否则你正在冒这样的风险进行更改。

答案 2 :(得分:1)

如果这是一个财务应用程序,我会先与会计师(或至少是您的财务人员)交谈,然后再使用帐户表格中的数字。会计表对于如何报告财务状况非常关键。这些ID可能具有您不理解的含义。除非他们有理由,否则没有人会给出否定身份。在任何情况下我都不会改变它,除非我理解为什么它开头是否定的。你可以通过做出不必要的改变来搞砸你的税务报告或其他一些事情。

答案 3 :(得分:0)

您可以禁用外键关系(如果您能够暂时脱机),然后使用脚本更新主键。我之前使用过此更新脚本来更改值,您可以很容易地将此​​代码包装在游标中,逐个查看相关的键值,并将任意值更新为您保持跟踪的递增值的。

在此处查看脚本:http://vyaskn.tripod.com/sql_server_search_and_replace.htm

如果你只有一个使用主键的表列表,你可以设置一系列在游标内运行的UPDATE语句,然后你就不需要使用这个脚本了(这可能有点慢) )。

但值得一提的是,为什么这些价值出现了怪癖。此数据库是否经常添加和删除值?主键值是否真的是任意的,或者它们看起来是否真实,但它们真的有意义吗?虽然我都是为了巩固,但你必须确保这些价值没有任何意义。

答案 4 :(得分:0)

使用ColdFusion这不应该是一个艰巨的任务,但它会很混乱,你必须要小心。您可以使用的一种方法是编写数据库脚本,然后生成一个全新的空白表模式。将accountID设置为新数据库中的标识字段。

然后,使用ColdFusion编写一个查询,该查询将提取所有旧帐户数据并将其逐个插入新数据库。对于每一行,让新数据库分配一个新ID。在每次插入之后,拉出新ID(使用@@ IDENTITY或MAX(accountID))并将新ID和旧ID一起存储在临时表中,以便您知道哪些旧ID属于哪些新ID。

接下来,对每个子表重复此过程。对于每个旧ID,请使用新ID拉取其子条目并将其重新插入新数据库。如果子表上的主键很好,您可以按原样插入它们,或者如果它们无关紧要,让服务器分配新的。

通过临时禁用关系来分配新ID可能会有效,但如果其中一个条目被分配了旧数据已使用的ID,则可能会发生冲突,这可能会导致冲突。

答案 5 :(得分:0)

在帐户表格中为新ID创建一个新列,并在每个相关表格中创建新列以引用新ID列。

ALTER TABLE accounts
ADD new_accountID int IDENTITY

ALTER TABLE notes
ADD new_accountID int

ALTER TABLE equipment
ADD new_accountID int

然后,您可以将每个引用表上的new_accountID列映射到accounts表。

UPDATE notes
SET new_accountID = accounts.new_accountID
FROM accounts
INNER JOIN notes ON (notes.accountID = accounts.accountID)

UPDATE equipment
SET new_accountID = accounts.new_accountID
FROM accounts
INNER JOIN equipment ON (equipment.accountID = accounts.accountID)

此时,每个表都包含旧密钥的accountID和新密钥的new_accountID。从这里开始它应该非常简单。

  1. 中断accountID上的所有外键。
  2. 在每个表上,UPDATE [table] SET accountID = new_accountID。
  3. 重新添加accountID的外键。
  4. 从所有表中删除new_accountID,因为不再需要它。