SQL Serverでレコードを削除した後、IDシードをリセットします

735
xorpower 2014-02-17 22:51.

SQLServerデータベーステーブルにレコードを挿入しました。テーブルには主キーが定義されており、自動インクリメントIDシードは「はい」に設定されています。これは主に、SQL Azureでは、各テーブルに主キーとIDを定義する必要があるためです。

ただし、テーブルからいくつかのレコードを削除する必要があるため、それらのテーブルのIDシードが妨害され、インデックス列(1の増分で自動生成される)が妨害されます。

レコードを削除した後、ID列をリセットして、列の番号が昇順になるようにするにはどうすればよいですか?

ID列は、データベース内のどこでも外部キーとして使用されません。

18 answers

1175
Petr Abdulin 2014-02-17 23:04.

DBCC CHECKIDENT管理コマンドは、IDカウンタをリセットするために使用されます。コマンド構文は次のとおりです。

DBCC CHECKIDENT (table_name [, { NORESEED | { RESEED [, new_reseed_value ]}}])
[ WITH NO_INFOMSGS ]

例:

DBCC CHECKIDENT ('[TestTable]', RESEED, 0);
GO

以前のバージョンのAzureSQLデータベースではサポートされていませんでしたが、現在はサポートされています。


SQL Serverでレコードを削除した後、IDシードをリセットしますのおかげで、コマンドのドキュメントが修正されました。

231
anil shah 2014-02-17 22:59.
DBCC CHECKIDENT ('TestTable', RESEED, 0)
GO

ここで、0はidentity開始値です。

96
Solomon Rutzky 2014-12-06 08:15.

IFことに留意すべき全てのデータが経由してテーブルから削除されているDELETE(すなわちノーWHEREであるように思われる(表を参照ないFKSが存在しない)、その後限り)アクセス許可が、aとbを可能にするように、句)ここでの場合)、TRUNCATE TABLEより効率的であると同時にシードをリセットするため、を使用することDELETE をお勧めしますIDENTITY。以下の詳細は、TRUNCATETABLEのMSDNページから抜粋したものです。

DELETEステートメントと比較すると、TRUNCATETABLEには次の利点があります。

  • 使用されるトランザクションログスペースが少なくなります。

    DELETEステートメントは、一度に1行ずつ削除し、削除された各行のエントリをトランザクションログに記録します。TRUNCATE TABLEは、テーブルデータの格納に使用されるデータページの割り当てを解除することでデータを削除し、ページの割り当て解除のみをトランザクションログに記録します。

  • 通常、使用されるロックは少なくなります。

    行ロックを使用してDELETEステートメントを実行すると、テーブル内の各行が削除のためにロックされます。TRUNCATE TABLEは、常にテーブル(スキーマ(SCH-M)ロックを含む)とページをロックしますが、各行はロックしません。

  • 例外なく、テーブルにはゼロページが残っています。

    DELETEステートメントが実行された後でも、テーブルには空のページを含めることができます。たとえば、ヒープ内の空のページは、少なくとも排他的(LCK_M_X)テーブルロックがないと割り当てを解除できません。削除操作でテーブルロックを使用しない場合、テーブル(ヒープ)には多くの空のページが含まれます。インデックスの場合、削除操作によって空のページが残る可能性がありますが、これらのページはバックグラウンドクリーンアッププロセスによってすばやく割り当て解除されます。

テーブルにID列が含まれている場合、その列のカウンターは、その列に定義されているシード値にリセットされます。シードが定義されていない場合は、デフォルト値1が使用されます。IDカウンターを保持するには、代わりにDELETEを使用します。

したがって、次のようになります。

DELETE FROM [MyTable];
DBCC CHECKIDENT ('[MyTable]', RESEED, 0);

ちょうどなる:

TRUNCATE TABLE [MyTable];

TRUNCATE TABLE制限事項などの詳細については、上記のドキュメント(上記のリンク)を参照してください。

91
Atal Kishore 2016-05-08 10:36.

ほとんどの回答はRESEEDを0に提案していますが、多くの場合、利用可能な次のIDに再シードする必要があります

declare @max int
select @max=max([Id])from [TestTable]
if @max IS NULL   //check when max is returned as null
  SET @max = 0
DBCC CHECKIDENT ('[TestTable]', RESEED,@max)

これにより、テーブルがチェックされ、次のIDにリセットされます。

64
Mikael Engver 2014-09-11 23:34.

