有没有一种聪明的方法可以将数字添加到关系数据库中的PK身份列中,而无需总灾难?

| 这与理想情况相去甚远,但是我需要通过将数字“ 1”附加到与其他四个表具有FK关系的PK Identiy列来修复数据库。我基本上是将四位数的数字变成五位数的数字。我需要保持关系。我可以将数字存储在var中,执行Set查询并附加1,然后为每个表执行此操作... 有更好的方法吗?     
已邀请:
考虑将另一个字段添加到PK,而不是扩展PK字段的长度。您的新字段将必须级联到相关表,就像字段长度增加一样,但是您必须保留原始的PK值。     
您说您的主键使用的是
identity
数据类型,因此在更新数字之前,您必须将其更改为ѭ1here(此处的文档),然后在更新后再次将其关闭。 只要您为关系设置了级联更新,其他表就应该自动更新。 编辑:由于无法更改标识值,我想您必须导出数据,设置新的标识值(+10000),然后再次导入数据。 任何人都有更好的建议...     
我的建议是: 停止写表。 使用新的PK将表复制到新表。 将旧表重命名为备份名称。 将新表重命名为原始表名。 计算所有表中的行,然后仔细检查您的工作。 继续使用表格。 事后更改PK并不有趣。     
如果所讨论的列上具有标识属性,它将变得很复杂。这或多或少是我的方法: 备份您的数据库。 将其置于单用户模式。进行手术时,您不需要任何人乱搞。 执行必要的the2ѭ语句 在有关表上禁用主键约束 禁用相关表上的所有触发器 禁用所有引用该表的外键约束。 克隆您的表,为其提供一个新名称和一个用于列的相同定义。不要为任何触发器,索引,外键或其他约束而烦恼。从表的定义中忽略identity属性。 创建一个新的\'map \'表,将您的旧ID值映射到新值:
create table dbo.pk_map
(
  old_id int not null primary key clustered ,
  new_id int not null unique nonclustered ,
)
填充地图表:
insert dbo.pk_map
select old_id = old.id ,
       new_id = f( old.id ) // f(x) is the desired transform
from dbo.tableInQuestion old
填充新表,为主键列提供新值:
insert dbo.tableInQuestion_NEW
select id = map.id ,
       ...
from dbo.tableInQuestion old
join dbo.pk_map          map on map.old_id = old.id
截断原始表:
TRUNCATE dbo.tableInQuestion
。由于您已禁用所有触发器和外键约束,因此这应该可以安全地工作。 执行
SET IDENTITY_INSERT dbo.tableInQuestion ON
。 重新加载原始表:
insert dbo.tableInQuestion
select *
from dbo.tableInQuestion_NEW
执行
SET IDENTITY_INSERT dbo.tableInQuestion OFF
执行
drop table dbo.tableInQuestion_NEW
。我们都做完了。 执行
DBCC CHECKIDENT( dbo.tableInQuestion , reseed )
,使身份计数器与表中的数据保持同步。 现在,使用映射表将更改后的主键列向下传播。根据您的E-R模型,这可能会变得复杂,因为引用更新列的外键本身可能是组合主键的一部分。 完成所有操作后,开始重新启用约束并触发您禁用的操作。确保使用
WITH CHECK
选项执行此操作。修复因此发现的所有问题。 最后,删除映射表,并清除单个用户标志,并使您的系统重新联机。 小菜一碟! (或者其他的东西。)     
考虑这种方法: 将身份种子重置为10000 +当前种子。 设置身份插入 从表中的值插入表中,并在此过程中将10000添加到标识列。 例如:
Set identity insert on
Insert Table(identity, column1, eolumn2)
select identity + 10000, column1, column2
From Table
Where identity < origional max identity value
插入后,您知道身份比原始身份多10000。 通过添加10000更新外键。     

要回复问题请先登录注册