1

このクエリを実行すると、ID に null 値が返されます。コードは、id 列の最大値を取得することになっています。

2013-06-13-0001
2013-06-13-0002

id 列のを取得する必要があります2013-06-13-0002(0002は よりも大きい値であるため)。クエリは最大 ID を取得し、それに 1 を追加することになっています。0001

SELECT 
   ID = LEFT(max(ID), 10) + '-' + 
        RIGHT('000' + CONVERT(VARCHAR, CONVERT(INT, RIGHT(max(ID), 4)) + 1), 4)
FROM John_IEP_Crossing_Dock_Shipment
WHERE
   LEFT(ID, 10) = CONVERT(VARCHAR(10), Getdate(), 20) 
4

1 に答える 1

1

実際にレコードを挿入する前に、このような新しいカスタム ID を選択しようとしないでください。他の誰かがあなたの前に同じ値を挿入する可能性があります。したがって、テーブル挿入を潜在的に実行する方法は次のとおりです。

insert into John_IEP_Crossing_Dock_Shipment (MyCol1, MyCol2, ID)
select @MyFormValue1,
    @MyFormValue2,
    convert(varchar(10), current_timestamp, 20)
        + '-'
        + right('000' + cast(cast(right(coalesce(max(ID), '0'), 4) as smallint) + 1 as varchar(4)), 4)
from John_IEP_Crossing_Dock_Shipment
where ID like convert(varchar(10), current_timestamp, 20) + '%'; -- like may use an index in this case

挿入前ではなく、挿入中に ID を考え出します。これにより、競合の問題はほとんど解決されます (4 桁の ID サフィックスでは、とにかく 1 日あたり 9,999 個の挿入しかできません) 。またcoalesce、今日まだデータがない場合 (および挿入 ID "...- 0001")。

挿入直後にこのレコードを選択してユーザーに表示する必要がある場合は、outputキーワードを使用できます。

まだ持っていない場合は、この ID 列に何らかの一意の制約を追加することが必須です。少なくとも、例外を処理し、競合がまだ問題である場合は、ユーザーが挿入を再試行できるようにすることができます (これらの挿入が衝突することは決してないか、またはそのようなことを防ぐためにテーブルをロックする必要があるかどうかを言うのに十分な専門家ではありません)。 )。

私は@MartinSmithに同意し、ID列(またはおそらく2012年のシーケンス)で作成日列を使用して、このID列を計算できるようにしたいと思います。また、一部の部品番号付けスキームは保存する必要があり、スキップされた番号が有効でない場合があることも理解しています (削除がない限り)。

詳しい方からのご意見をお待ちしております。

于 2013-06-14T21:13:57.660 に答える