0

InvoiceID (int ID) プライマリ キーを持つ請求書テーブルがあります。InvoiceNumber 列は整数です。Invoice_Numbers という請求書番号を生成するために使用する別のテーブルがあります (以下を参照)。請求書番号が一意であることを確認し、ギャップを防ぐために、以下のコードを実装しました。誰かがこのコードをレビューして、その信頼性についてコメントできますか? マルチユーザー環境で SQL 2008 を実行しています。

請求書の挿入中にユーザーが呼び出して手続きしたときに同じ請求書番号を取得する可能性はどのくらいですか?

 
存在する場合
   (選択する *
    FROM sys.objects
    WHERE object_id = OBJECT_ID(N'[輸入].[請求書番号]')
           AND タイプ IN ( N'U' ))
  DROP TABLE [インポート].[Invoices_Numbers]

行く

CREATE TABLE [インポート].[Invoices_Numbers] ( [InvoiceNumber] [INT] IDENTITY(1, 1) NOT NULL ,[削除] [BIT] NOT NULL ,[中古] [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] ) オン [プライマリ]

行く

ALTER PROCEDURE [インポート].[Get_Invoice_Number] ( @InvoiceNumber INT OUTPUT ) なので 始める 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

終わり

4

1 に答える 1

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
于 2012-06-07T12:27:50.820 に答える