私は@anil shahs答えようとしました、そしてそれはアイデンティティをリセットしました。しかし、新しい行が挿入されると、が取得されましたidentity = 2。そこで、代わりに構文を次のように変更しました。

DELETE FROM [TestTable]

DBCC CHECKIDENT ('[TestTable]', RESEED, 0)
GO

次に、最初の行はID = 1を取得します。

17
RealSollyM 2015-08-11 23:47.

ほとんどの回答はを示唆RESEEDして0おり、これをTRUNCATEDテーブルの欠陥と見なす人もいますが、Microsoftには、ID

DBCC CHECKIDENT ('[TestTable]', RESEED)

これにより、テーブルがチェックされ、次のにリセットされIDます。これは、MS SQL2005から現在まで利用可能です。

https://msdn.microsoft.com/en-us/library/ms176057.aspx

9
jacob 2016-07-12 21:57.

2コマンドを発行するとトリックが可能です

DBCC CHECKIDENT ('[TestTable]', RESEED,0)
DBCC CHECKIDENT ('[TestTable]', RESEED)

最初はIDをゼロにリセットし、次はそれを次に使用可能な値に設定します--jacob

7
epic 2016-12-07 01:46.

@jacob

DBCC CHECKIDENT ('[TestTable]', RESEED,0)
DBCC CHECKIDENT ('[TestTable]', RESEED)

私のために働いた、私は最初にテーブルからすべてのエントリをクリアし、次に削除後のトリガーポイントに上記を追加する必要がありました。これで、削除するたびにそこからエントリが取得されます。

7
Dyna Dave 2017-04-20 06:31.

Truncate テーブルは、レコードをクリアし、カウンターをリセットし、ディスク領域を再利用するため、推奨されます。

DeleteまたCheckIdent、外部キーによって切り捨てができない場合にのみ使用してください。

5
Mukesh Pandey 2017-03-30 20:00.

ID列を新しいIDでリセット...

DECLARE @MAX INT
SELECT @MAX=ISNULL(MAX(Id),0) FROM [TestTable]

DBCC CHECKIDENT ('[TestTable]', RESEED,@MAX)
3
Ben Thul 2014-02-18 05:00.

これはよくある質問であり、答えは常に同じです。そうしないでください。ID値は任意として扱う必要があるため、「正しい」順序はありません。

3
Matthew Baic 2014-12-06 05:02.

このスクリプトを実行して、ID列をリセットします。2つの変更を加える必要があります。tableXYZを、更新する必要のあるテーブルに置き換えます。また、ID列の名前を一時テーブルから削除する必要があります。これは、35,000行3列のテーブルでは瞬時に行われました。明らかに、テーブルをバックアップし、最初にテスト環境でこれを試してください。


select * 
into #temp
From tableXYZ

set identity_insert tableXYZ ON

truncate table tableXYZ

alter table #temp drop column (nameOfIdentityColumn)

set identity_insert tableXYZ OFF

insert into tableXYZ
select * from #temp
2
Chris Mack 2019-01-06 12:31.

これを行うには、次のスクリプトを使用します。「エラー」が発生するシナリオは1つだけです。これは、テーブルからすべての行を削除し、IDENT_CURRENT現在1に設定されている場合、つまり、最初はテーブルに1行しかなかった場合です。

DECLARE @maxID int = (SELECT MAX(ID) FROM dbo.Tbl)
;

IF @maxID IS NULL
    IF (SELECT IDENT_CURRENT('dbo.Tbl')) > 1
        DBCC CHECKIDENT ('dbo.Tbl', RESEED, 0)
    ELSE
        DBCC CHECKIDENT ('dbo.Tbl', RESEED, 1)
    ;
ELSE
    DBCC CHECKIDENT ('dbo.Tbl', RESEED, @maxID)
;
1
Bimzee 2016-05-02 21:11.
DBCC CHECKIDENT (<TableName>, reseed, 0)

これにより、現在のID値が0に設定されます。

次の値を挿入すると、ID値は1に増分されます。

1
costa 2017-10-05 10:11.

このストアドプロシージャを使用します。

IF (object_id('[dbo].[pResetIdentityField]') IS NULL)
  BEGIN
    EXEC('CREATE PROCEDURE [dbo].[pResetIdentityField] AS SELECT 1 FROM DUMMY');
  END
GO

SET  ANSI_NULLS ON
GO
SET  QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[pResetIdentityField]
  @pSchemaName NVARCHAR(1000)
