再シードについて読んだすべてのドキュメントは、次のようなことを示唆しています。
SET @maxIdentityValue = (SELECT MAX(id) FROM tablename)
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';
[〜#〜] msdn [〜#〜] で説明されているように、次のように使用するだけで十分です。
DBCC CHECKIDENT('tablename', RESEED)
ただし、ほとんどの場合、機能しない次の2つの条件があります。
あなたが言及した方法で彼らと一緒に行かなければならない(max(id)と残りを選択する)ので、なぜそもそもわざわざするのですか? :)
再シードしてギャップを残すことができるように、最大値を決定したい場合があります(例:最大値+ 100)。 1つのケースは、テーブルの複数のコピーがあり、それらから独立しているが相互に排他的なID範囲を配布しようとしている場合です。
しかし、それでも、パラメーターなしのRESEEDがすべてのシナリオで正しく機能するかどうかはわかりません。
テーブルを最大に再シードするのはよくあることですか?どうして?ループ内に一連の行を生成し、最終的にロールバックする、コーディングが不十分なアプリケーションですか?
いずれの場合も、MAXとRESEEDをトランザクションでラップして、最大値を取得した後、再シードを発行する前にユーザーが新しい行を挿入する可能性を防ぐ必要があります。
おそらく最も簡単な方法(これは聞こえるほどクレイジーで、見た目はコードの臭いがする)は、次のように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列の最大値を使用してリセットされます。