如何在表格上用新的主键替换现有的主键?

3
我正在使用一个传统的SQL Server数据库,其中有一个核心表格具有糟糕的主键。该键是NVARCHAR(50)类型,并包含基于表中各种事物生成的应用程序字符串。出于明显的原因,我想用自动递增(identity)INT列替换此键。
这是一个巨大的数据库,我们正在逐步升级它。我们希望将对其他组件写入的表的更改最小化。我认为我可以通过以下方式更改表格而不会破坏任何内容:
1.向表中添加新的Id列并使其可空 2.填充唯一整数并使其NOT NULL 3.删除现有的主键,同时确保该列仍具有唯一性约束 4.将新的Id列设置为新的主键和identity
第3项非常麻烦。由于这是一个核心表,有许多其他表与之具有外键约束。要删除现有的主键,似乎必须先删除所有这些外键约束,然后再创建它们。 是否有更简单的方法来做到这一点,还是我只能编写脚本?

快速问题:
  1. 当您说删除此主键时,您并不是指删除该列,对吗?
  2. 您是否尝试在其他表上禁用外键约束:ALTER TABLE <table_name> NOCHECK CONSTRAINT <foreignkey_name>。这可能有助于您达到第4点,完成后重新启用fk约束。
- Icarus
正确 - 我实际上想保留所有外键约束。我还没有尝试禁用它们,但错误提示我需要实际删除它们。不过我可以尝试一下吗? - Damovisa
不,我认为你根本不需要删除它们。只需禁用它们,进行操作后再重新启用即可。@ericb链接的脚本正是这样做的。使用ALTER TABLE <table_name> NOCHECK CONSTRAINT <fk_name>来禁用,使用ALTER TABLE <table_name> CHECK CONSTRAINT <fk_name>来启用。 - Icarus
好的,我尝试禁用它们然后进行更改。不幸的是,当我尝试删除主键时它失败了。但是删除和重新创建的方法可行。 - Damovisa
2个回答

1
很抱歉,这是一个坏消息。我们刚刚完成了一个类似的大型项目,尽管我们的首席数据库管理员有一些技巧。你可以看看像this这样的东西,以生成翻转开关所需的脚本:

谢谢。这就是我最终使用的内容。 - Damovisa

1

我曾经也做过同样的事情,基本上使用了您描述的过程。当然,您首先必须访问每个其他表,并添加指向基础表中新列的新外键。

所以我使用的方法是:

  1. 在基础表中添加一个自动递增整数的新列,并确保它具有唯一索引(稍后将被主键替换)
  2. 对于指向基础表的每个外键关系,在子表中添加一个新列。(请注意,如果存在多个关系,则可能会在子表中添加多个列)
  3. 对于子表中每个键的实例,输入一个值到新的外键字段中
  4. 替换您的外键关系,使新列现在起作用
  5. 将基础表中的新列设置为主键
  6. 删除基础表中的旧主键和每个子表中的旧外键。

这是可行的,不像一开始听起来那么难。关键是一系列针对子表的更新语句,其性质如下:

Update child_table
set new_column = (select new_primary from base)
where old_primary = old_foreign

是的,我喜欢那个策略。不幸的是,因为我们只是逐步进行,我不想改变这些外键引用。目前,我可以将它们指向旧的键。当我们更新这些表时,我们会解决这个问题。 - Damovisa
我也遇到了同样的问题。我仍然先构建了外键。这个过程持续了几个月,但是在这段时间内需要维护两组键。您仍然需要能够添加新的外键关系并使它们正常工作。我认为快速实现更好。首先用2-3个表进行概念验证,然后开始深入。 - Karl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接