sql - 行为不当的身份

标签 sql sql-server tsql identity sql-server-2008-r2

执行以下脚本,创建一个表并将其填充到您的开发数据库中。

SET NOCOUNT ON
Drop Table dbo.Region
GO
CREATE TABLE dbo.Region(
    RegionId      int             IDENTITY(1,1),
    RegionName    varchar(100)    NOT NULL
)
GO

INSERT INTO dbo.Region (RegionName) 
VALUES  ('Region One'), 
        ('Region Two');
GO

SELECT * FROM dbo.Region

这是您期望从行为良好的 Identity 字段中获得的输出。

RegionId    RegionName
----------- ------------------
1           Region One
2           Region Two

现在让我们在 Identity 列中强制输入几个值。

SET NOCOUNT ON
Drop Table dbo.Region
GO
CREATE TABLE dbo.Region(
    RegionId      int             IDENTITY(1,1),
    RegionName    varchar(100)    NOT NULL
)
GO

SET IDENTITY_INSERT dbo.Region ON;
INSERT INTO dbo.Region (RegionId, RegionName) 
VALUES (-9, 'Unknown'),
       (-99, 'N/A');
SET IDENTITY_INSERT dbo.Region OFF;

INSERT INTO dbo.Region (RegionName) 
VALUES  ('Region One'), 
        ('Region Two');
GO

SELECT * FROM dbo.Region

输出为

RegionId    RegionName
----------- ------------------
-9          Unknown
-99         N/A
2           Region One
3           Region Two

RegionId=1去了哪里?




编辑经过进一步研究,如果您两次尝试相同的特技,Sql-Server 不会跳过任何内容

SET NOCOUNT ON
Drop Table dbo.Region
GO
CREATE TABLE dbo.Region(
    RegionId      int             IDENTITY(1,1),
    RegionName    varchar(100)    NOT NULL
)
GO

SET IDENTITY_INSERT dbo.Region ON;
INSERT INTO dbo.Region (RegionId, RegionName) 
VALUES (-9, 'Unknown'), 
       (-99, 'N/A');
SET IDENTITY_INSERT dbo.Region OFF;

INSERT INTO dbo.Region (RegionName) 
VALUES  ('Region One'), 
        ('Region Two');
GO
SET IDENTITY_INSERT dbo.Region ON;
INSERT INTO dbo.Region (RegionId, RegionName) 
VALUES (-999, 'Known-Unknown'), 
       (-9999, 'Really N/A');
SET IDENTITY_INSERT dbo.Region OFF;

INSERT INTO dbo.Region (RegionName) 
VALUES  ('Region Four'), 
        ('Region Five');
GO

SELECT * FROM dbo.Region

这里的输出是

RegionId    RegionName
----------- ------------------
-9          Unknown
-99         N/A
2           Region One
3           Region Two
-999        Known-Unknown
-9999       Really N/A
4           Region Four
5           Region Five

在之前的案例中,1 丢失了。这里的 4 并没有丢失!

所以现在这就是不可预测的、缺失的身份!

为什么RegionId = 1丢失了,但RegionId = 4却没有丢失?!

最佳答案

IDENTITY(1,1) 适用于表中的第一行

由于您已经插入了两行,因此种子不再适用

下一个身份算法是在检测到表中存在现有记录时向种子开始添加 1,因为 1 可能已被使用。

关于sql - 行为不当的身份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6377731/

相关文章:

c# - MySQL - 键 "PRIMARY"的重复条目

mysql - 如何在 MYSQL 中比较 YEAR 类型?

sql - 将 SQL Server View 结果插入表

mysql - SQL按位运算(MySql)

sql - 如何在SQL表中插入空行?

sql - 如何在Oracle中计数后选择最大值?

sql-server - SQL 服务器 : one table fulltext index vs multiple table fulltext index

sql - 插入到已删除的输出子句中

sql-server - 使用覆盖索引、合并连接、散列连接的查询

c# - 字段相等需要什么条件?