滚动计数器

时间:2012-04-27 08:38:06

标签: tsql sql-server-2005

我需要使用这样的现有表来促进滚动计数器: -

CREATE TABLE [dbo].[IdentityCounter](
    [CounterName] [nvarchar](255) NOT NULL,
    [StartId] [bigint] NOT NULL,
    [EndId] [bigint] NOT NULL,
    [CurrentId] [bigint] NOT NULL,
    [CreatedTime] [datetime] NULL,
    [ModifiedTime] [datetime] NULL,
    [Description] [nvarchar](255) NULL
) ON [PRIMARY]

例如说我有以下内容: -

 CounterName  "ReceiptNumber"
 StartId  1
 EndId  99999 
 etc. etc.

对于特定的CounterName,我希望能够将存储过程或函数调用到: -

  • 为了获取下一个值并将其保存回CurrentId并将CurrentId作为结果发回

  • 如果下一个值等于EndId + 1,那么我需要使下一个值等于StartId并将其保存回CurrentId。同时发送CurrentId作为结果。

  • 会有多个应用程序调用此方法,因此需要确保事情保持一致。

计数器不是关键,它只是需要传递给第三方服务的东西。

最好的方法是什么?

谢谢! ITG

1 个答案:

答案 0 :(得分:1)

首先,我声明的数据看起来像你问题中的数据。如果您在问题中声明这一点会更好,以便我们都使用相同的数据。数据有一个区别:出于演示目的,EndID为5而不是99999。

INSERT INTO dbo.IdentityCounter(
  CounterName,
  StartID,
  EndID,
  CurrentID
)
VALUES (
  N'ReceiptNumber',
  1,
  5,
  1
);

此程序符合您的要求:

CREATE PROCEDURE dbo.IncrementCounter (
  @CounterName NVARCHAR(255)
)
AS
BEGIN
  SET NOCOUNT ON;

  UPDATE dbo.IdentityCounter
  SET CurrentID = CASE WHEN CurrentID = EndID THEN StartID ELSE CurrentID + 1 END
  OUTPUT DELETED.CurrentID
  WHERE CounterName = @CounterName;
END;

它返回一个'标量'结果集(一列,一行),表示在计数器递增之前给定CounterName的CurrentID值。

重复执行的例子:

EXEC dbo.IncrementCounter
  @CounterName = 'ReceiptNumber';
EXEC dbo.IncrementCounter
  @CounterName = 'ReceiptNumber';
EXEC dbo.IncrementCounter
  @CounterName = 'ReceiptNumber';
EXEC dbo.IncrementCounter
  @CounterName = 'ReceiptNumber';
EXEC dbo.IncrementCounter
  @CounterName = 'ReceiptNumber';
EXEC dbo.IncrementCounter
  @CounterName = 'ReceiptNumber';
EXEC dbo.IncrementCounter
  @CounterName = 'ReceiptNumber';
EXEC dbo.IncrementCounter
  @CounterName = 'ReceiptNumber';
EXEC dbo.IncrementCounter
  @CounterName = 'ReceiptNumber';
EXEC dbo.IncrementCounter
  @CounterName = 'ReceiptNumber';

应输出与此序列类似的十个结果集:123451,{ {1}},234