当身份种子达到主键中的现有值时会发生什么?

What happens when Identity seed reaches an existent value in a primary key?

我有一个标识列,它也是 INT 数据类型的主键。由于讨论的问题here(缓存丢失),身份有差距,我选择重新播种到以前的值。具体来说,我的情况是这样的:

表 1

ID_PK    Field1
---------------
28       'd'
29       'e'
30       'h'
1029     'f'
1030     'g'

我环顾四周,找不到明确的答案来说明当我进行插入并且种子达到会破坏约束的现有值时会发生什么。假设我要在 table 的两个单独查询中插入值 'x''y',我可以想到以下可能性:

  1. 身份将在第一次插入之前重新播种,我将正确插入两个值。

  2. 第一次插入会失败,然后重新设置列的种子,然后第二次插入才会成功。

  3. 两者都不起作用,在 table

  4. 中插入值之前,我必须显式调用 DBCC CHECKIDENT 重新播种

那么,是哪个?或者上面的none?如果我在 Table1 中插入多行结果查询,这种行为会有所不同吗?提前致谢

无论如何,为了完整起见,这里有一个您可以用来测试的脚本:

USE Sandbox;
GO

CREATE TABLE test(ID int IDENTITY(1,1) PRIMARY KEY CLUSTERED, string char(1));
GO

INSERT INTO test (string)
VALUES ('a'),('b'),('c'),('d');
GO

SELECT *
FROM test;
GO

DELETE FROM test
WHERE string IN ('b','c');
GO

SELECT *
FROM test;
GO
DBCC CHECKIDENT ('dbo.test', RESEED, 1);
GO  
INSERT INTO test (string)
VALUES ('e'),('f');
GO

SELECT *
FROM test;
GO

INSERT INTO test (string)
VALUES ('g');
GO

SELECT *
FROM test;
GO
DROP TABLE test;

运行 这个脚本会给你你需要的答案。如果您想知道为什么我使用 1 作为 RESEED 值,请参阅 documentation:

The following example forces the current identity value in the AddressTypeID column in the AddressType table to a value of 10. Because the table has existing rows, the next row inserted will use 11 as the value, that is, the new current increment value defined for the column value plus 1.

在我的脚本中,这意味着要在 RESEED 之后插入的下一行的 IDENTITY 的值为 2,而不是 1(作为已经存在于 table 中的行(ID 的 14))。

不过正如一些人在评论中所说,确实没有必要在 IDENTITY 列上使用 RESEED。如果你需要维护一个序列,你应该(不出所料)使用 SEQUENCE: CREATE SEQUENCE (Transact-SQL)

这取决于:

场景 1

您在 IDENTITY 列中得到重复项,因为没有唯一索引或 PK 约束。

create table I (
    id int identity(1,1) not null,
    i int null
)

场景 2

您收到以下错误,因为插入的值与主键约束冲突:

Msg 2627, Level 14, State 1, Line 1 Violation of PRIMARY KEY constraint 'PK__I__3213E83FE0B0E009'. Cannot insert duplicate key in object 'dbo.I'. The duplicate key value is (11). The statement has been terminated.

create table I (
    id int identity(1,1) not null primary key,
    i int null
)

这证明 IDENTITY 本身并不能保证唯一性,只有 UNIQUE CONSTRAINT 才能保证唯一性。

关闭,原来是(2)。

第一次插入失败,自动补种到最高值,只有下次插入成功。如果任何值会破坏主键约束,则多值插入的行为相同。