2012-04-27 71 views
1

我需要使用現有的表像這樣便於滾動計數器: -滾動計數器

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

+0

不知道你的申請,但看到這樣的表在我的腦海裏提出了一些紅色的改變旗幟。爲什麼您的計數器不與相應的實體表關聯?爲什麼不是收據表中的ReceiptNumber部分?我找不到有這樣的櫃檯表的任何理由。但是,你的里程可能會有所不同,當然。 – 2012-04-27 09:37:29

+0

ReceiptNumber傳遞給第三方服務,我們最多可以使用5位數字並且需要滾動。這不是任何關鍵。對不起,應該在最初的問題中做得更清楚:( – inthegarden 2012-04-27 10:29:27

+0

如果你可以修改它,你應該爲這個表添加聲明性約束。我假設'CounterName'列是唯一的,可能是主鍵,所以它應該被聲明爲這樣,你應該爲'CurrentId'添加一個檢查約束,以便它永遠不會小於'StartId'或者大於'EndId'。 – 2012-04-27 13:19:44

回答

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; 

它返回一個「標」結果集(一列,一列),它代表了CurrentID對前定CounterName值計數器遞增。重複執行的

實施例:

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'; 

應輸出10結果集與此類似序列:1234512345

+0

Re。數據,是的,需要更多練習!感謝您抽出時間回答大家的讚賞:) – inthegarden 2012-04-27 13:39:45