例では、トランザクションを使用しているように見えません。私の推測では、ステートメントのSELECT部分はとして表示されていますが、これはREADCOMMODTEDです。そうでなければ重複は見られません。 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))
これはyaのために動作しない場合は、シーケンステーブル(各シーケンスに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
'rhserial'カラムを' INT IDENTITY'カラムにして、連続番号を増やしてSQL Serverに残すことはできませんか?これは本当に最善の方法です。面倒な手間や煩わしさはありません。SQL Serverに作業をさせてください。 –
いいえ。各プロジェクトにはシリアル番号が必要です。したがって、プロジェクト1234は1から上に向かってrhserialを持ちます。また、プロジェクト1235には、1つ上から上に向かってrhserialがあります。 rhserialはテーブル全体で一意ではありません。 – derekcohen
この場合、(1)各プロジェクトの現在のシリアル番号を持つテーブルと、(2)各プロジェクトの次の有効な番号を取得するためのスレッドと並行処理に安全なメソッド(ストアドプロシージャなど)が必要です。その "シリアルテーブルなし"。 'SELECT MAX()+ 1'を使うだけで、**負荷のかからない**安全です。 [この他のSOの質問とこれを行う方法を示すRemus Rusanuの答えを参照してください](http://stackoverflow.com/questions/5083846/sql-server-2005-using-generated-sequences-instead-of-identity-columns ) –