テーブルがありますtable1
SQL Server 2008では、レコードが含まれています。
主キーが必要ですtable1_Sno
列は自動インクリメント列になります。これは、データ転送やテーブルのクローンなしで実行できますか?
ALTER TABLEを使用して自動インクリメント列を追加できることは知っていますが、主キーである既存の列にAUTO_INCREMENTオプションを単純に追加できますか?
IDENTITY
プロパティの変更は、実際にはメタデータのみの変更です。ただし、メタデータを直接更新するには、インスタンスをシングルユーザーモードで起動し、sys.syscolpars
および文書化されていない/サポートされていないものであり、私が推奨するものや追加の詳細を提供するものではありません。
SQL Server 2012+でこの答えに出くわした人にとって、自動インクリメント列のこの結果を達成する最も簡単な方法は、SEQUENCE
オブジェクトを作成し、next value for seq
を列のデフォルトとして。
または、以前のバージョン(2005年以降)の this connect item に記載されている回避策は、ALTER TABLE...SWITCH
。また、MSDN here でブログを書いています。これを達成するためのコードはそれほど単純ではなく、制限があります-変更されるテーブルは外部キー制約の対象になり得ないなど。
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
この戦略では、行を物理的に2回コピーします。コピーするテーブルが非常に大きい場合、時間がかかることがあります。
データを保存し、自動インクリメントとプライマリキーを使用してテーブルを削除して再構築し、データを再度読み込むことができます。
例で説明します。
ステップ1、テーブルfoobarを作成します(主キーまたは自動インクリメントなし):
CREATE TABLE foobar(
id int NOT NULL,
name nchar(100) NOT NULL,
)
ステップ2、いくつかの行を挿入
insert into foobar values(1, 'one');
insert into foobar values(2, 'two');
insert into foobar values(3, 'three');
ステップ3、foobarデータを一時テーブルにコピーします:
select * into temp_foobar from foobar
ステップ4、foobarテーブルの削除:
drop table foobar;
ステップ5、主キーと自動インクリメントのプロパティを使用してテーブルを再作成します:
CREATE TABLE foobar(
id int primary key IDENTITY(1, 1) NOT NULL,
name nchar(100) NOT NULL,
)
ステップ6、一時テーブルからデータをfoobarに挿入する
SET IDENTITY_INSERT temp_foobar ON
INSERT into foobar (id, name) select id, name from temp_foobar;
手順7、一時テーブルを削除し、動作するかどうかを確認します:
drop table temp_foobar;
select * from foobar;
これを取得する必要があります。foobarテーブルを調べると、id列は1の自動インクリメントであり、idは主キーです。
1 one
2 two
3 three
デザイナーを介してこれを実行する場合は、既存の列をヌル可能に変更するときに「 」「変更の保存は許可されていません」の指示に従って実行できます
はい、できます。 [ツール]> [デザイナ]> [テーブルとデザイナ]に移動し、「テーブルの再作成を妨げる変更の保存を禁止する」のチェックを外します。
新しい列を追加したくなく、現在のint列が一意であることを保証できる場合は、すべてのデータを一時テーブルに選択し、テーブルを削除して、指定されたIDENTITY列で再作成できます。次に、SET IDENTITY INSERT ON
一時テーブル内のすべてのデータを新しいテーブルに挿入できます。
いいえ、データのある既存の列に自動増分オプションを追加することはできません。あなたが言及したオプションが最適だと思います。
ご覧ください here 。
以下のスクリプトは良い解決策になる可能性があります。また、大規模なデータで作業しました。
NO_WAITを使用したALTER DATABASE WMlive SET RECOVERY SIMPLE
ALTER TABLE WMBOMTABLE DROP CONSTRAINT PK_WMBomTable
ALTER TABLE WMBOMTABLEドロップ列BOMID
ALTER TABLE WMBOMTABLE ADD BomID int IDENTITY(1、1)NOT NULL;
ALTER TABLE WMBOMTABLE ADD CONSTRAINT PK_WMBomTable PRIMARY KEY CLUSTERED(BomID);
ALTER DATABASE WMlive SET RECOVERY FULL WITH NO_WAIT