it-swarm.com.de

Wie ändert man Identitätsspaltenwerte programmgesteuert?

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.

159

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
217
A-K

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
40
Martin Smith

Ä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.

26
Michael Pryor

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.

18
Miles D

Dies kann mithilfe einer temporären Tabelle erfolgen.

Die Idee

  • einschränkungen deaktivieren (falls Ihre ID von einem Fremdschlüssel referenziert wird)
  • erstellen Sie eine temporäre Tabelle mit der neuen ID
  • löschen Sie den Tabelleninhalt
  • kopieren Sie die Daten aus der kopierten Tabelle in Ihre Originaltabelle zurück
  • zuvor deaktivierte Einschränkungen aktivieren

SQL-Abfragen

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

6
Roxana

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!

4

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

1
Tanner

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.

1
Ogglas

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.

1
Robin Bennett

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
1
Tomas Kubes

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 ..

  1. Löschte die falsch eingefügten Spalten
  2. Verwenden Sie Force Insert mit Identität ein/aus (unten erklärt)

http://beyondrelational.com/modules/2/blogs/28/posts/10337/sql-server-how-do-i-insert-an-explicit-value-into-an-identity-column- Wie-aktualisiere-ich-den-Wert-einer.aspx

0
Balu

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

0
Asith Raj