我看到一个SQL Insert语句的一个非常奇怪的问题,我有一个简单的表,ID和2个日期时间,请参阅下面的创建脚本 -
CREATE TABLE [dbo].[DATA_POPULATION_LOGS](
[ID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[START] [datetime] NOT NULL,
[FINISH] [datetime] NOT NULL,
CONSTRAINT [PK__DATA_POP__3214EC2705D8E0BE] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
我现在正在尝试运行以下插入脚本 -
INSERT INTO [dbo].[DATA_POPULATION_LOGS]
([START]
,[FINISH])
VALUES
(GETDATE()
,GETDATE())
失败并出现以下错误 -
Msg 2627, Level 14, State 1, Line 1
Violation of PRIMARY KEY constraint 'PK__DATA_POP__3214EC2705D8E0BE'. Cannot insert duplicate key in object 'dbo.DATA_POPULATION_LOGS'. The duplicate key value is (11).
每次执行插入时,上面错误消息中的重复键值都会增加,因此它似乎知道它是一个标识列。
导致这个问题的原因是什么?!
提前致谢。 西蒙
修改
我现在已经创建了这个表的副本,并且可以使用该脚本插入到新表中,可能导致它失败的原因是什么?
答案 0 :(得分:9)
可能有人发表DBCC CHECKIDENT
反对该表。执行此操作时,SQL Server将服从您,并尝试从RESEED
开始生成值并按增量递增。它不首先检查这些值是否已经存在(即使存在PK)。简单的repro会产生相同的错误:
USE tempdb;
GO
CREATE TABLE dbo.floob(ID INT IDENTITY(1,1) PRIMARY KEY);
GO
INSERT dbo.floob DEFAULT VALUES;
GO
DBCC CHECKIDENT('dbo.floob', RESEED, 0);
GO
INSERT dbo.floob DEFAULT VALUES;
GO
DROP TABLE dbo.floob;
要阻止这种情况发生,您可以找出现在的最大值,然后再次运行CHECKIDENT
:
DBCC CHECKIDENT('dbo.tablename', RESEED, <max value + 10 or 20 or something here>);