Wie kann ich IDENTITY_INSERT mit SQL Server 2008 ein- und ausschalten?


461

Warum erhalte ich beim Einfügen einen Fehler, wenn IDENTITY_INSERTAUS eingestellt ist?

Wie schalte ich es in SQL Server 2008 richtig ein? Wird SQL Server Management Studio verwendet?

Ich habe diese Abfrage ausgeführt:

SET IDENTITY_INSERT Database. dbo. Baskets ON

Dann bekam ich die Nachricht in der Konsole zurück, dass die Befehle erfolgreich ausgeführt wurden. Wenn ich die Anwendung jedoch ausführe, wird immer noch der folgende Fehler angezeigt:

Cannot insert explicit value for identity column in table 'Baskets' when 
IDENTITY_INSERT is set to OFF.

Bitte erweitern Sie diese Frage, damit wir verstehen, was Sie versuchen. Welche Anweisung wird ausgeführt, wenn dieser Fehler auftritt, und wie lautet der tatsächliche Text der Fehlermeldung?
Matt Gibson

Auch wenn Sie eine andere Frage gestellt, sollten Sie eine Antwort hier akzeptieren: Wir beantwortet , was Sie gefragt .
Gbn

8
Ich habe einen Schrecken vor der Idee, dass jemand versucht, Identitätswerte aus einer Anwendung zu senden. Dies sollten Sie nur mit der seltenen Datenmigration tun. Wenn Sie dies regelmäßig genug tun, um es von einer Anwendung aus auszuführen, müssen Sie wahrscheinlich Ihr Tabellendesign überdenken.
HLGEM

Ich verwende dies in meiner SQL-Skriptsicherung. Während der Wiederherstellung kann ich die Daten in eine automatisch inkrementierte Tabelle mit Originalwerten laden. Mit der Skriptsicherung konnte ich die SQL-Datenbank herunterstufen. Durch die Realisierung von Scripted Backup durch Management Studio wird das Skript entladen, wenn Binärdaten in einem Textfeld gespeichert werden.
Jettero

Antworten:


771

Über SQL gemäß MSDN

SET IDENTITY_INSERT sometableWithIdentity ON

INSERT INTO sometableWithIdentity 
    (IdentityColumn, col2, col3, ...)
VALUES 
    (AnIdentityValue, col2value, col3value, ...)

SET IDENTITY_INSERT sometableWithIdentity OFF

Die vollständige Fehlermeldung sagt Ihnen genau, was falsch ist ...

Ein expliziter Wert für die Identitätsspalte kann nicht in die Tabelle 'sometableWithIdentity' eingefügt werden, wenn IDENTITY_INSERT auf OFF gesetzt ist.


@Beginner: du bist aber, daher der Fehler. Woher sollen wir wissen, dass Sie keine Werte einfügen möchten? Wir haben nur eine Fehlermeldung
gbn

3
Fehler ist von meiner App, wenn ich DB.SaveChanges () mache;
Anfänger

5
Nein, hören Sie einfach auf, einen Wert für die Identitätsspalte zu senden. Oder legen Sie fest, ob Sie in Ihrer App einen Wert senden möchten. Warum sollte dann eine Spalte mit der Identitätseigenschaft festgelegt werden, um Werte zu generieren? Wir können uns nicht für Sie entscheiden
gbn

22
@Beginner: Die Einstellung ist nur in der aktuellen Sitzung anwendbar (niemand hat in dieser Frage darauf hingewiesen), sodass Ihre Anwendung sie aktivieren müsste, damit die Anwendung solche Einfügungen ausführen kann (und es ist wahrscheinlich am besten, sie sofort zu aktivieren es wieder aus, wenn solche Einfügungen abgeschlossen sind, wie gbn Shows). Wie Sie einen Wert in die Identitätsspalte einfügen, ohne es zu merken, ist nicht klar, aber möglicherweise würden ältere Versionen von SQL Server ihn implizit in alle Spalten aufnehmen, wenn keine expliziten Einfügungsspalten angegeben werden (?), Wie Ismael zu vermuten scheint.
Rob Parker

2
@Rob, ich denke, Sie haben einen Punkt und ich persönlich versage die Codeüberprüfung für jeden Code, der nicht eingefügt wird, ohne Spalten anzugeben. Abgesehen von der Zeit, die für einen Fehler verschwendet wird, ist dies eine riskante Vorgehensweise, und Sie können ernsthafte Probleme mit der Datenintegrität haben, wenn die Spaltendaten nicht richtig übereinstimmen.
HLGEM

