3

这远非理想情况,但我需要通过将数字“1”附加到与其他四个表具有 FK 关系的 PK Identiy 列来修复数据库。我基本上是把一个四位数的数字变成一个五位数的数字。我需要维持关系。我可以将数字存储在 var 中,执行 Set 查询并附加 1,然后为每个表执行此操作...

有没有更好的方法来做到这一点?

4

5 回答 5

2

您说您正在为主键使用identity数据类型,因此在更新数字之前,您必须SET IDENTITY_INSERT ON此处的文档),然后在更新后再次将其关闭。

只要您为关系设置了级联更新,其他表就应该自动更新。

编辑:由于无法更改身份值,我猜您必须导出数据,设置新的身份值(+10000),然后再次导入您的数据。

谁有更好的建议...

于 2011-05-18T15:51:08.983 回答
1

我的建议是:

  1. 停止写表。
  2. 将表复制到具有新 PK 的新表中。
  3. 将旧表重命名为备份名称。
  4. 将新表重命名为原始表名。
  5. 计算所有表格中的行数并仔细检查您的工作。
  6. 继续使用表格。

事后改变PK并不好玩。

于 2011-05-18T16:16:08.943 回答
1

考虑向 PK 添加另一个字段,而不是延长 PK 字段的长度。您的新字段必须级联到相关表,就像字段长度增加一样,但您可以保留原始 PK 值。

于 2011-05-18T17:24:20.353 回答
1

如果有问题的列上有一个标识属性,它就会变得复杂。这或多或少是我的做法:

  • 备份您的数据库。

  • 将其置于单用户模式。在你做手术的时候,你不需要任何人在附近闲逛。

  • 执行ALTER TABLE必要的语句

    • 禁用相关表的主键约束
    • 禁用相关表上的所有触发器
    • 禁用所有引用相关表的外键约束。
  • 克隆你的表,给它一个新的名字和一个列相同的定义。不要为任何触发器、索引、外键或其他约束而烦恼。从表的定义中省略标识属性。

  • 创建一个新的“映射”表,将旧的 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 )以使身份计数器与表中的数据重新同步。

  • 现在,使用映射表将更改的主键列向下传播。根据您的 ER 模型,这可能会变得复杂,因为引用更新列的外键本身可能是复合主键的一部分。

  • 完成后,开始重新启用您禁用的约束和触发器。确保使用该WITH CHECK选项执行此操作。修复因此发现的任何问题。

  • 最后,删除映射表,清除单用户标志并使您的系统重新联机。

小菜一碟!(或者其他的东西。)

于 2011-05-18T17:49:13.030 回答
0

考虑这种方法:将身份种子重置为 10000 + 当前种子。设置identity insert on Insert into the table 从表中的值,中途的identity列加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 来更新外键。

于 2011-05-18T19:59:59.713 回答