列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を設定する必要がありますが、値も時々変更する必要があります。私の質問は、このタスクをどのように達成するかです。
必要がある
set identity_insert YourTable ON
次に、行を削除し、別のIDで再挿入します。
挿入が完了したら、identity_insertをオフにすることを忘れないでください
set identity_insert YourTable OFF
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
SQL Server 2005マネージャーのUIを使用して、列を変更し、列のautonumber(identity)プロパティを削除します(右クリックしてテーブルを選択し、[デザイン]を選択します)。
次に、クエリを実行します。
UPDATE table SET Id = Id + 1
次に、autonumberプロパティを列に追加します。
まず、IDENTITY_INSERTのオンまたはオフの設定は、必要なものには機能しません(ギャップのプラグインなど、新しい値の挿入に使用されます)。
GUIを介して操作を行うと、一時テーブルが作成され、IDフィールドのない新しいテーブルにすべてのデータがコピーされ、テーブルの名前が変更されます。
これは、一時テーブルを使用して実行できます。
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)で十分だと思います...幸運を祈ります
列がPKでない場合は、常にテーブルに新しい列を作成し、番号を増やして元の列を削除してから、新しい列を変更して古い列にすることができます。
なぜあなたがこれを行う必要があるのか興味があります...私がこれまでIdentity列でふさぐ必要があったほとんどは、数字を埋め戻すことであり、DBCC CHECKIDENT(tablename、RESEED、newnextnumber)
がんばろう!
IDの変更は、主にid列にリンクされたオブジェクト/関係を中心に、いくつかの要因によって失敗する場合があります。ここでは、IDが変更されたとしてもIDはめったにないので、dbの設計が問題になっているようです(理由があり、変更が失敗していると確信しています)。 IDを時々変更する必要がある場合は、自分で管理して現在の値から生成できるプライマリキー/オートナンバーではない新しいダミーID列を作成することをお勧めします。あるいは、ID挿入の許可に問題がある場合、上記のChrisotphersのアイデアは私のもう1つの提案です。
がんばろう
PSそれはそれが実行されているシーケンシャル順序がIDのリストに既に存在するアイテムにリストの値を更新しようとしているので失敗していませんか?ストローを握って、おそらく行数+1を追加し、それが機能する場合は行数を減算します:-S
最初にすべての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列に明示的な値を挿入できません。
IDを時々変更する必要がある場合は、おそらくID列を使用しないことをお勧めします。過去に、各テーブルの次のIDを追跡する「カウンタ」テーブルを使用して、自動番号フィールドを手動で実装しました。これは、ID2000がSQL2000でデータベースの破損を引き起こしていましたが、IDを変更できることがテストに役立つことがあるためです。
値を変更した新しい行を挿入してから、古い行を削除できます。次の例では、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
私は最後の瞬間に私を助けた良い記事を見ました..私はID列を持つテーブルにいくつかの行を挿入しようとしましたが、間違ってそれを削除しなければなりませんでした。行を削除すると、ID列が変更されました。挿入された列を更新する方法を見つけようとしましたが、運がありませんでした。だから、グーグルで検索中にリンクが見つかりました..
非常に素晴らしい質問です。まず、特定のテーブルの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