160

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

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

ここで、このテーブルのすべての ID を次のように変更したいと思います。

ID = ID + 1

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

ID 列 'ID' を更新できません。

私はこれを試しました:

    ALTER TABLE Test NOCHECK CONSTRAINT ALL 
    set identity_insert ID ON

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

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

4

13 に答える 13

226

必要がある

set identity_insert YourTable ON

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

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

set identity_insert YourTable OFF
于 2009-07-27T13:15:27.147 に答える
39

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
于 2013-06-22T10:16:44.463 に答える
26

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

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

UPDATE table SET Id = Id + 1

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

于 2009-04-15T12:48:01.927 に答える
18

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

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

于 2009-04-15T13:32:50.743 に答える
9

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

アイデア

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

SQLクエリ

testテーブルに2つの追加の列(column2と)があり、andcolumn3を参照する外部キーを持つテーブルが2つあるとします(実際の問​​題は決して単純ではないため)。testforeign_table1foreign_table2

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;

それでおしまい。

于 2012-08-30T15:09:19.097 に答える
6

DBCC CHECKIDENT ( 'databasename.dbo.orders',RESEED, 999) このコマンドで任意の ID 列番号を変更できます。また、必要なすべての番号からそのフィールド番号を開始することもできます。たとえば、私のコマンドでは、 1000 (999+1) これで十分だと思います...頑張ってください

于 2012-04-11T20:18:55.117 に答える
1

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

幸運を

PS実行中の順番が、リスト内の値をIDのリストにすでに存在するアイテムに更新しようとしているため、失敗していませんか?ストローをつかんで、おそらく行数+1を加算し、それが機能する場合は行数を減算します:-S

于 2009-04-15T13:10:56.087 に答える
1

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

于 2009-07-27T10:18:12.513 に答える
1

値が変更された新しい行を挿入してから、古い行を削除できます。次の例では、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
于 2015-02-05T21:01:02.930 に答える
1

最初にすべての 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しないと、次のエラーが発生します。

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

于 2016-08-08T13:34:46.127 に答える
0

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

  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-value-of-an.aspx

于 2012-09-17T23:41:06.977 に答える
0

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

注: ID 列を編集したら、IDENTITY_INSERTをオフにすることを忘れないでください。そうしないと、他のテーブルの 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

于 2016-07-27T10:01:32.153 に答える