我想从已排序的表重建数据表

时间:2014-06-05 19:34:28

标签: sql sql-server database sql-server-2000

好的,首先是一点背景,我继承了在MSSQL 2000上维护数据库。

在数据库中,通过外键,有大量互连的表。

我尝试做的是以排序方式重建每个表格,以消除表格IDENT列中的空白。

特别是在一张桌子上,我有以下列:

RL_ID,RL_FK_RaidID,RL_FK_MemberID,RL_FK_ItemID,RL_ItemValue,RL_Notes,RL_IsUber,RL_IsWishItem,RL_LootModifier,RL_WishItemValue,RL_WeightedLootValue

它使用RL_ID作为IDENT列,当前使用DBCC CHECKIDENT报告32620(表) 但是,此表中只有12128行信息。

所以我尝试了一个简单的脚本,以排序的方式将所有信息复制到一个新表中:

INSERT INTO Table_1

SELECT     RL_ID, RL_FK_RaidID, RL_FK_MemberID, RL_FK_ItemID, RL_ItemValue, RL_Notes, RL_IsUber, RL_IsWishItem, RL_LootModifier, RL_WishItemValue, RL_WeightedLootValue

FROM         RaidLoot

ORDER BY RL_ID

然后使用以下命令从源表中删除所有行:

TRUNCATE TABLE (RaidLoot)

使用以下内容验证IDENT是否为

DBCC CHECKIDENT (RaidLoot)

现在将数据从第1行复制回原始表格到结尾:

SET IDENTITY_INSERT RaidLoot ON

INSERT INTO RaidLoot (RL_ID, RL_FK_RaidID, RL_FK_MemberID, RL_FK_ItemID, RL_ItemValue, RL_Notes, RL_IsUber, RL_IsWishItem, RL_LootModifier, RL_WishItemValue, RL_WeightedLootValue)

SELECT RL_ID, RL_FK_RaidID, RL_FK_MemberID, RL_FK_ItemID, RL_ItemValue, RL_Notes, RL_IsUber, RL_IsWishItem, RL_LootModifier, RL_WishItemValue, RL_WeightedLootValue

FROM         Table_1

ORDER BY RL_ID

SET IDENTITY_INSERT RaidLoot OFF

现在验证我只有12128行数据:

DBCC CHECKIDENT (RaidLoot)

(注意:我最后再次使用32620,因为它从未对RL_ID进行重新编号,只是将它们放回到留下间隙的相同位置)。那么我在哪里/怎样才能从1开始重新编号RL_ID列,这样当它将数据写回原始表时我没有差距?

我能看到的唯一其他解决方案是在将其写回原始表之前手动更改Table_1中的每一行RL_ID的心痛过程。虽然这不可能。我有另一个表有大约306,000行数据,但IDENT报告列出为450,123,所以我希望有一种更简单的方法来自动化重编号过程。

2 个答案:

答案 0 :(得分:0)

如果你真的必须这样做(对我来说似乎很浪费时间),你也必须调整所有的外键引用。

考虑为每个表添加NewID列并按顺序填充新列的策略。然后,您可以在调整外键所需的查询中使用此NewID列。尽管如此,除非你能提出一致的模式,否则非常混乱。

由于你可以查询元数据以确定外键等,这当然是可能的,如果你真的有很多表,肯定应该认真考虑。

ADDED

There is a simple way to populate the NewID column

declare @id int
set @id = 0
update MyTable set NewID=@id, @id=@id+1

这并不明显,但确实如此。

答案 1 :(得分:-1)

我不认为它与架构中其他表引用的RL_ID有关 - 如果我设置了单个表测试,则身份将始终显示为身份字段中的最大数字:< / p>

CREATE TABLE #temp (id INT IDENTITY(1,1), other VARCHAR(1))

INSERT INTO #temp
        ( other )
VALUES  (  -- id - int
          'a'  -- other - varchar(1)
          ),('b'),('c'),('d'),('e')

SELECT *
FROM #temp

SELECT *
INTO #holder
FROM #temp
WHERE other = 'C'

TRUNCATE TABLE #temp

SET IDENTITY_INSERT #temp ON

INSERT INTO #temp
        ( id, other )
SELECT  id ,
        other
FROM #holder

DBCC CHECKIDENT (#temp)

DROP TABLE #temp
DROP TABLE #holder

所以你的新身份是32620,因为这是MAX(RL_ID)