【发布时间】:2012-06-11 11:23:33
【问题描述】:
我有一个具有 InvoiceID (int identity) 主键的发票表。和一列 InvoiceNumber,它是一个整数。我有另一个表用于生成名为 Invoice_Numbers 的发票编号(见下文)。为了确保发票号码是唯一的并防止出现空白,我实施了以下代码。有人可以查看此代码并评论其可靠性。在多用户环境中运行 SQL 2008。
用户在插入发票时拨打电话然后购买时获得相同发票编号的可能性有多大?
如果存在 (选择 * FROM 系统对象 WHERE object_id = OBJECT_ID(N'[Imports].[Invoices_Numbers]') 并输入(N'U')) DROP TABLE [Imports].[Invoices_Numbers]去
CREATE TABLE [Imports].[Invoices_Numbers] ( [InvoiceNumber] [INT] IDENTITY(1, 1) 非空 ,[已删除] [BIT] 非空 ,[已使用] [BIT] 不为空, 约束 [PK_Invoices_Numbers] 主键集群([InvoiceNumber] ASC)与(PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF,IGNORE_DUP_KEY = OFF,ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON)ON [PRIMARY] ) 在 [主要]
去
ALTER PROCEDURE [Imports].[Get_Invoice_Number] ( @InvoiceNumber INT 输出 ) 作为 开始 声明 @NewNumber INT 声明 @MinNumber INT
BEGIN TRAN
SELECT @MinNumber = MIN(InvoiceNumber)
FROM Imports.Invoices_Numbers
IF @MinNumber > 1
BEGIN
SET IDENTITY_INSERT Imports.Invoices_Numbers ON;
INSERT Imports.Invoices_Numbers
(
Invoicenumber
,Deleted
,Used
)
VALUES
(
1
,0
,1
)
SET IDENTITY_INSERT Imports.Invoices_Numbers OFF;
SET @NewNumber=1
END
ELSE
BEGIN
WITH Gaps
AS (SELECT TOP 1 a.InvoiceNumber + 1 AS GapValue
FROM Imports.Invoices_Numbers a
WHERE NOT EXISTS
(SELECT *
FROM Imports.Invoices_Numbers b
WHERE b.InvoiceNumber = a.InvoiceNumber + 1)
AND a.InvoiceNumber <
(SELECT MAX(InvoiceNumber)
FROM Imports.Invoices_Numbers))
SELECT @NewNumber = GapValue
FROM Gaps
IF @NewNumber IS NULL
BEGIN
SELECT TOP 1 @NewNumber = InvoiceNumber
FROM Imports.Invoices_Numbers
WHERE Used = 0
AND Deleted = 0
ORDER BY InvoiceNumber
IF @NewNumber IS NULL
BEGIN
INSERT Imports.Invoices_Numbers
(
Deleted
,Used
)
VALUES
(
0
,1
)
SELECT @NewNumber = SCOPE_IDENTITY ()
END
ELSE
BEGIN
UPDATE Imports.Invoices_Numbers
SET Used = 1
WHERE InvoiceNumber = @NewNumber
END
END
ELSE
BEGIN
SET IDENTITY_INSERT Imports.Invoices_Numbers ON;
INSERT Imports.Invoices_Numbers
(
Invoicenumber
,Deleted
,Used
)
VALUES
(
@NewNumber
,0
,1
)
SET IDENTITY_INSERT Imports.Invoices_Numbers OFF;
END
END
SELECT @InvoiceNumber = @NewNumber
COMMIT TRAN
结束
【问题讨论】:
-
Gareth 你还没有完整阅读这篇文章
-
Olivier 刚刚浏览了该链接。然而,它并没有解决我试图解决的关键问题。首先,环境是多用户的,因此可能会出现 proc。被同时调用是有的。第二个即时消息使用第二个表生成发票编号(串行),我确保如果出现问题,空白被填补。仔细查看proc。看看我想做什么。
-
公平点。我已删除该评论。如果您将 UNIQUE CONSTRAINT 添加到您的 InvoiceNumber 列,您将防止重复。
-
“序列”一词似乎让所有人望而却步。这个问题与会计有关——发票号、订单号、抽奖券号等需要分发给多个并发用户,并且会计师需要知道每个用户发生了什么和他们每一个人。 通常认为有必要按顺序发布它们(因此,没有间隙),但这实际上取决于应用程序。
标签: sql sql-server sql-server-2008