, @pTableName NVARCHAR(1000) AS
DECLARE @max   INT;
DECLARE @fullTableName   NVARCHAR(2000) = @pSchemaName + '.' + @pTableName;

DECLARE @identityColumn   NVARCHAR(1000);

SELECT @identityColumn = c.[name]
FROM sys.tables t
     INNER JOIN sys.schemas s ON t.[schema_id] = s.[schema_id]
     INNER JOIN sys.columns c ON c.[object_id] = t.[object_id]
WHERE     c.is_identity = 1
      AND t.name = @pTableName
      AND s.[name] = @pSchemaName

IF @identityColumn IS NULL
  BEGIN
    RAISERROR(
      'One of the following is true: 1. the table you specified doesn''t have an identity field, 2. you specified an invalid schema, 3. you specified an invalid table'
    , 16
    , 1);
    RETURN;
  END;

DECLARE @sqlString   NVARCHAR(MAX) = N'SELECT @maxOut = max(' + @identityColumn + ') FROM ' + @fullTableName;

EXECUTE sp_executesql @stmt = @sqlString, @params = N'@maxOut int OUTPUT', @maxOut = @max OUTPUT

IF @max IS NULL
  SET @max = 0

print(@max)

DBCC CHECKIDENT (@fullTableName, RESEED, @max)
go

--exec pResetIdentityField 'dbo', 'Table'

私の答えをもう一度見てください。私はあなたが知っておくべきSQLServer2008r2で奇妙な振る舞いに出くわしました。

drop table test01

create table test01 (Id int identity(1,1), descr nvarchar(10))

execute pResetIdentityField 'dbo', 'test01'

insert into test01 (descr) values('Item 1')

select * from test01

delete from test01

execute pResetIdentityField 'dbo', 'test01'

insert into test01 (descr) values('Item 1')

select * from test01

最初の選択でが生成され0, Item 1ます。

2番目のものはを生成し1, Item 1ます。テーブルが作成された直後にリセットを実行すると、次の値は0になります。正直なところ、Microsoftがこのようなものを正しく取得できないのは驚きではありません。テーブルを再作成した後や、テーブルがすでに作成されているときに実行することがある参照テーブルにデータを入力するスクリプトファイルがあるために発見しました。

1
KimvdLinde 2020-04-28 04:42.

私は開発中に多数のテーブルに対してこれを実行しようとしてきましたが、これは魅力として機能します。

DBCC CHECKIDENT('www.newsType', RESEED, 1);
DBCC CHECKIDENT('www.newsType', RESEED);

したがって、最初に強制的に1に設定し、次にテーブルに存在する行の最高のインデックスに設定します。idexの残りの部分をすばやく簡単に。

0
Fandango68 2018-05-23 19:16.

完全なDELETE行とIDENTITYカウントをリセットするには、これを使用します(SQL Server 2008 R2)

USE mydb

-- ##################################################################################################################
-- DANGEROUS!!!! USE WITH CARE
-- ##################################################################################################################

DECLARE
  db_cursor CURSOR FOR
    SELECT TABLE_NAME
      FROM INFORMATION_SCHEMA.TABLES
     WHERE TABLE_TYPE = 'BASE TABLE'
       AND TABLE_CATALOG = 'mydb'

DECLARE @tblname VARCHAR(50)
SET @tblname = ''

OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @tblname

WHILE @@FETCH_STATUS = 0
BEGIN
  IF CHARINDEX('mycommonwordforalltablesIwanttodothisto', @tblname) > 0
    BEGIN
      EXEC('DELETE FROM ' + @tblname)
      DBCC CHECKIDENT (@tblname, RESEED, 0)
    END

  FETCH NEXT FROM db_cursor INTO @tblname
END

CLOSE db_cursor
DEALLOCATE db_cursor
GO
0
Ali Sufyan 2019-07-03 19:16.

テーブル全体をクリーンアップしない限り、0に再シードすることはあまり実用的ではありません。

そうでなければ、アンソニー・レイモンドによって与えられた答えは完璧です。最初に最大ID列を取得してから、maxをシードします。

Related questions

MORE COOL STUFF

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

ねえNFL、ジョーバロウとカイラーマレーは女性の権利をサポートするために少しの助けを使うことができます

ねえNFL、ジョーバロウとカイラーマレーは女性の権利をサポートするために少しの助けを使うことができます

