IDENTITY
の変更 プロパティは実際にはメタデータのみの変更です。ただし、メタデータを直接更新するには、インスタンスをシングルユーザーモードで起動し、sys.syscolpars
のいくつかの列をいじくり回す必要があります。 文書化されていない/サポートされていないため、私が推奨したり、追加の詳細を提供したりするものではありません。
SQL Server 2012+でこの回答に出くわした人にとって、列の自動インクリメントのこの結果を達成する最も簡単な方法は、SEQUENCE
を作成することです。 オブジェクトを作成し、next value for seq
を設定します 列のデフォルトとして。
または、以前のバージョン(2005以降)の場合、この接続アイテムに投稿された回避策は、ALTER TABLE...SWITCH
を使用したデータ操作のサイズを必要とせずにこれを行う完全にサポートされた方法を示しています 。こちらのMSDNについてもブログに書いています。これを実現するためのコードはそれほど単純ではなく、制限がありますが、テーブルが変更されるなど、外部キー制約のターゲットにすることはできません。
サンプルコード。
identity
のないテストテーブルを設定します 列。
CREATE TABLE dbo.tblFoo
(
bar INT PRIMARY KEY,
filler CHAR(8000),
filler2 CHAR(49)
)
INSERT INTO dbo.tblFoo (bar)
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT 0))
FROM master..spt_values v1, master..spt_values v2
identity
を持つように変更します 列(多かれ少なかれ瞬時)。
BEGIN TRY;
BEGIN TRANSACTION;
/*Using DBCC CHECKIDENT('dbo.tblFoo') is slow so use dynamic SQL to
set the correct seed in the table definition instead*/
DECLARE @TableScript nvarchar(max)
SELECT @TableScript =
'
CREATE TABLE dbo.Destination(
bar INT IDENTITY(' +
CAST(ISNULL(MAX(bar),0)+1 AS VARCHAR) + ',1) PRIMARY KEY,
filler CHAR(8000),
filler2 CHAR(49)
)
ALTER TABLE dbo.tblFoo SWITCH TO dbo.Destination;
'
FROM dbo.tblFoo
WITH (TABLOCKX,HOLDLOCK)
EXEC(@TableScript)
DROP TABLE dbo.tblFoo;
EXECUTE sp_rename N'dbo.Destination', N'tblFoo', 'OBJECT';
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
PRINT ERROR_MESSAGE();
END CATCH;
結果をテストします。
INSERT INTO dbo.tblFoo (filler,filler2)
OUTPUT inserted.*
VALUES ('foo','bar')
与える
bar filler filler2
----------- --------- ---------
10001 foo bar
クリーンアップ
DROP TABLE dbo.tblFoo