当我从大型 Excel 将数据导入新表时,如果一条记录失败,则不会导入任何内容。我认为这没关系,因为它符合原子性规则。但是,当我修复源数据错误并再次导入时,标识列不是从 1 开始,而是从一个大值开始。
例如
create table #test (id int identity(1,1), name varchar(4) default '')
insert into #test (name) values('1 insert will failed');
select ident_current('#test') as ident_current
insert into #test (name) values('2 insert will failed');
select ident_current('#test') as ident_current
insert into #test (name) values('3 OK');
select ident_current('#test') as ident_current
select * from #test
drop table #test
结果
id name
----------- ----
3 3 OK
维基百科将ACID描述为如下
原子性
原子性要求每个事务都是“全有或全无”:如果事务的一部分失败,则整个事务失败,数据库状态保持不变。原子系统必须保证每种情况下的原子性,包括电源故障、错误和崩溃。
因此,如果插入失败,SQL Server 似乎不会让数据库状态(标识值)保持不变,那么,这是否违反了 ACID 规则?
顺便说一句,当插入失败时,PostgreSQL 不会让身份(序列)值增长。(更新:仅有时,请参阅评论。不要依赖于此。)。
test=# create table AutoIncrementTest (id serial not null, name varchar(4));
NOTICE: CREATE TABLE will create implicit sequence "autoincrementtest_id_seq" for serial column "autoincrementtest.id"
CREATE TABLE
test=# insert into autoincrementtest(name) values('12345');
ERROR: value too long for type character varying(4)
test=# insert into autoincrementtest(name) values('12345');
ERROR: value too long for type character varying(4)
test=# insert into autoincrementtest(name) values('1234');
INSERT 0 1
test=# select * from autoincrementtest;
id | name
----+------
1 | 1234