【问题标题】:Reset IDENTITY column whitout deleting all rows重置 IDENTITY 列而不删除所有行
【发布时间】:2019-01-30 11:15:42
【问题描述】:

我有下表

CREATE TABLE [dbo].[MyTable](
    [Name] NVARCHAR(200) NOT NULL,
    [Surname] NVARCHAR(200) NOT NULL,
    [Permanent] [bit] NULL,
    [Idx] [bigint] IDENTITY(1,1) NOT NULL
 CONSTRAINT [MyTable] PRIMARY KEY CLUSTERED 
(
    [Idx] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

包含 [Permanent]=1 的 1000 行和 [Permanent] NULL 的 500.000 行

此外,我有一个执行以下步骤的存储过程(称为 MySP):

  1. 从 [MyTable] 中删除 [Permanent] 为 NULL
  2. (大量计算)
  3. 将第 2 点的结果插入 [MyTable]

MySP 每天都会运行,因此 [Idx] 的数量会迅速增加,因为每天有 500.000 行被删除和插入。 我的目标是,在 SP 执行期间,重置列 [Idx] 的值以保持 [Idx] 的最大数量尽可能低。

第一次尝试

我尝试在 MySP 结束时使用以下查询进行更新,但系统给了我一个(正确的)错误。

UPDATE A
SET A.[Idx]=B.[Idx_new]
FROM [dbo].[MyTable] A
INNER JOIN (
    SELECT [Idx],ROW_NUMBER() OVER (ORDER BY [Idx]) AS [Idx_new]
    FROM [dbo].[MyTable]
) B
ON A.[Idx]=B.[Idx]

第二次尝试 看完以下两个问题/答案

我在 MySP 的末尾添加了以下内容

DBCC CHECKIDENT ('MyTable', RESEED, 1); 

但这也不像在 [MyTable] 中那样工作,与两个问题的情况不同,保留一些行,因此 [Idx] 不是唯一的并且不如 [Idx] 是一个具体的风险是我的主键。

如何重置标识列值以及仍保留在 [MyTable] 中的行?

【问题讨论】:

  • 1) 找到表中的最小id 2) 动态代码:DBCC CHECKIDENT (' MyTable ', RESEED, <min_id + 1>);
  • Bigint 的最大值为 2^63,因此地球会在你用完之前螺旋式进入太阳。一般来说,你不应该乱用身份列。

标签: sql-server sql-server-2005 primary-key sql-server-identity


【解决方案1】:

使用@Killer Queen 建议,我已经使用这个sn-p 代码解决了,它在DELETE 之后找到MAX([Idx])MAX([Idx]),并在新的INSERT 之前重新植入身份。

因为[Permanent]=1 的行是表中插入的第一行,所以它们的[Idx] 值从1 开始并且非常低。

DELETE 
FROM [MyTable]
WHERE [Permanent]!=1 OR [Permanent] IS NULL

DECLARE @MaxIdx As bigint
SET @MaxIdx = (SELECT ISNULL(MAX([Idx]),0) FROM [MyTable])

DBCC CHECKIDENT ('MyTable', RESEED, @MaxIdx); 

【讨论】:

  • 如果同一个 sp 的另一个副本同时执行,它可以从表 BETWEEN 中删除 SELECT ISNULL(MAX([Idx]),0) FROM [MyTable] 和 DBCC CHECKIDENT ('MyTable', RESEED, @MaxIdx);
  • 如果也有并发INSERT,可以INSERT BETWEEN SELECT ISNULL(MAX([Idx]),0) FROM [MyTable] and DBCC CHECKIDENT('MyTable',重新种子,@MaxIdx);
猜你喜欢
  • 1970-01-01
  • 2017-04-03
  • 1970-01-01
  • 2011-04-16
  • 1970-01-01
  • 1970-01-01
  • 2013-06-13
  • 1970-01-01
  • 2019-01-16
相关资源
最近更新 更多