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

361

Ich habe den folgenden Fehler, wenn ich das folgende Skript ausführe. Worum geht es bei dem Fehler und wie kann er behoben werden?

Insert table(OperationID,OpDescription,FilterID)
values (20,'Hierachy Update',1)

Error:

Server: Nachricht 544, Ebene 16, Status 1, Zeile 1

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

Martin Clayton
quelle
2
@HimanshuAhuja Diese Frage (1334012) ist 10 Jahre alt, die Sie nur mit 1 verknüpft haben. Wenn überhaupt, dann ist die neuere ein Duplikat. Bei näherer Betrachtung werden Sie jedoch feststellen, dass sie sich unterscheiden (die neuere IDENTITY_INSERT gibt ON an). Bitte löschen Sie Ihre Flagge / Kommentar.
Jason
@jasie wird das tun, da ich mich nicht erinnere, wann ich diese Flagge gepostet hatte
Himanshu Ahuja

Antworten:

467

Sie fügen Werte ein, für OperationIddie es sich um eine Identitätsspalte handelt.

Sie können die Identitätseinfügung in der Tabelle wie folgt aktivieren, um Ihre eigenen Identitätswerte anzugeben.

SET IDENTITY_INSERT Table1 ON

INSERT INTO Table1
/*Note the column list is REQUIRED here, not optional*/
            (OperationID,
             OpDescription,
             FilterID)
VALUES      (20,
             'Hierachy Update',
             1)

SET IDENTITY_INSERT Table1 OFF 
pjp
quelle
14
+1 genau - die Option aktivieren explizite Einsätze zu ermöglichen , ON , dann einfügen, dann die Option aktivieren OFF wieder
marc_s
13
Wenn Sie der Identitätsspalte wirklich Ihren Wert hinzufügen möchten, ist dies Ihre Antwort. Andererseits hat jemand die Spalte so eingestellt, dass sie beim Einfügen von selbst erhöht wird. In diesem Fall verfolgt die Tabelle die nächste freie Nummer, und Sie müssen die OperationID nicht selbst generieren. Die neue ID kann mit SELECT SCOPE_IDENTITY () abgerufen werden.
Hakan Winther
15
Gefährliche Praxis, empfehlen Sie nicht, es ohne Vorbehalte zu verwenden, die erklären, warum es eine schlechte Idee ist. Sehr schlechte Antwort.
HLGEM
7
Gute Antwort, aber stellen Sie sicher, dass Sie wissen, was Sie tun. Für mich ist es nützlich, eine Datenbank mit Daten zu erstellen, in denen die Fremdschlüssel über verschiedene Tabellen hinweg übereinstimmen müssen
Berty
2
@UlyssesAlves: Diese Option kann nur für eine einzelne Tabelle datenbankweit aktiviert werden. Wenn Sie sie also für eine Tabelle aktiviert lassen , können Sie sie nie für eine andere Tabelle verwenden. Außerdem: Es ist keine Option, die aktiviert bleiben sollte. Standardmäßig sollten Sie SQL Server Identitätswerte verarbeiten lassen. Dies ist nur als letztes Mittel für ganz bestimmte Fälle gedacht. Es ist keine allgemeine Option, die aktiviert oder deaktiviert werden soll Ihre Freizeit ...
marc_s
61

Setzen Sie keinen Wert auf OperationID, da dieser automatisch generiert wird. Versuche dies:

Insert table(OpDescription,FilterID) values ('Hierachy Update',1)
Wael Dalloul
quelle
5
Dies ist die richtige Antwort, wenn Sie automatisch generierte OperationID
Shaijut
46

Einfach Wenn Sie diesen Fehler auf SQL Server erhalten, führen Sie diese Abfrage aus:

SET IDENTITY_INSERT tableName ON

Dies funktioniert nur mit einer einzelnen Datenbanktabelle. Wenn z. B. der Tabellenname student ist, sieht die Abfrage folgendermaßen aus SET IDENTITY_INSERT student ON

Wenn Sie diesen Fehler in Ihrer Webanwendung erhalten oder das Entity Framework verwenden, führen Sie diese Abfrage zuerst auf dem SQL Server aus und aktualisieren Sie Ihr Entity Model ( .edmx file), und erstellen Sie Ihr Projekt. Dieser Fehler wird behoben