ジョー・バロウロー対ウェイド事件の転覆に対応するNFLは、言葉を言わないことで、腹立たしいが予測可能なPRの結果でした。

別の日、別のヒンジのないLIV記者会見

別の日、別のヒンジのないLIV記者会見

(lから)パット・ペレス、ブルックス・ケプカ、パトリック・リードサウジアラビアのLIVゴルフリーグのさらに別の信じられないほどの記者会見で、スポーツのファンはブルックス・ケプカからでたらめな吐き気と質問回避の驚異的なマスタークラスを受けました。パトリックリード、ブライソンデシャンボー、パットペレス、最近のPGAツアーの脱北者。

ミズ・マーベルの家族の帰郷は悪役よりも激しく打撃を与える

ミズ・マーベルの家族の帰郷は悪役よりも激しく打撃を与える

レッドダガーとマーベルさんがチームを組んでいます。

6億7500万ドルのビットコインローンのデフォルト後にすべての資産を清算するように命じられたスリーアローズキャピタル

6億7500万ドルのビットコインローンのデフォルト後にすべての資産を清算するように命じられたスリーアローズキャピタル

暗号業界最大の沈没船の1つであるスリーアローズキャピタルは、ついにその悲惨さから解放されています。火曜日に、不良債権ヘッジファンドは、債権者からの返済を要求する訴訟の高まりに応えて、バージンアイランド裁判所によって清算を命じられました彼らが3ACに行ったローン。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

Suffragettes Indicam #3: Junho

Suffragettes Indicam #3: Junho

Mais um mês se findando — e metade do ano de 2022 já passou. Sabe o que isso significa? Não, não é hora de verificar se você está cumprindo com suas resoluções de Ano Novo.

多元宇宙—Junø

多元宇宙—Junø

チェーン間アカウントがJunoに登場します。異なるブロックチェーン間でスマートコントラクトの構成可能性と真の相互運用性を提供します。

#brand【ベター・コール・ソール!アメリカのテレビシリーズ「ブレイキング・バッド」に最高のビジネス例が隠されている】・・・ルールクリエイティブ

#brand【ベター・コール・ソール!アメリカのテレビシリーズ「ブレイキング・バッド」に最高のビジネス例が隠されている】・・・ルールクリエイティブ

1.ドラマを見た後、起業する考えはありますか?あなたのビジネスはボトルネックに遭遇しましたか?方向性がなくてわからない場合は、ドラマを追いかけて行くことを心からお勧めします。(?)ブラフではなく、最も完璧なビジネス例を隠すドラマがあります。2.ブレイキング・バッドとその弁護士ドラマ「ブレイキング・バッド」を見た友人たちは、演劇の中で、穏やかな表情で、弁護士のソウル・グッドマンに深く感銘を受けなければなりません。口を開けて、感覚の弱い傭兵の性格を持っています。道徳の面で、サル・グッドマンは無意識のうちに劇に欠かせない役割を果たし、彼自身のシリーズ「絶望的な弁護士」(ベター・コール・ソール)を生み出しました。ウェントウのテキストとビデオは、劇中のソウル・グッドマンのテレビコマーシャルです。製品(サービス)、競争戦略、市場ポジショニング、ブランド名、ターゲット顧客グループ、コミュニケーション軸から広告まで、サル・グッドマンの役割のビジネス設定は、「最低」と見なすことができる超超超超超超完全です。ブランドコミュニケーションのコスト」「変化」のモデル。なぜ?私の分析をご覧ください。3.ソウル・グッドマンの「事業戦略」1.基本情報ブランド名:Saul Goodman製品:法律相談サービス対象顧客:麻薬中毒、飲酒運転、事故など。法律知識の欠如は、一般的に公立弁護士にしか余裕がなく、真面目な弁護士も「特別な法律を持つ消費者」を避けます。恐れてはいけない「​​ニーズ」。コミュニケーションの主軸:この国のすべての男性、女性、子供は有罪判決を受けるまで無実だと思います。地域:アルバカーキ市スローガン:Thrallに電話したほうがいいです!(ベター・コール・ソール)広告:2つの可能性のある犯罪状況をシミュレートします+サウルの主張+サウルのスローガン2をより適切に呼び出します。

メインネットガイド— Arbitrum Odyssey Week 2

メインネットガイド— Arbitrum Odyssey Week 2

最新のアップデートを受け取るために私たちに従ってください。ニュースレター:https://www。

Language