Tsql 滚动计数器

Tsql 滚动计数器,tsql,sql-server-2005,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, [Modifi

我需要使用这样的现有表格以方便滚动计数器:-

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.
对于特定的计数器名,我希望能够调用存储过程或函数:-

  • 获取下一个值并将其保存回CurrentId,然后将CurrentId作为结果发送回

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

  • 将有多个应用程序调用此功能,因此需要确保事情保持一致

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

最好的方法是什么


谢谢!ITG

首先,我声明的数据与您问题中的数据相似。如果你在你的问题中声明这一点会更好,这样我们都在使用相同的数据。数据有一个区别:出于演示目的,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;
它返回一个“标量”结果集(一列一行),表示计数器递增之前给定计数器名的
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';

应输出与此序列类似的十个结果集:
1
2
3
4
5
1
2
3
4
5
,首先,我声明的数据与您问题中的数据相似。如果你在你的问题中声明这一点会更好,这样我们都在使用相同的数据。数据有一个区别:出于演示目的,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;
它返回一个“标量”结果集(一列一行),表示计数器递增之前给定计数器名的
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';

应该输出与此序列相似的十个结果集:
1
2
3
4
5
1
2
3
4
5

不知道您的应用程序,但看到这样的表格会让我的头脑中出现一些红色的变化。为什么计数器不与相应的实体表关联?为什么您的ReceiptNumber不在收据表中?我找不到有这样一张桌子的好理由。当然,您的里程数可能会有所不同。ReceiptNumber会传递给第三方服务,我们最多可以使用五位数字,需要滚动。这不是什么钥匙。对不起,我应该在第一个问题中说得更清楚:(如果允许修改,则应在此表中添加声明性约束。我假设
CounterName
列是唯一的,并且可能是主键,因此应将其声明为唯一的。应向
CurrentId
添加检查约束,以使其永远不能小于
StartId
或大于
EndId
。如果您的ID值从未超过99999,则
BIGINT
是一种不合适的数据类型。
INT
将存储所有这些值。我不知道您的应用程序,但看到这样的表会在我的脑海中升起一些红色的alter标志。为什么您的计数器没有关联到相应的实体表?为什么您没有r ReceiptNumber是收据表的一部分?我找不到有这样一个计数器表的好理由。但是您的里程数当然可能会有所不同。收据号会传递给第三方服务,我们最多可以使用五位数字,它需要滚动。它不是任何类型的键。抱歉,在最初的问题中应该更清楚地说明这一点:(如果允许修改,则应在此表中添加声明性约束。我假设
CounterName
列是唯一的,并且可能是主键,因此应将其声明为唯一的。应向
CurrentId
添加检查约束,以使其永远不能小于
StartId
或大于
EndId
。如果您的ID值从未超过99999,则
BIGINT
是一种不合适的数据类型。
INT
将存储所有这些值。关于数据,是的,需要更多练习!!感谢您抽出时间回答:)关于数据,是的,需要更多的练习!!感谢您抽出时间回答,非常感谢:)