Umang Patwa
quelle
Dies war in meiner MVC-Webanwendung mit EF der Fall, und ich habe gerade das Modell aus .edmx gelöscht und erneut hinzugefügt (Rechtsklick Modell aus Datenbank aktualisieren) und das Projekt bereinigt und neu erstellt, das dann für mich funktioniert hat. Vielen Dank, dass Sie @Umang Patwa
Ishwor Khanal
42

Seien Sie sehr vorsichtig, wenn Sie IDENTITY_INSERT auf ON setzen. Dies ist eine schlechte Vorgehensweise, es sei denn, die Datenbank befindet sich im Wartungsmodus und ist auf Einzelbenutzer eingestellt. Dies betrifft nicht nur Ihre Einfügung, sondern auch die anderer Personen, die versuchen, auf die Tabelle zuzugreifen.

Warum versuchen Sie, einen Wert in ein Identitätsfeld zu setzen?

HLGEM
quelle
5
Auswirkungen auf welche Weise? Dies ist eine Option auf Sitzungsebene, die keine Eigenschaft der Tabelle ist.
Martin Smith
5
Einmalige Datensynchronisierung zwischen zwei Datenbanken, für die Sie Beziehungen pflegen möchten. Zum Beispiel habe ich es verwendet, um mein Produktschema von einer Datenbank in eine andere zu ziehen
NSjonas
1
@NSjonas, das wäre eine gute Verwendung von set Identity _insert table1 ON. Ich habe Leute gesehen, die dies nutzen wollten, um etwas aus der Anwendung zu machen, das mit einer einfachen Einfügung gemacht werden sollte und die es ermöglicht, die Identität zu generieren.
HLGEM
2
Die Frage lautet: "Können Sie angeben, was es ist und wie es gelöst werden kann?" Ihre Antwort ist ein Kommentar, der eine Warnung und eine andere Frage anstelle einer richtigen Antwort auf das Problem auslöst.
Qualitätskatalysator
Ja, fügen Sie keinen Wert in den Primärschlüssel ein.
Doflamingo
22

Grundsätzlich gibt es zwei verschiedene Möglichkeiten, Datensätze ohne Fehler einzufügen:

1) Wenn IDENTITY_INSERT auf OFF gesetzt ist. Die PRIMARY KEY "ID" darf nicht vorhanden sein

2) Wenn IDENTITY_INSERT auf ON gesetzt ist. Die PRIMARY KEY "ID" muss vorhanden sein

Gemäß dem folgenden Beispiel aus derselben Tabelle, die mit einem IDENTITY PRIMARY KEY erstellt wurde:

CREATE TABLE [dbo].[Persons] (    
    ID INT IDENTITY(1,1) PRIMARY KEY,
    LastName VARCHAR(40) NOT NULL,
    FirstName VARCHAR(40)
);

1) Im ersten Beispiel können Sie neue Datensätze in die Tabelle einfügen, ohne einen Fehler zu erhalten, wenn IDENTITY_INSERT ausgeschaltet ist. Die PRIMARY KEY "ID" DARF NICHT AUS DEN "INSERT INTO" -Anweisungen vorhanden sein, und ein eindeutiger ID-Wert wird automatisch hinzugefügt : . Wenn die ID in diesem Fall vom INSERT vorhanden ist, wird die Fehlermeldung "Expliziter Wert für Identifizierungsspalte in Tabelle kann nicht eingefügt werden ..." nicht angezeigt.

SET IDENTITY_INSERT [dbo].[Persons] OFF;
INSERT INTO [dbo].[Persons] (FirstName,LastName)
VALUES ('JANE','DOE'); 
INSERT INTO Persons (FirstName,LastName) 
VALUES ('JOE','BROWN');

AUSGABE VON TABELLE [dbo]. [Personen] sind:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE

2) Im zweiten Beispiel können Sie neue Datensätze in die Tabelle einfügen, ohne dass ein Fehler auftritt, wenn IDENTITY_INSERT aktiviert ist. Der PRIMARY KEY "ID" MUSS in den "INSERT INTO" -Anweisungen vorhanden sein , solange der ID-Wert noch nicht vorhanden ist : Wenn die ID in diesem Fall vom INSERT NICHT vorhanden ist, wird der Fehler "Expliziter Wert muss sein" angezeigt angegeben für Identitätsspaltentabelle ... "

