顺序发票号码SQL服务器

时间:2012-06-07 11:54:13

标签: sql sql-server sql-server-2008

我有一张发票表,其中包含InvoiceID(int identity)主键。还有一个InvoiceNumber列,它是一个整数。我有另一张表用于生成名为Invoice_Numbers的发票号码(见下文)。为了确保发票号码是唯一的并防止出现差距,我已经实施了以下代码。有人可以审查此代码并评论其可靠性。在多用户环境中运行SQL 2008。

在插入发票期间,用户在调用时获得相同的发票号码有多大的机会?

 
IF EXISTS
   (SELECT *
    FROM   sys.objects
    WHERE  object_id = OBJECT_ID(N'[Imports].[Invoices_Numbers]')
           AND type IN ( N'U' ))
  DROP TABLE [Imports].[Invoices_Numbers]

GO

CREATE TABLE [Imports].[Invoices_Numbers] ( [InvoiceNumber] [INT] IDENTITY(1, 1) NOT NULL ,[Deleted] [BIT] NOT NULL ,[Used] [BIT] NOT NULL, CONSTRAINT [PK_Invoices_Numbers] PRIMARY KEY CLUSTERED ( [InvoiceNumber] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]

GO

ALTER PROCEDURE [Imports].[Get_Invoice_Number] ( @InvoiceNumber INT OUTPUT ) AS BEGIN DECLARE @NewNumber INT DECLARE @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

END

1 个答案:

答案 0 :(得分:1)

您的解决方案看起来有点复杂。除了数据导入任务之外,我不建议使用set identity_insert

为了确保唯一性,我首先添加一个唯一约束:

alter table Invoices add constraint UX_Invoices_InvoiceNr unique

然后你可以使用这样的SQL语句来插入发票:

while 1=1
    begin        
    declare @new_nr int
    select  @new_nr = max(InvoiceNr) + 1
    from    dbo.Invoices

    if @new_nr is null
        set @new_nr = 1

    insert  dbo.Invoices
            (InvoiceNr, ...)
    values  (@new_nr, ...)

    if @@rowcount = 1
        break
    end