SQL Serverは既存のテーブルに自動インクリメント主キーを追加します


253

タイトルとして、すでに150000レコードが入力されている既存のテーブルがあります。Id列(現在はnull)を追加しました。

クエリを実行してこの列に増分番号を入力し、主キーとして設定して自動増分をオンにできると仮定しています。これは続行する正しい方法ですか?もしそうなら、どうすれば最初の数字を埋めることができますか?

回答:


429

いいえ-逆の方法で行う必要があります。getgo asから直接追加しINT IDENTITYます。これを行うと、ID値が入力されます。

ALTER TABLE dbo.YourTable
   ADD ID INT IDENTITY

そしてそれを主キーにすることができます:

ALTER TABLE dbo.YourTable
   ADD CONSTRAINT PK_YourTable
   PRIMARY KEY(ID)

または、すべてを1つのステップで実行したい場合:

ALTER TABLE dbo.YourTable
   ADD ID INT IDENTITY
       CONSTRAINT PK_YourTable PRIMARY KEY CLUSTERED

2
これは本当に良い答えですが、開始整数を1から1000に変更するにはどうすればよいですか?1000からカウントを開始したいと思います。使用できると思われますALTER TABLE ORDER ALTER COLUMN ORDERNO RESTART WITH 1が、専門家に確認せずに試したくありませんでした:)参照。 pic.dhe.ibm.com/infocenter/iseries/v7r1m0/...
user1477388

3
私はこれを使用しましたが、うまくいったようですalter table attachments add ATTACHMENT_NUMBER int identity (1000, 1)
user1477388

1
@stom:何も指定しない場合は、seed = 1およびincrement = 1が使用されます-これは、とにかく最も頻繁に使用される設定です。このようなテーブルを作成した場合、問題なく機能します。ただし、SQLスクリプトでは常にシードと増分を明示的に指定することをお勧めします-特に大規模なサイトの場合。それはただ良い習慣です。
marc_s 2015年

1
@stom:まあ、それPRIMARY KEYが適切に行われていることを意味します。つまり、NOT NULL絶対に必要というわけではありません。しかし、私は明示的にすることを好むのでNOT NULL、絶対に明確にするために、常にそこにいます
marc_s

3
@ turbo88:を定義するPRIMARY KEYと、クラスター化インデックスが自動的に作成されます(明示的に指定しない限りNONCLUSTERED
marc_s

19

IDENTITYを「オンにする」ことはできません。これはテーブルの再構築です。

番号の順序を気にしない場合は、IDENTITYを使用してNOT NULL列を一度に追加します。15万行は多くありません。

番号の順序を維持する必要がある場合は、それに応じて番号を追加します。次に、SSMSテーブルデザイナを使用してIDENTITYプロパティを設定します。これにより、列のドロップ/追加/番号の保持/再シードを実行するスクリプトを生成できます。


5
OPはSQL Server 2008上にあるため、方法があります
Martin Smith、

インスタンス全体をシングルユーザーモードで起動する必要があるため、ほとんどの状況ではおそらく実行ALTER TABLE ... SWITCHできませんが、それがなくても実行できます。
マーティン・スミス、

11

この問題が発生しましたが、(さまざまな理由により)ID列を使用できませんでした。私はこれに落ち着きました:

DECLARE @id INT
SET @id = 0 
UPDATE table SET @id = id = @id + 1 

ここから借りる。


4

列がテーブルに既に存在し、それがnullの場合、次のコマンドで列を更新できます(id、tablename、tablekeyを置き換えます)。

UPDATE x
SET x.<Id> = x.New_Id
FROM (
  SELECT <Id>, ROW_NUMBER() OVER (ORDER BY <tablekey>) AS New_Id
  FROM <tablename>
  ) x

これで時間を節約できました!@gbnの回答の良い補遺。
クリステンウェイト

2

既存のテーブルに列を追加して識別すると、列に自動的に入力されるため、手動で入力する必要はありません。


2

設計者は、ID(1,1)を設定できます。tblを右クリック=>設計=>一部左(右クリック)=>プロパティ=> ID列で#columnを選択します。

プロパティ

idendtityカラム


1
これが良いアプローチかどうかについての情報はありますか?OPは、それが「続行する正しい方法」であるかどうかを尋ねています。より完全な答えは、彼らがアプローチの長所/短所を知るのに役立つでしょう。
jinglesthula 2017

実際、私はこのオプションを開発環境で使用しています。この変更を本番環境に渡す場合、IDフィールドが一部のストアプロシージャまたはトリガーで使用されている場合は、VIEW DEPENDENCYで検証する必要があります。
gustavo herrera 2017

2

テーブルが主キーまたはforiegenキーを使用して他のテーブルと関係がある場合、テーブルを変更することが不可能である可能性があります。そのため、テーブルを削除して再度作成する必要があります。
これらの問題を解決するには、データベースを右クリックしてスクリプトを生成する必要があり、詳細オプションセットでデータのタイプを設定して、スキーマとデータにスクリプトを作成します。その後、列を変更してこのスクリプトを使用し、クエリを実行してテーブルを識別および再生成します。
クエリは次のようになります。

USE [Db_YourDbName]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Drop TABLE [dbo].[Tbl_TourTable]

CREATE TABLE [dbo].[Tbl_TourTable](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](50) NULL,
    [Family] [nvarchar](150) NULL)  

