如何在截断并保留 ID 列值后从临时表中重新插入记录
Posted
技术标签:
【中文标题】如何在截断并保留 ID 列值后从临时表中重新插入记录【英文标题】:How to re-insert records from temporary table after truncate and keep ID column values 【发布时间】:2014-03-10 00:50:21 【问题描述】:假设我想删除 SQL Server 表中三个月前插入的所有记录,并保留此后插入的记录。我们正在处理三个月期间两边的许多记录,所以我决定不使用 WHERE 子句语句运行 DELETE,而是将所有内容插入临时表,截断原始表,然后插入临时表中的所有记录回到原来的表。
但我想保留主键 ID 列中的所有值,这些值由另一个表中的外键使用。如何避免重置种子值以及插入每条记录的 ID 列相同的所有内容?
【问题讨论】:
不要删除...不要删除。在该范围内添加“活动”标志或其他内容以将记录标记为活动或已删除。 我正在删除,以便我们可以释放数据库中的空间。 Boss 不想为持有 2000 万条客户很少查看的广告印象日志而付费。因此,我将 3 个月以上的所有内容插入到一个表格中,该表格包含每个广告的总展示次数和点击次数。应该在服务器上释放几 GB。 如果你从另一个表中引用这个表,你是否也删除了对旧行的引用? 没有对该表的引用 【参考方案1】:删除外键并禁用原始表中的标识增量。然后执行您提到的上述过程。那是
-
将记录插入临时表 - (插入 - 选择您想要的任何内容以及另一个表中存在的外键行)。
截断原始表。
将临时表中的记录插入原表(如果记录很多,删除原表并将临时表重命名为原表名)。
添加外键约束并启用标识属性
重新设定身份。 - DBCC CHECKIDENT (yourtable, reseed, 10045)
10045 - 对应于临时表中的行数。所以身份种子从 10046 开始。
希望这会有所帮助。
【讨论】:
我从CHECKIDENT得到的身份种子会得到临时表的行数还是得到最新的ID列值?我需要新种子是 ID 列中的最大值而不是行数。 您将种子值传递给CHECKIDENT
函数。您可以在插入后从表中选择MAX
标识值,然后将其传递给CHECKIDENT
以获得所需的功能。【参考方案2】:
试试:
SET IDENTITY_INSERT OLD_TABLE ON;
GO
INSERT INTO OLD_TABLE ( ... columns, including ID ... )
SELECT ( ... columns, including ID ... ) FROM TEMP_TABLE;
【讨论】:
以上是关于如何在截断并保留 ID 列值后从临时表中重新插入记录的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SQL 中对触发器进行语法化,以便在插入后从同一个表中更新列(oracle 数据库)
使用 SQL Server DTS 包有条件地在目标表中插入/更新行
如果列值 id 与另一个表中的 ID 描述匹配,则在指定列中插入数据(规范化形式)