SET IDENTITY_INSERT [dbo].[Persons] ON;
INSERT INTO [dbo].[Persons] (ID,FirstName,LastName)
VALUES (5,'JOHN','WHITE'); 
INSERT INTO [dbo].[Persons] (ID,FirstName,LastName)
VALUES (3,'JACK','BLACK'); 

AUSGABE VON TABELLE [dbo]. [Personen] sind:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE
3     BLACK      JACK
5     WHITE      JOHN
QS-Spezialist
quelle
2
Plus eins, um zu erklären, wie die Flagge funktioniert. Rettete meinen Tag Superman
John
20

Fügen Sie in Ihrer Entität für diese Tabelle das DatabaseGeneratedAttribut über der Spalte hinzu, für die die Identitätseinfügung festgelegt ist:

Beispiel:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TaskId { get; set; }
user902490
quelle
Nun, stimmt, aber ich wollte wirklich eine Antwort für EF :-) Trotzdem ist es nicht angemessen für das OP, das EF möglicherweise nie benutzt hat oder vielleicht sogar angetroffen hat.
Auspex
In jedem Fall ist die Antwort falsch. Meine Entität ist bereits mit angegeben DatabaseGeneratedOption.Identity, und ich erhalte immer noch den Fehler. Es ist meine eigene Schuld, ich setze Pseudo-IDs in die neuen Zeilen, um sie auf meiner Webseite voneinander zu unterscheiden, und ich hoffe, sie einfach auf Null zu setzen, bevor die insertausreicht.
Auspex
13

Sie können diese Anweisung einfach verwenden, wenn Ihr Tabellenname School lautet . Vor dem Einsetzen stellen Sie sicher , identity_insert eingestellt ist ON und nach INSERT - Abfrage wiederum identity_insert OFF

SET IDENTITY_INSERT School ON
/*
  insert query
  enter code here
*/
SET IDENTITY_INSERT School OFF

quelle
1
Könnten Sie Ihre Antwort ein wenig erweitern, um eine Erklärung des Befehls aufzunehmen, warum er funktioniert und welche Auswirkungen er hat?
Gareththegeek
@gareththegeek Ja, es ist für die Identitätsspalte, die Sie aktivieren müssen, um Daten einzufügen.
6

Wenn Sie Liquibase zum Aktualisieren Ihres SQL Servers verwenden, versuchen Sie wahrscheinlich, einen Datensatzschlüssel in ein AutoIncrement-Feld einzufügen. Wenn Sie die Spalte aus der Einfügung entfernen, sollte Ihr Skript ausgeführt werden.

<changeSet id="CREATE_GROUP_TABLE" >
    <createTable tableName="GROUP_D">
        <column name="GROUP_ID" type="INTEGER" autoIncrement="true">
            <constraints primaryKey="true"/>
        </column>
    </createTable>
</changeSet>

<changeSet id="INSERT_UNKNOWN_GROUP" >
    <insert tableName="GROUP_D">    

        <column name="GROUP_ID" valueNumeric="-1"/>
 ...
    </insert>
</changeSet>
iowatiger08
quelle
4

Ihre Abfrage enthält eine bereits erwähnte OperationId, die nicht vorhanden sein sollte, da sie automatisch erhöht wird

Insert table(OperationID,OpDescription,FilterID)
values (20,'Hierachy Update',1)

so wird Ihre Anfrage sein

Insert table(OpDescription,FilterID)
values ('Hierachy Update',1)
Onkar_M18
quelle
3

Eine andere Situation besteht darin, zu überprüfen, ob der Primärschlüssel den gleichen Namen wie bei Ihren Klassen hat, wobei der einzige Unterschied darin besteht, dass an Ihren Primärschlüssel eine 'ID' angehängt ist, oder [Schlüssel] auf Primärschlüsseln anzugeben, die nicht mit dem wie zusammenhängen Klasse heißt.

