7

再シードについて読んだすべてのドキュメントは、次のようなことを示唆しています。

  1. SET @maxIdentityValue = (SELECT MAX(id) FROM tablename)
  2. 走るDBCC CHECKIDENT('tablename', RESEED, @maxIdentityValue)

それでも、必要なのは単純なDBCC CHECKIDENT('tablename', RESEED)ものだけであり、最大値を指定しなくても、テーブルから正しいID値を自動的に判別するように見えます。

最初に値を抽出することMAXが好ましい理由(パフォーマンスまたはその他)はありますか?

ピギーバックの質問:再シードが必要な理由は、レプリケーションを使用していて、データベースレプリケーションが実行されるたびにIDがNullに設定され続けるためです。私は何が間違っているのですか?各テーブルの正しいIDシードを維持するにはどうすればよいですか?

更新(現在のソリューション)

今のところ、最大値は使用していません。これは私が使用しているストアドプロシージャです(クエリを使用して生成し、sys.columnsそれぞれを新しいクエリウィンドウに切り取って貼り付けるだけです。混乱し、遅く、エレガントではありませんが、ストアドプロシージャに精通していないため、動的SQLクエリを使用したい):

declare @seedval integer
declare @maxval integer
declare @newval integer
set @seedval = (select ident_current('mytable'));
set @maxval = (select MAX(id) from mytable);
if @maxval > @seedval or @seedval is NULL
BEGIN
    print 'Need to reseed: max is '  + cast(@maxval as varchar) + ' and seed is ' + cast(@seedval as varchar) 
    dbcc checkident('mytable', RESEED);
    set @newval = (select ident_current('mytable'));
    print 'Max is ' + cast(@maxval as varchar) + ' and seed is ' + cast(@newval as varchar) 
END 
ELSE
    print 'No need to reseed'; 
4

3 に答える 3

9

MSDNに記載されているように、次のものを使用するだけで十分です。

 DBCC CHECKIDENT('tablename', RESEED)  

ただし、ほとんどの場合、次の 2 つの条件では機能しません。

  • 現在の ID 値がテーブルの最大値を超えています。
  • テーブルからすべての行が削除されます。

あなたが言及した方法で行かなければならないので(max(id)と残りを選択してください)、そもそもなぜ気にするのですか?:)

于 2013-01-21T19:01:49.453 に答える
2

再シードしてギャップを残すことができるように、最大​​値を決定したい場合があります (最大値 + 100 など)。1 つのケースとして、テーブルの複数のコピーがあり、それらから独立しているが相互に排他的な ID 範囲を配布する場合があります。

それでも、パラメーターなしの RESEED がすべてのシナリオで正しく機能するかどうかはわかりません。

テーブルを最大に再シードしているのはよくあることですか? なんで?ループ内で大量の行を生成し、最終的にロールバックするアプリケーションのコーディングが不十分ですか?

いずれにせよ、トランザクションで MAX と RESEED をラップして、最大値を取得した後、再シードを発行する前にユーザーが新しい行を挿入する可能性を防ぐ必要があります。

于 2013-01-21T18:51:46.443 に答える
2

(この他のSOページから回答を再投稿しています)

おそらく最も簡単な方法は (クレイジーに聞こえるかもしれませんが、見た目がコード臭いかもしれません)、次のDBCC CHECKIDENTように 2 回実行することです。

-- sets all the seeds to 1
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'', RESEED, 1)'

-- run it again to get MSSQL to figure out the MAX/NEXT seed automatically
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'')'

終わり。

必要に応じて、もう一度実行して、すべてのシードがどのように設定されているかを確認できます。

-- run it again to display what the seeds are now set to
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'')'

これは、ドキュメントのコメントを利用するための創造的な方法です。

テーブルの現在の ID 値が ID 列に格納されている最大 ID 値より小さい場合、ID 列の最大値を使用してリセットされます。

于 2016-11-03T04:55:34.527 に答える