GO

SET IDENTITY_INSERT [dbo].[Tbl_TourTable] ON 

INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')

SET IDENTITY_INSERT [dbo].[Tbl_TourTable] off 

0

ここにあなたが試すことができるアイデアがあります。元のテーブル-ID列なしtable1が新しいテーブルを作成-ID列とともにtable2を呼び出します。データをtable1からtable2にコピーします。ID列には、自動インクリメントされた数値が自動的に入力されます。

元のテーブルの名前をtable1からtable3に変更します。新しいテーブルの名前をtable2からtable1に変更します(元のテーブル)。問題がないことを確認して適切に機能したら、不要になったときにtable3をドロップします。


0

異なる名前と同じ列、主キーと外部キーの関連付けで新しいテーブルを作成し、これをコードのInsertステートメントでリンクします。例:EMPLOYEEの場合は、EMPLOYEESに置き換えます。

CREATE TABLE EMPLOYEES(

    EmpId        INT NOT NULL IDENTITY(1,1), 
    F_Name       VARCHAR(20) ,
    L_Name       VARCHAR(20) ,
    DOB          DATE ,
    DOJ          DATE ,
    PRIMARY KEY (EmpId),
    DeptId int FOREIGN KEY REFERENCES DEPARTMENT(DeptId),
    DesgId int FOREIGN KEY REFERENCES DESIGNATION(DesgId),
    AddId int FOREIGN KEY REFERENCES ADDRESS(AddId)   
) 

ただし、既存のEMPLOYEEテーブルを削除するか、要件に応じて調整する必要があります。


0

この回答は、最高得票数の回答への小さな追加であり、SQL Serverで機能します。質問で自動インクリメントの主キーが要求されました。現在の回答では主キーが追加されていますが、自動インクリメントのフラグは付けられていません。以下のスクリプトは、列の存在を確認し、自動インクリメントフラグを有効にして追加します。

IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'YourTable' AND COLUMN_NAME = 'PKColumnName')
BEGIN


ALTER TABLE dbo.YourTable
   ADD PKColumnName INT IDENTITY(1,1)

CONSTRAINT PK_YourTable PRIMARY KEY CLUSTERED

END

GO

0
ALTER TABLE table_name ADD temp_col INT IDENTITY(1,1) 
update 

5
説明できますか?
Muhammad Dyas Yaskur

1
このコードはOPの問題を解決する可能性がありますが、コードでOPの問題に対処する方法についての説明を含めることをお勧めします。このようにして、将来の訪問者はあなたの投稿から学び、それを自分のコードに適用することができます。SOはコーディングサービスではなく、知識のリソースです。また、質の高い、完全な回答が支持される可能性が高くなります。これらの機能は、すべての投稿が自己完結型であるという要件とともに、フォーラムとは異なるプラットフォームとしてのSOの強みの一部です。編集して情報を追加したり、ソースドキュメントで説明を補足したりできます。
ysf

-1

テーブルの変更/ **テーブルの名前を貼り付け** / add ID int IDENTITY(1,1)

/ **から削除し、見出しの名前を貼り付けます** / where id in

選択a.id FROM / **表の名前を貼り付けます/ LEFT OUTER JOINとして(SELECT MIN(id)as id FROM /表の名前を 貼り付け/ GROUP BY /列c1、c2 ...を貼り付けます** /

) as t1 
ON a.id = t1.id

WHERE t1.id IS NULL

表の変更/ **表の名前を貼り付け** / DROP COLUMN id


あなたの質問は何ですか?質問方法
アンキルツァー

1
マークダウンを使用してコード例を適切にフォーマットし、回答を編集します。
ビル・ケラー

-3

このようなものを試してください(最初にテストテーブルで):

your_database_nameを使用
行く
WHILE(SELECT COUNT(*)FROM your_table WHERE your_id_field IS NULL)> 0
ベギン
    行カウントを設定1
    UPDATE your_table SET your_id_field = MAX(your_id_field)+1
終わり
「すべて完了」の印刷

私はこれをまったくテストしていませんので、注意してください!


1
-1(IDENTITY列の追加に関する)質問に回答せず、とにかく機能しません。そこにUPDATE your_table SET your_id_field = MAX(your_id_field)+1こだわることはできませんMAXWHERE同じ行を繰り返し更新することを避けるための句はどこにありますか?
マーティン・スミス

-3

これはMariaDBで機能するため、SQL Serverでのみ機能することを期待できます。挿入したばかりのID列をドロップし、次の構文を使用します。

ALTER TABLE table_name ADD id INT PRIMARY KEY AUTO_INCREMENT;

別のテーブルは必要ありません。これは、単にid列を挿入し、それをプライマリインデックスにして、順次値を設定します。SQL Serverがこれを行わない場合、時間を無駄にしてしまったことをお詫びします。


-3

ALTER TABLE table_name ADD COLUMN ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT; これは役に立つかもしれません

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.