我有一个表,其中包含事务的标头信息。交易属于不同的项目。
在标题中我有列:
rhguid - uniqueidentifier
rhserial - int
rh_projectID - int
首先我插入行(还有更多列)
然后我计算该项目的序列号:
update responseheader
set rhSerial = 1 + (select isnull(max(rhSerial), 0)
from responseheader
where (rhstatus = 0) AND (rh_projectID = 1234))
where
(rhGUID = <preassignedGUID>);
但是,当项目同时发生许多交易时,我发现重复的rhserial
值。
我在使用SQL Server 2008的经典ASP中这样做。
有更好的方法吗?
答案 0 :(得分:1)
从您的示例来看,它看起来不像您正在使用交易。我的猜测是语句的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))
如果这对ya不起作用,请尝试创建序列表(每个序列一个)。
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