salemsky95
quelle
2
  1. Dies tritt auf, wenn Sie eine Spalte (Primärschlüssel) haben, die in SQL nicht auf Is Identity to true festgelegt ist, und wenn Sie beim Einfügen keinen expliziten Wert davon übergeben. Es dauert die erste Zeile, dann können Sie die zweite Zeile nicht einfügen, der Fehler wird angezeigt. Dies kann korrigiert werden, indem Sie diese Codezeile [DatabaseGenerated(DatabaseGeneratedOption.Identity)]in Ihre PrimaryKey-Spalte einfügen und sicherstellen, dass sie auf einen Datentyp int festgelegt ist . Wenn die Spalte der Primärschlüssel ist und in SQL auf IsIDentity auf true gesetzt ist, ist diese Codezeile nicht erforderlich[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  2. Dies tritt auch auf, wenn Sie eine Spalte haben, die nicht der Primärschlüssel ist, in SQL auf Is Identity auf true gesetzt ist und Sie in Ihrer EF diese Codezeile nicht hinzugefügt haben [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
Siphamandla Held Ngwenya
quelle
Vielen Dank, dies war die Lösung, nach der ich stundenlang gesucht habe.
Vishav Premlall
2

Die beste Lösung ist die Verwendung von Anmerkungen GeneratedValue(strategy = ...), d. H.

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column ...
private int OperationID;

Es heißt, dass diese Spalte von der Datenbank mithilfe der IDENTITY-Strategie generiert wird und Sie sich nicht darum kümmern müssen - die Datenbank wird dies tun.

Tomasz Dzięcielewski
quelle
1

Wenn Sie dieses Problem haben, während Sie einen SQL-Server mit dem Sequelize-Typoskript npm verwenden, müssen Sie Folgendes @AutoIncrementzur ID-Spalte hinzufügen :

  @PrimaryKey
  @AutoIncrement
  @Column
  id!: number;
Kate Kasinskaya
quelle
0

Wenn Sie eine Verbindung mit Oracle SQL Developer herstellen, müssen Sie / sqldev: stmt hinzufügen / .

/ sqldev: stmt / set identity_insert TABLE on;

Hao Deng
quelle
Dies ist eindeutig nicht der Fall, die Frage hat ein "SQL-Server" -Tag
DanielV
0

Ich bin nicht sicher, wozu die "Tabelle einfügen" dient, aber wenn Sie nur versuchen, einige Werte einzufügen, versuchen Sie:

Insert Into [tablename] (OpDescription,FilterID)
values ('Hierachy Update',1);

Ich hatte die gleiche Fehlermeldung, aber ich denke, das sollte funktionieren. Die ID sollte automatisch inkrementiert werden, solange es sich um einen Primärschlüssel handelt.

Matthew
quelle
0

Ich habe dieses Problem gelöst, indem ich jedes Mal ein neues Objekt erstellt habe, wenn ich der Datenbank etwas hinzufügen möchte.

Naresh Bisht
quelle
0

Beachten Sie, dass, wenn Sie jede Zeile mit schließen ;, dieSET IDENTITY_INSERT mytable ON Befehl für die folgenden Zeilen nicht gilt .

dh
eine Abfrage wie

SET IDENTITY_INSERT mytable ON;
INSERT INTO mytable (VoucherID, name) VALUES (1, 'Cole');

Gibt den Fehler
Cannot insert explicit value for identity column in table 'mytable' when IDENTITY_INSERT is set to OFF.

Aber eine Abfrage wie diese wird funktionieren:

SET IDENTITY_INSERT mytable ON
INSERT INTO mytable (VoucherID, name) VALUES (1, 'Cole')
SET IDENTITY_INSERT mytable OFF;

Es scheint, dass der SET IDENTITY_INSERTBefehl nur für eine Transaktion gilt und ;das Ende einer Transaktion bedeutet.

cryanbhu
quelle
-1

Das Problem ergab sich aus der Verwendung von nicht typisiertem DBContext oder DBSet, wenn Sie Interface verwenden und die Methode zum Speichern von Änderungen generisch implementieren

Wenn dies Ihr Fall ist, schlage ich zum Beispiel vor, DBContex stark zu tippen

MyDBContext.MyEntity.Add(mynewObject)

dann .Savechangeswird es funktionieren

Mostafa Basha
quelle
-1

Löschen Sie einfach die Tabellen, die in Ihre .dbml-Datei gezogen werden, und ziehen Sie sie erneut. Dann Lösung reinigen> Lösung neu erstellen> Lösung erstellen.

Das hat bei mir funktioniert.

Ich habe die Tabelle nicht selbst erstellt, ich habe VS und SSMS verwendet, ich bin diesem Link für ASP.NET Identity gefolgt: https://docs.microsoft.com/en-us/aspnet/identity/overview/getting-started/ Hinzufügen einer Aspnet-Identität zu einem leeren oder vorhandenen Webformular-Projekt

Usama
quelle