Ich habe eine MS SQL 2005-Datenbank mit einer Tabelle Test
mit der Spalte ID
. ID
ist eine Identitätsspalte.
Ich habe Zeilen in dieser Tabelle und alle haben ihren entsprechenden automatisch inkrementierten ID-Wert.
Jetzt möchte ich jede ID in dieser Tabelle wie folgt ändern:
ID = ID + 1
Aber wenn ich das tue, bekomme ich eine Fehlermeldung:
Identitätsspalte 'ID' kann nicht aktualisiert werden.
Ich habe es versucht:
ALTER TABLE Test NOCHECK CONSTRAINT ALL
set identity_insert ID ON
Aber das löst das Problem nicht.
Ich muss Identität für diese Spalte festlegen, aber ich muss von Zeit zu Zeit auch Werte ändern. Meine Frage ist also, wie man diese Aufgabe erfüllt.
Du musst
set identity_insert YourTable ON
Löschen Sie dann Ihre Zeile und fügen Sie sie mit einer anderen Identität erneut ein.
Vergessen Sie nach dem Einfügen nicht, identity_insert zu deaktivieren
set identity_insert YourTable OFF
IDENTITY
Spaltenwerte sind unveränderlich.
Es ist jedoch möglich, die Tabellenmetadaten zu wechseln, um die Eigenschaft IDENTITY
zu entfernen, die Aktualisierung durchzuführen und dann zurückzuschalten.
Angenommen, die folgende Struktur
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'
Dann kannst du machen
/*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*/
In SQL Server 2012 ist es möglich, eine automatisch inkrementierende Spalte zu haben, die auch mit SEQUENCES
einfacher aktualisiert werden kann.
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
Ändern Sie über die Benutzeroberfläche in SQL Server 2005 Manager die Spalte, und entfernen Sie die Eigenschaft für die automatische Nummerierung (Identität) der Spalte (wählen Sie die Tabelle aus, indem Sie mit der rechten Maustaste darauf klicken, und wählen Sie "Entwurf" aus).
Führen Sie dann Ihre Abfrage aus:
UPDATE table SET Id = Id + 1
Fügen Sie anschließend die Eigenschaft für die automatische Nummerierung wieder der Spalte hinzu.
Erstens funktioniert das Aktivieren oder Deaktivieren von IDENTITY_INSERT nicht für das, was Sie benötigen (es wird zum Einfügen neuer Werte verwendet, z. B. zum Schließen von Lücken).
Wenn Sie den Vorgang über die GUI ausführen, wird lediglich eine temporäre Tabelle erstellt, alle Daten werden in eine neue Tabelle ohne Identitätsfeld kopiert und die Tabelle wird umbenannt.
Dies kann mithilfe einer temporären Tabelle erfolgen.
Angenommen, Ihre test
-Tabelle enthält zwei zusätzliche Spalten (column2
Und column3
) Und es gibt zwei Tabellen mit Fremdschlüsseln, die auf test
mit dem Namen foreign_table1
und foreign_table2
(weil echte Probleme niemals einfach sind).
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;
Das ist es.
DBCC CHECKIDENT ('databasename.dbo.orders', RESEED, 999) Mit diesem Befehl können Sie jede Identitätsspaltennummer ändern. Sie können diese Feldnummer auch von jeder gewünschten Nummer aus starten 1000 (999 + 1) hoffen, dass es genug wäre ... viel Glück
Wenn es sich bei der Spalte nicht um eine PK handelt, können Sie in der Tabelle immer eine NEUE Spalte mit den inkrementierten Zahlen erstellen, das Original löschen und die neue Spalte in die alte ändern.
ich bin gespannt, warum Sie dies möglicherweise tun müssen. Das meiste, was ich jemals mit Identity-Spalten zu tun hatte, war das Auffüllen von Zahlen, und ich habe gerade DBCC CHECKIDENT (Tabellenname, RESEED, neue nächste Nummer) verwendet.
viel Glück!
Die Änderung der Identität kann in Abhängigkeit von einer Reihe von Faktoren fehlschlagen, die sich hauptsächlich auf die mit der ID-Spalte verknüpften Objekte/Beziehungen beziehen. Es scheint, als ob DB-Design hier genauso problematisch ist, wie IDs sich selten oder nie ändern sollten (ich bin mir sicher, dass Sie Ihre Gründe haben und die Änderungen kaskadieren). Wenn Sie die IDs wirklich von Zeit zu Zeit ändern müssen, würde ich vorschlagen, entweder eine neue Dummy-ID-Spalte zu erstellen, die nicht der Primärschlüssel/die Autonummer ist, die Sie selbst verwalten und aus den aktuellen Werten generieren können. Alternativ wäre die Idee von Chrisotphers mein anderer Vorschlag, wenn Sie Probleme haben, das Einfügen von Identität zuzulassen.
Viel Glück
PS: Es schlägt nicht fehl, weil die Reihenfolge, in der es ausgeführt wird, versucht, einen Wert in der Liste auf ein Element zu aktualisieren, das bereits in der Liste der IDs vorhanden ist. Wenn Sie sich an Strohhalme klammern, addieren Sie vielleicht die Anzahl der Reihen + 1. Wenn dies funktioniert, subtrahieren Sie die Anzahl der Reihen: -S
Speichern Sie zuerst alle IDs und ändern Sie sie programmgesteuert auf die Werte, die Sie nicht möchten. Entfernen Sie sie dann aus der Datenbank und fügen Sie sie dann mit einer ähnlichen Methode erneut ein:
use [Name.Database]
go
set identity_insert [Test] ON
insert into [dbo].[Test]
([Id])
VALUES
(2)
set identity_insert [Test] OFF
Für Masseneinsatzgebrauch:
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
Beispieldaten aus file.csv:
2;
3;
4;
5;
6;
Wenn Sie nicht identity_insert
to off erhalten Sie folgende Fehlermeldung:
Es kann kein expliziter Wert für die Identitätsspalte in die Tabelle 'Test' eingefügt werden, wenn IDENTITY_INSERT auf OFF gesetzt ist.
Wenn Sie die IDs gelegentlich ändern müssen, ist es wahrscheinlich am besten, keine Identitätsspalte zu verwenden. In der Vergangenheit haben wir die automatische Nummerierung von Feldern manuell mithilfe einer Tabelle "Zähler" implementiert, die die nächste ID für jede Tabelle protokolliert. IIRC wir haben dies getan, weil Identitätsspalten Datenbankbeschädigung in SQL2000 verursachten, aber in der Lage war, IDs zu ändern, war gelegentlich zum Testen nützlich.
Sie können neue Zeilen mit geänderten Werten einfügen und dann alte Zeilen löschen. Im folgenden Beispiel wird die ID so geändert, dass sie mit dem Fremdschlüssel übereinstimmt 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
Ich habe einen guten Artikel gesehen, der mir im letzten Moment geholfen hat. Ich habe versucht, ein paar Zeilen in eine Tabelle mit einer Identitätsspalte einzufügen, habe es aber falsch gemacht und muss zurück löschen. Sobald ich die Zeilen gelöscht habe, wurde meine Identitätsspalte geändert. Ich habe versucht, eine Möglichkeit zu finden, die eingefügte Spalte zu aktualisieren, aber - kein Glück. Also, während der Suche auf Google einen Link gefunden ..
Sehr nette Frage, zuerst müssen wir auf der IDENTITY_INSERT für die bestimmte Tabelle, nach dem Ausführen der Einfügeabfrage (muss den Spaltennamen angeben).
Hinweis: Vergessen Sie nicht, nach dem Bearbeiten der Identitätsspalte auszuschalten die IDENTITY_INSERT. Andernfalls können Sie die Identitätsspalte für keine andere Tabelle bearbeiten.
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