从您的示例来看,您似乎没有使用交易。我的猜测是语句的 SELECT 部分作为READ UNCOMMITTED运行,否则您将看不到重复项。有多种方法可以使用 ADO 启动事务,但我更喜欢使用存储过程。
尝试实现这样的事情:
CREATE PROC dbo.ResponseHeader_Insert
<more data to insert>,
@ProjectID INT,
@Status SMALLINT
as
insert responseheader (column names here)
select <param values here>, isnull(max(rhSerial), 0) + 1
from responseheader
where (rhstatus = @Status) AND (rh_projectID = @ProjectID))
如果这对你不起作用,请尝试创建序列表(每个序列一个)。
create table <tablename> (
SeqID int identity(1,1) primary key,
SeqVal varchar(1)
)
创建一个获取下一个身份的过程:
create procedure GetNewSeqVal_<tablename>
as
begin
declare @NewSeqValue int
set NOCOUNT ON
insert into <tablename> (SeqVal) values ('a')
set @NewSeqValue = scope_identity()
delete from <tablename> WITH (READPAST)
return @NewSeqValue
end
如果需要创建的序列表太多,或者您想即时创建序列,请尝试以下方法:
Create table AllSequences (
SeqName nvarchar(255) primary key, -- name of the sequence
Seed int not null default(1), -- seed value
Incr int not null default(1), -- incremental
Currval int
)
Go
create procedure usp_CreateNewSeq
@SeqName nvarchar(255),
@seed int = 0,
@incr int = 1
as
begin
declare @currval int
if exists (
select 1 from AllSequences
where SeqName = @SeqName )
begin
print 'Sequence already exists.'
return 1
end
if @seed is null set @seed = 1
if @incr is null set @incr = 1
set @currval = @seed
insert into AllSequences (SeqName, Seed, Incr, CurrVal)
values (@SeqName, @Seed, @Incr, @CurrVal)
end
go
create procedure usp_GetNewSeqVal
@SeqName nvarchar(255)
as
begin
declare @NewSeqVal int
set NOCOUNT ON
update AllSequences
set @NewSeqVal = CurrVal = CurrVal+Incr
where SeqName = @SeqName
if @@rowcount = 0 begin
print 'Sequence does not exist'
return
end
return @NewSeqVal
end
go