web-dev-qa-db-ja.com

ID列の値をプログラムで変更する方法は?

Testを持つテーブルIDを持つMS SQL 2005データベースがあります。 IDはID列です。

このテーブルには行があり、すべての行に対応するIDの自動インクリメント値があります。

次に、この表のすべてのIDを次のように変更します。

ID = ID + 1

しかし、これを行うとエラーが発生します:

ID列「ID」を更新できません。

私はこれを試しました:

    ALTER TABLE Test NOCHECK CONSTRAINT ALL 
    set identity_insert ID ON

しかし、これは問題を解決しません。

この列にIDを設定する必要がありますが、値も時々変更する必要があります。私の質問は、このタスクをどのように達成するかです。

158

必要がある

set identity_insert YourTable ON

次に、行を削除し、別のIDで再挿入します。

挿入が完了したら、identity_insertをオフにすることを忘れないでください

set identity_insert YourTable OFF
217
A-K

IDENTITY列の値は不変です。

ただし、テーブルメタデータを切り替えてIDENTITYプロパティを削除し、更新を行ってから元に戻すことは可能です。

次の構造を想定

CREATE TABLE Test
(
ID INT IDENTITY(1,1) PRIMARY KEY,
X VARCHAR(10)
)

INSERT INTO Test 
OUTPUT INSERTED.*
SELECT 'Foo' UNION ALL
SELECT 'Bar' UNION ALL
SELECT 'Baz'

その後、あなたはできる

/*Define table with same structure but no IDENTITY*/
CREATE TABLE Temp
(
ID INT PRIMARY KEY,
X VARCHAR(10)
)

/*Switch table metadata to new structure*/
ALTER TABLE Test SWITCH TO Temp;

/*Do the update*/
UPDATE Temp SET ID = ID + 1;

/*Switch table metadata back*/
ALTER TABLE Temp SWITCH TO Test;

/*ID values have been updated*/
SELECT *
FROM Test

/*Safety check in case error in preceding step*/
IF NOT EXISTS(SELECT * FROM Temp)
    DROP TABLE Temp /*Drop obsolete table*/

SQL Server 2012では、SEQUENCESを使用してより簡単に更新できる自動インクリメント列を使用できます。

CREATE SEQUENCE Seq
    AS INT
    START WITH 1
    INCREMENT BY 1

CREATE TABLE Test2
(
ID INT DEFAULT NEXT VALUE FOR Seq NOT NULL PRIMARY KEY,
X VARCHAR(10)
)

INSERT INTO Test2(X)
SELECT 'Foo' UNION ALL
SELECT 'Bar' UNION ALL
SELECT 'Baz'

UPDATE Test2 SET ID+=1
40
Martin Smith

SQL Server 2005マネージャーのUIを使用して、列を変更し、列のautonumber(identity)プロパティを削除します(右クリックしてテーブルを選択し、[デザイン]を選択します)。

次に、クエリを実行します。

UPDATE table SET Id = Id + 1

次に、autonumberプロパティを列に追加します。

26
Michael Pryor

まず、IDENTITY_INSERTのオンまたはオフの設定は、必要なものには機能しません(ギャップのプラグインなど、新しい値の挿入に使用されます)。

GUIを介して操作を行うと、一時テーブルが作成され、IDフィールドのない新しいテーブルにすべてのデータがコピーされ、テーブルの名前が変更されます。

18
Miles D

これは、一時テーブルを使用して実行できます。

アイデア

  • 制約を無効にします(IDが外部キーによって参照されている場合)
  • 新しいIDで一時テーブルを作成します
  • テーブルの内容を削除する
  • コピーしたテーブルから元のテーブルにデータをコピーします
  • 以前に無効にされた制約を有効にする

SQLクエリ

testテーブルに2つの追加列(column2およびcolumn3)があり、foreign_table1およびforeign_table2と呼ばれるtestを参照する外部キーを持つ2つのテーブルがあるとしましょう(実際の問​​題は決して単純ではないため)。

alter table test nocheck constraint all;
alter table foreign_table1 nocheck constraint all;
alter table foreign_table2 nocheck constraint all;
set identity_insert test on;

select id + 1 as id, column2, column3 into test_copy from test v;
delete from test;
insert into test(id, column2, column3)
select id, column2, column3 from test_copy

alter table test check constraint all;
alter table foreign_table1 check constraint all;
alter table foreign_table2 check constraint all;
set identity_insert test off;
drop table test_copy;

それでおしまい。

DBCC CHECKIDENT( 'databasename.dbo.orders'、RESEED、999)このコマンドで任意のID列番号を変更できます。また、必要なすべての番号からそのフィールド番号を開始することもできます。 1000(999 + 1)で十分だと思います...幸運を祈ります

6
Roxana

