あなたの質問は本質的に:
そもそも、私が本来許されるべきではなかったこの危険なことを、もはやできないのはなぜですか。
その質問への回答はほとんど無関係です(ただし、この機能を要求するこれらのConnectアイテムでいくつかのMicrosoftコメントを確認できます:#294193および#252226)。完全を期すために、私の概要は次のとおりです。IDプロパティを削除する機能は、最初からシステムテーブルを操作する機能を持っていることの意図しない副作用でした。これは、多くの場合に使用されることを意図したものではなく、たいていは非常に悪い結果を伴うため、削除されました。これは、文書化されておらず、サポートされていないシステムテーブルハックでした。システムテーブルのデータを変更する機能は削除されませんでした。MicrosoftがID列である列からハッキングすることを望まなくなったためです。システムテーブルの改ざんは非常に危険であるため、削除されました。IDENTITYプロパティ自体を削除することは、特に対象を絞った機能の削除ではなく、可能であった古代の時代にさえ、このアプローチを完全に信頼することはできなかったでしょう。
とはいえ、代わりにこの質問に答えてみませんか?
最小限のダウンタイムまたはダウンタイムなしで列のIDENTITYプロパティを削除するにはどうすればよいですか?
これは、Connectの回避策#252226でALTER TABLE ... SWITCH
自分のPaul Whiteから最初に学んだ技術を使用して、簡単に行うことができます。この単純なテーブルを前提とした簡単な例:
CREATE TABLE dbo.Original
(
ID INT IDENTITY(1,1) PRIMARY KEY,
name SYSNAME
);
GO
INSERT dbo.Original(name) VALUES(N'foo'),(N'bar');
GO
SELECT * FROM dbo.Original;
GO
結果:
ID name
-- ----
1 foo
2 bar
次に、シャドーテーブルを作成して、それに切り替え、古いテーブルを削除し、新しいテーブルの名前を変更して、通常のアクティビティを再開します。
CREATE TABLE dbo.New
(
ID INT PRIMARY KEY,
name SYSNAME
);
GO
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
ALTER TABLE dbo.Original SWITCH TO dbo.New;
DROP TABLE dbo.Original;
EXEC sys.sp_rename N'dbo.New', N'Original', 'OBJECT';
COMMIT TRANSACTION;
GO
INSERT dbo.Original(ID,name) VALUES(3,N'splunge');
UPDATE dbo.Original SET ID = 6 WHERE ID = 1;
GO
SELECT * FROM dbo.Original;
GO
結果:
ID name
-- -------
2 bar
3 splunge
6 foo
次にクリーンアップします。
DROP TABLE dbo.Original;
これはメタデータ操作のみであり、データの移動はありません。メタデータが更新されている間、他のユーザーのみがブロックされます。しかし、確かに、これは非常に単純な例です。外部キーがある場合、またはレプリケーション、変更データキャプチャ、変更追跡などの他の機能を使用している場合は、この変更を行う前にそれらの一部を無効にするか削除する必要がある場合があります(すべての組み合わせをテストしたわけではありません)。特に外部キーについては、すべての(または選択した)外部キー制約を削除して再作成するスクリプトを生成する方法を示すこのヒントを参照してください。
さらに、SQL Serverがこの列にデータを入力しないようにアプリケーションコードを更新し、列の順序または指定する必要がある列に依存する可能性のある挿入または選択ステートメントを確認する必要があります。一般的に、このテーブルについて言及する場合は、コードベース全体をgrepします。
これを処理する別の方法については、Itzik Ben-Ganによるこのスクリプト(出典:この古代の記事)も参照してください。ただし、ここではデータの移動が伴うため、「ダウンタイムなし」または「最小限のダウンタイム」要件は提供されません。