59

Ich hatte ein Problem, bei dem ich es auch nach dem Setzen von IDENTITY_INSERT ON nicht einfügen konnte.

Das Problem war, dass ich die Spaltennamen nicht angegeben habe und es aus irgendeinem Grund nicht mochte.

INSERT INTO tbl Values(vals)

Machen Sie also im Grunde die vollständigen INSERT INTO tbl (cols) -Werte (vals)


6
Stellen Sie keine Fragen im Antwortbereich.
Duk

4
Dies war genau das, was es von mir wollte, um die Spaltenliste anzugeben (beide Spalten auf der Tabelle, bla)
Maslow

36

Importieren: Sie müssen Spalten in die INSERTAnweisung schreiben

INSERT INTO TABLE
SELECT * FROM    

Das ist nicht richtig.

Insert into Table(Field1,...)
Select (Field1,...) from TABLE

Ist richtig


2
Vielen Dank, das war sehr hilfreich
José Romero

1
Wenn Sie in beiden Tabellen identische Spalten haben, können Sie darauf verzichten, die Spalten in der Auswahl (Feld1 ..) wie folgt aufzulisten .... In Tabelle einfügen (Feld1, ...) Wählen Sie * aus TABELLE ... und wenn Sie haben Identitätsfeld, das zuerst eingefügt werden soll ** SET IDENTITY_INSERT Tabellenname ON
user3590235

@ user3590235 Dies ist eine riskante Annahme, dass die Spaltenliste identisch ist. Tun Sie dies außerhalb manueller Benutzerabfragen niemals, da ich garantiere, dass Sie PROD eines Tages unterbrechen werden, wenn jemand anderes die Tabellendefinition ändert, ohne Ihre Referenz zu aktualisieren.
Elaskanator

5

Ich weiß, dass dies ein älterer Thread ist, aber ich bin gerade darauf gestoßen. Wenn der Benutzer nach einer anderen Sitzung versucht, Einfügungen in die Spalte Identität auszuführen, setzen Sie IDENTITY_INSERT ON, um den obigen Fehler zu erhalten.

Das Festlegen des Identity Insert-Werts und der nachfolgenden Insert DML-Befehle muss von derselben Sitzung ausgeführt werden.

Hier hat @Beginner Identity Insert separat aktiviert und dann die Einfügungen aus seiner Anwendung ausgeführt. Deshalb hat er den folgenden Fehler erhalten:

Cannot insert explicit value for identity column in table 'Baskets' when 
IDENTITY_INSERT is set to OFF.

0

Dies ist wahrscheinlich, wenn Sie ein PRIMARY KEY-Feld haben und einen Wert einfügen, der dupliziert wird, oder wenn das INSERT_IDENTITY-Flag aktiviert ist


0

Es erscheint notwendig, SET IDENTITY_INSERT Database.dbo.Baskets ON;vor jedem SQL- INSERTSendebatch ein zu setzen .

Sie können mehrere INSERT ... VALUES ...Befehle senden, die SET IDENTITY_INSERT ... ON;am Anfang mit einer Zeichenfolge gestartet wurden . Setzen Sie einfach kein Batch-Separator dazwischen.

Ich weiß nicht, warum das SET IDENTITY_INSERT ... ONnach dem Sendeblock nicht mehr funktioniert (zum Beispiel .ExecuteNonQuery()in C #). Ich musste SET IDENTITY_INSERT ... ON;am Anfang der nächsten SQL-Befehlszeichenfolge erneut setzen.


Vielleicht beantwortet dies Ihre Frage: stackoverflow.com/questions/5791941/…
Demetris Leptos

-1

Sie müssen den Befehl 'go' hinzufügen, nachdem Sie die Identitätseinfügung festgelegt haben. Beispiel:

SET IDENTITY_INSERT sometableWithIdentity ON
go

INSERT sometableWithIdentity (IdentityColumn, col2, col3, ...)
VALUES (AnIdentityValue, col2value, col3value, ...)

SET IDENTITY_INSERT sometableWithIdentity OFF
go

5
Diese Frage ist vier Jahre alt und hat eine akzeptierte Antwort. Ihre Antwort dupliziert die akzeptierte Antwort
Ghost

13
Nun, keine exakte Vervielfältigung - er hat die "go" -Befehle aufgenommen ...;)
RoastBeast
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.