あなたの例から、トランザクションを使用しているようには見えません。私の推測では、ステートメントの 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))
これがうまくいかない場合は、シーケンス テーブル (シーケンスごとに 1 つ) を作成してみてください。
create table <tablename> (
SeqID int identity(1,1) primary key,
SeqVal varchar(1)
)
次の ID を取得する手順を作成します。
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