重新插入带有标识列的行

时间:2011-05-18 06:40:23

标签: sql sql-server sql-server-2008 identity-column

我正在SQL Server(2008 R2)中实现一个包含要执行的作业的队列。完成后,作业将移至历史记录表,并设置成功或失败的标志。队列表中的项目具有标识列作为主键。历史队列具有此id的组合和作为PK的时间戳。

如果作业失败,我想选择重新运行它,他们的方式这被认为是将其移动从历史表背,背到现场排队。出于可追溯性的目的,我希望重新插入的行与原始条目具有相同的ID,这会导致问题,因为这是一个标识列。

我看到两种可能的解决方案:

1)使用IDENTITY_INSERT:

SET IDENTITY_INSERT TableName ON

-- Move from history to live queue

SET IDENTITY_INSERT TableName OFF

2)创建一些自定义逻辑以生成唯一ID,例如从实时和历史队列中获取最大ID值并添加一个。

我没有看到任何真正的问题,除了它凌乱,可能性能不佳,它让我的神经质皮肤爬行......

选项1我喜欢,但我不太清楚其含义。这将如何表现?而且我知道同时对两张桌子这样做会让事情崩溃和燃烧。如果两个线程同时对同一个表执行此操作会发生什么?

对于半常用的存储过程来说,这是否是一个很好的方法,或者这种技术是否只能用于在蓝色月亮中批量插入数据?

有哪些想法是最好的选择,还是有更好的方法?

4 个答案:

答案 0 :(得分:1)

我选择选项1 - 使用IDENTITY_INSERT

SET IDENTITY_INSERT TableName ON

-- Move from history to live queue

SET IDENTITY_INSERT TableName OFF

IDENTITY_INSERT是适用于当前连接的设置 - 因此,如果其他连接执行类似操作,则不会产生任何影响。使用它时出现错误的唯一地方是,如果您尝试在另一个表格上设置ON而未先在第一个表格上将其设为OFF

答案 1 :(得分:0)

您是否可以使用原始(实时)标识值插入历史记录表?你说你无论如何都将它与时间戳结合起来。

答案 2 :(得分:0)

假设Queue的Identity列是分配“Job ID”的列,我认为最简单的解决方案是添加一个新的“OriginalJobID”可空列,可能是FK指向历史表。然后,当您重新运行作业时,允许它在添加到队列时获取新ID,但让它在此新列中保留对原始作业的引用。

要回答“或者这种技术是否只能用于在蓝色月亮中批量插入数据”,我会说是的,当然,这正是它的用途。


糟糕,@ Damien_The_Unbeliever是对的,我忘记了IDENTITY_INSERT设置是每个连接。使用身份插入方法让自己陷入真正的麻烦会很复杂(我猜想会采用像MARS这样的东西,或者错误的错误处理)。尽管如此,我认为尝试重用ID是一个错误!

答案 3 :(得分:0)

我可以在重用身份值时看到潜在的性能问题,即标识列是否由聚簇索引编制索引。

严格增长的数字将导致插入的行始终在聚集索引中最后添加,并且不会发生页面拆分。

如果您开始插入重复使用的数字,则可能会在插入期间导致页面拆分。 如果这是一个问题取决于您的域名。

相关问题