序列化表中的行

时间:2012-04-22 08:29:02

标签: sql-server-2008 tsql asp-classic

我有一个表,其中包含事务的标头信息。交易属于不同的项目。

在标题中我有列:

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中这样做。

有更好的方法吗?

1 个答案:

答案 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