首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

使用預存程序模擬 IDENTITY(100,1) 自動遞增邏輯

     編輯:關於SqlServer

情境

需在不使用 IDENTITY 欄位的情況下,實現從 100 起始、遞增 1 的序號產生機制(如訊息編號)。

實作:序號管理表 + 預存程序

1. 建立序號儲存表

CREATE TABLE common_info (
    name VARCHAR(10),
    value INT
)
INSERT INTO common_info VALUES ('msg_count', 100)

2. 取號預存程序(含並發保護)

CREATE PROC p_ins_alm_msg
    @msg_count INT OUTPUT
AS
BEGIN
    -- 取得目前值
    SELECT @msg_count = value 
    FROM common_info 
    WHERE name = 'msg_count'

    -- 嘗試原子性更新:舊值比對確保無競爭
    UPDATE common_info 
    SET value = @msg_count + 1 
    WHERE name = 'msg_count' AND value = @msg_count

    -- 若更新 0 列表被並發修改,回傳錯誤
    IF @@ROWCOUNT = 0
        RETURN -1000

    -- 使用新序號插入業務表
    INSERT INTO table1 (field0) VALUES (@msg_count)
    RETURN 0
END
GO

關鍵設計點

  • 樂觀並發控制:WHERE value = @msg_count 確保更新基於讀取時的值,避免競爭條件
  • 輸出參數回傳:呼叫端可直接取得配發序號
  • 錯誤代碼:-1000 表並發衝突,呼叫端可重試

呼叫範例

DECLARE @next_id INT
EXEC @ret = p_ins_alm_msg @next_id OUTPUT
IF @ret = 0
    PRINT '配發序號:' + CAST(@next_id AS VARCHAR)
ELSE
    PRINT '並發衝突,請重試'

替代方案比較

若環境支援,優先使用 IDENTITY 或 SEQUENCE;僅在舊版本或特殊業務需求下採用序號表方案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方案優點缺點
IDENTITY 欄位原生、高效、無並發問題難以重設種子、跨表同步困難
序號表 + 預存程序彈性控制、跨表共用、可手動調整需自行處理並發、效能略低
SEQUENCE (SQL 2012+)原生序列物件、支援快取、跨表舊版不支援