列がPKでない場合は、常にテーブルに新しい列を作成し、番号を増やして元の列を削除してから、新しい列を変更して古い列にすることができます。

なぜあなたがこれを行う必要があるのか​​興味があります...私がこれまでIdentity列でふさぐ必要があったほとんどは、数字を埋め戻すことであり、DBCC CHECKIDENT(tablename、RESEED、newnextnumber)

がんばろう!

4

IDの変更は、主にid列にリンクされたオブジェクト/関係を中心に、いくつかの要因によって失敗する場合があります。ここでは、IDが変更されたとしてもIDはめったにないので、dbの設計が問題になっているようです(理由があり、変更が失敗していると確信しています)。 IDを時々変更する必要がある場合は、自分で管理して現在の値から生成できるプライマリキー/オートナンバーではない新しいダミーID列を作成することをお勧めします。あるいは、ID挿入の許可に問題がある場合、上記のChrisotphersのアイデアは私のもう1つの提案です。

がんばろう

PSそれはそれが実行されているシーケンシャル順序がIDのリストに既に存在するアイテムにリストの値を更新しようとしているので失敗していませんか?ストローを握って、おそらく行数+1を追加し、それが機能する場合は行数を減算します:-S

1
Tanner

最初にすべてのIDを保存し、それらをプログラムで必要でない値に変更してから、データベースから削除してから、同様の方法で再度挿入します。

use [Name.Database]
go
set identity_insert [Test] ON
insert into [dbo].[Test]
           ([Id])
     VALUES
           (2)
set identity_insert [Test] OFF

一括挿入の場合:

use [Name.Database]
go
set identity_insert [Test] ON
BULK INSERT [Test]
FROM 'C:\Users\Oscar\file.csv'
WITH (FIELDTERMINATOR = ';',
      ROWTERMINATOR = '\n',
      KEEPIDENTITY)
set identity_insert [Test] OFF

File.csvからのサンプルデータ:

2;
3;
4;
5;
6;

identity_insertをoffに設定しないと、次のエラーが表示されます。

IDENTITY_INSERTがOFFに設定されている場合、テーブル 'Test'のID列に明示的な値を挿入できません。

1
Ogglas

IDを時々変更する必要がある場合は、おそらくID列を使用しないことをお勧めします。過去に、各テーブルの次のIDを追跡する「カウンタ」テーブルを使用して、自動番号フィールドを手動で実装しました。これは、ID2000がSQL2000でデータベースの破損を引き起こしていましたが、IDを変更できることがテストに役立つことがあるためです。

1
Robin Bennett

値を変更した新しい行を挿入してから、古い行を削除できます。次の例では、IDを外部キーと同じに変更しますPersonId

SET IDENTITY_INSERT [PersonApiLogin] ON

INSERT INTO [PersonApiLogin](
       [Id]
      ,[PersonId]
      ,[ApiId]
      ,[Hash]
      ,[Password]
      ,[SoftwareKey]
      ,[LoggedIn]
      ,[LastAccess])
SELECT [PersonId]
      ,[PersonId]
      ,[ApiId]
      ,[Hash]
      ,[Password]
      ,[SoftwareKey]
      ,[LoggedIn]
      ,[LastAccess]
FROM [db304].[dbo].[PersonApiLogin]
GO

DELETE FROM [PersonApiLogin]
WHERE [PersonId] <> ID
GO
SET IDENTITY_INSERT [PersonApiLogin] OFF
GO
1
Tomas Kubes

私は最後の瞬間に私を助けた良い記事を見ました..私はID列を持つテーブルにいくつかの行を挿入しようとしましたが、間違ってそれを削除しなければなりませんでした。行を削除すると、ID列が変更されました。挿入された列を更新する方法を見つけようとしましたが、運がありませんでした。だから、グーグルで検索中にリンクが見つかりました..

  1. 誤って挿入された列を削除しました
  2. IDのオン/オフを使用した強制挿入の使用(以下で説明)

http://beyondrelational.com/modules/2/blogs/28/posts/10337/sql-server-how-do-i-insert-an-explicit-value-into-an-identity-column- how-do-i-update-the-of-an.aspx

0
Balu

非常に素晴らしい質問です。まず、特定のテーブルのIDENTITY_INSERTをonする必要があります。その後、挿入クエリを実行します(列名を指定する必要があります)。

注:ID列を編集した後、IDENTITY_INSERTをoffすることを忘れないでください。完了していない場合、他のテーブルのID列を編集できません。

SET IDENTITY_INSERT Emp_tb_gb_Menu ON
     INSERT Emp_tb_gb_Menu(MenuID) VALUES (68)
SET IDENTITY_INSERT Emp_tb_gb_Menu OFF

http://allinworld99.blogspot.com/2016/07/how-to-edit-identity-field-in-sql.html

0
Asith Raj