2011-08-03 9 views
0

私は請求書を格納するSQL Serverテーブルを使用して、請求書を呼び出すことができます。私は請求書(連続していない自動識別ではありません)のための連続的な自動番号機能を実装する必要があります。さらに、ユーザーAとユーザーBの請求書の並行処理の問題を同時に処理する必要がありますが、2つの請求書には同じ番号(明らかに)を使用するべきではありません。連続自律番号

T-SQLの理想的な実装方法は何でしょうか?

+0

私はアイデンティティ列を使用する必要はありませんか? – Ioannis

+0

SQL ServerのIDENTITY列は、並行性とパフォーマンスという2つの重要な問題(ビュー)にあるため、そのまま実装されています。あなたは前者のためにユニークな値を持つことが保証されていますが、後者のために可能なギャップを守る必要があります。今あなたはギャップの可能性を排除しようとしています(IDENTITYのあなたの実装で)。あなたは、あなたが戻って苦しんでいると思いますか? –

+0

私は非常に明確ではありません...たとえば、最後の請求書には190があり、請求書番号32を削除します。それから新しい挿入された請求書は番号32を持つ必要があります。それは私がアイデンティティを必要としない理由です。 – Ioannis

答えて

2

私たちが何か類似した方法をとったのは、[ID]と呼ばれる1列のuseIDというテーブルを作成することでした。 Integerデータ型を使用します。この表には1行しかありません。それ以上のことは少しあります。

今度は、イベント番号SELECTuseIDからログに記録し、追跡の目的でこの[ID]値を使用してトランザクションを実行する必要があるたびに、 SELECT[ID]に変更された直後に、useIDの値を1増やします(または問題のシステムに必要なものすべて)。このようにして、ユニークで連続した[ID]値を維持します。新しい[ID]値の順序に影響を与えずに、[ID]値の宛先から削除することができます。私たちがこれを使って夜間に約10百万回の取引を実行し、3ヶ月ごとに開始値をリセットするので、これは非常に優れています。

2

IDENTITYカラム。

英数字の請求書番号が必要な場合は、質問を必要な形式で更新することをお勧めします。

レコードを削除したり、INSERT中にエラーが発生したり、INSERTを含むトランザクションをテーブルにロールバックしたり、関連するdbccコマンドによってシードが更新された場合には、ギャップが生じます。

実際にギャップを再利用する必要がある場合(例:請求書のようなものに対してはそうしないことにします(例:請求書#32では後日、請求書番号190 ...)シリアライズ可能なトランザクションで最低の空き値を見つけ、アイデンティティの挿入を設定し、そのId値を持つ行を挿入し、アイデンティティを挿入してトランザクションをコミットすることができます。 (未テスト)このような

何か:それは必要ではない場合

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 

BEGIN TRAN 
SET IDENTITY_INSERT dbo.myTable ON 

DECLARE @minId int = -1 

;WITH cterows(Id, rownum) 
AS 
(
    SELECT Id, row_number() OVER(ORDER BY Id ASC) AS rownum 
) 
SELECT @minId = MIN(rownum) FROM cterows 
WHERE Id <> rownum 

IF (@minId IS NOT NULL AND @minId <> -1) 
    BEGIN 
    -- found a gap 
    -- Insert at @minId 
    END 
ELSE 
    BEGIN 
    -- No gap, INSERT as normal 
    END 


SET IDENTITY_INSERT dbo.myTable OFF; 
COMMIT 
1

は、これらの番号がためにあなたが乱数を作成することができ、続けて、それがあるべき場合は、あなたがその列IDENTITY colunmを作ることができます続けて

あなたの乱数を作成するには、チェックこのpost

0

あなたは英数字の請求書番号のためSQL Varchar列を作ることができ、ここでは、一意の請求書を生成する必要がないか、を使用することができます列。

関連する問題