SQL Server标识列插入失败

时间:2011-11-02 07:34:13

标签: sql-server

大家好我只有一个简单的问题:

当标识列上的insert语句失败时会发生什么?

是否有可能说,例如,如果我插入一个带有标识列的行,那个标识列将为1,并再次插入但是失败并且不插入和数据。然后尝试再次插入,该行的标识现在是3?

非常感谢任何建议。

感谢。

3 个答案:

答案 0 :(得分:5)

这取决于数据插入失败的原因是什么。例如,如果值无效(类型错误),则不会增加标识值。但是,如果第一个插入成功,但随后被删除(通过事务失败并回滚),则身份值IS递增。

-- Next identity value = 1
INSERT INTO Table1 (
    field1)
VALUES ('a')

-- Next identity value = 2    
BEGIN TRAN
INSERT INTO Table1 (
  field1)
VALUES ('b')

-- Next identity value = 3    
ROLLBACK TRAN

-- Next identity value = 3, although the insertion was removed.    
INSERT INTO Table1 (
  field1)
VALUES ('c')

-- Next identity value = 4

第一个插入将具有标识列值= 1,第二个插入失败,第三个插入将具有标识列值= 3.

答案 1 :(得分:1)

仅仅因为列具有IDENTITY规范并不一定意味着它是唯一的。

如果在该列上具有唯一约束(或主键约束),则可以将多个相同的值插入该列的行中。

但是,通常,您的IDENTITY作为主键(或者至少对它们有UNIQUE个约束),在这种情况下,尝试插入已经存在的值将导致错误(“唯一约束违规”或类似的东西)

为了能够将特定值插入IDENTITY列,您需要拥有SET IDENTITY_INSERT (table name) ON - 否则,SQL Server将阻止您甚至为IDENTITY列指定值

为了说明 - 试试这个:

 -- create demo table, fill with values
CREATE TABLE IdentityTest (ID INT IDENTITY, SomeValue CHAR(1))

INSERT INTO IdentityTest(SomeValue) VALUES('A'), ('B'), ('C')

SELECT * FROM IdentityTest  -- Output (1)

-- insert duplicate explicit values into table
SET IDENTITY_INSERT IdentityTest ON

INSERT INTO IdentityTest(ID, SomeValue) VALUES(1, 'Z'), (2, 'Y')

SET IDENTITY_INSERT IdentityTest OFF

SELECT * FROM IdentityTest  -- Output (2)

-- add unique constraint
TRUNCATE TABLE dbo.IdentityTest

ALTER TABLE IdentityTest ADD CONSTRAINT UX_ID UNIQUE(ID)

INSERT INTO IdentityTest(SomeValue) VALUES('A'), ('B'), ('C')

SET IDENTITY_INSERT IdentityTest ON

INSERT INTO IdentityTest(ID, SomeValue) VALUES(1, 'Z')  -- error message (3)

DROP TABLE IdentityTest

输出(1):

ID  SomeValue
1   A
2   B
3   C

输出(2):

ID  SomeValue
1   A
2   B
3   C
1   Z
2   Y

错误讯息(3):

  

Ms 2627,Level 14,State 1,Line 9
  违反UNIQUE KEY约束'UX_ID'。无法在对象'dbo.IdentityTest'中插入重复键。重复键值为(1)。

答案 2 :(得分:1)

一种方法是在行已存在时阻止插入。

IF (Not Exists (Select ID From Table Where SomeCol = @SomeVal) Insert Into Table Values (@SomeVal)