Impossible d'insérer une valeur explicite pour la colonne d'identité dans la table 'table' lorsque IDENTITY_INSERT est défini sur OFF


361

J'ai l'erreur ci-dessous lorsque j'exécute le script suivant. Quelle est l'erreur et comment la résoudre?

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

Erreur:

Serveur: Msg 544, niveau 16, état 1, ligne 1

Impossible d'insérer une valeur explicite pour la colonne d'identité dans la table 'table' lorsque IDENTITY_INSERT est défini sur OFF.



2
@HimanshuAhuja Cette question (1334012) a 10 ans, celle que vous avez liée seulement 1. Si quelque chose, alors le plus récent est un doublon. Mais en y regardant de plus près, vous constaterez qu'ils diffèrent (le plus récent spécifie IDENTITY_INSERT comme ON). Veuillez supprimer votre drapeau / commentaire.
jasie

@jasie fera cela car je ne me souviens pas quand j'avais posté ce drapeau
Himanshu Ahuja

Réponses:


467

Vous insérez des valeurs pour OperationIdcela est une colonne d'identité.

Vous pouvez activer l'insertion d'identité sur la table comme ceci afin de pouvoir spécifier vos propres valeurs d'identité.

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 

14
+1 exactement - tourner l'option pour permettre des insertions explicites ON , puis insérez, puis mettez l'option OFF à nouveau
marc_s

13
Si vous voulez vraiment ajouter votre valeur à la colonne d'identité, c'est votre réponse, mais d'un autre côté, quelqu'un a défini la colonne pour qu'elle s'incrémente d'elle-même lors de l'insertion. Dans ce cas, le tableau gardera la trace du prochain numéro gratuit et vous n'avez pas besoin de générer vous-même l'OperationID. Le nouvel identifiant peut être récupéré par SELECT SCOPE_IDENTITY ().
Hakan Winther

15
Pratique dangereuse, ne recommande pas de l'utiliser sans avertissements expliquant pourquoi c'est une mauvaise idée. Très mauvaise réponse.
HLGEM

7
bonne réponse, mais assurez-vous de savoir ce que vous faites. Pour moi, il est utile d'amorcer une base de données avec des données où les clés étrangères doivent correspondre sur différentes tables
Berty

2
@UlyssesAlves: cette option ne peut être activée que pour une seule table à l'échelle de la base de données - donc si vous la laissez activée pour une table, vous ne pourrez jamais l'utiliser pour une autre table. De plus: ce n'est pas une option qui devrait être laissée sur - par défaut, vous devez laisser les valeurs d'identité de poignée SQL Server - c'est uniquement conçu comme une mesure de dernier recours pour des cas très spécifiques - pas une option polyvalente de quitter ou de désactiver à vos loisirs ...
marc_s

61

ne mettez pas de valeur à OperationID car il sera généré automatiquement. essaye ça:

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

5
c'est la bonne réponse si vous voulez générer automatiquement OperationID
shaijut

46

Si vous obtenez cette erreur sur le serveur SQL, exécutez cette requête -

SET IDENTITY_INSERT tableName ON

cela ne fonctionne que sur une seule table de base de données, par exemple si le nom de la table est étudiant, la requête ressemble à ceci SET IDENTITY_INSERT student ON

Si vous obtenez cette erreur sur votre application Web ou que vous utilisez le framework d'entité, exécutez d'abord cette requête sur le serveur SQL et mettez à jour votre modèle d'entité ( .edmx file) et générez votre projet et cette erreur sera résolue


C'était le cas dans mon application Web MVC avec EF et je viens de supprimer le modèle de .edmx et de l'ajouter à nouveau (Clic droit Mettre à jour le modèle de la base de données) et nettoyer et reconstruire le projet qui a ensuite fonctionné pour moi. Merci @Umang Patwa
Ishwor Khanal

42

Faites très attention de ne pas définir IDENTITY_INSERT sur ON. Il s'agit d'une mauvaise pratique, sauf si la base de données est en mode maintenance et définie sur un seul utilisateur. Cela affecte non seulement votre insert, mais aussi ceux de toute autre personne essayant d'accéder à la table.

Pourquoi essayez-vous de mettre une valeur dans un champ d'identité?


5
Affecte de quelle manière? Il s'agit d'une option au niveau de la session et non d'une propriété de la table.
Martin Smith

5
Synchronisation unique des données entre deux bases de données que vous souhaitez maintenir des relations. Par exemple, je l'ai utilisé pour extraire mon schéma de produit d'une base de données à une autre
NSjonas

1
@NSjonas, ce serait une bonne utilisation de set Identity _insert table1 ON. J'ai vu des gens qui voulaient l'utiliser pour faire quelque chose à partir de l'application qui devrait être fait avec un simple insert et permettant à l'identité d'être générée.
HLGEM

2
La question est "Pourriez-vous préciser de quoi il s'agit et comment le résoudre?" Votre réponse est un commentaire qui déclenche un avertissement et une autre question au lieu d'une réponse appropriée qui résout le problème.
Quality Catalyst

ouais, n'insérez pas de valeur dans la clé primaire.
doflamingo

22

Il existe essentiellement 2 façons différentes d'INSERER des enregistrements sans avoir d'erreur:

1) Lorsque IDENTITY_INSERT est réglé sur OFF. La clé primaire ID " " NE DOIT PAS ÊTRE PRÉSENT

2) Lorsque IDENTITY_INSERT est défini sur ON. La clé primaire ID DOIT ÊTRE PRÉSENT

Comme dans l'exemple suivant de la même table créée avec une CLÉ PRIMAIRE D'IDENTITÉ:

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

1) Dans le premier exemple, vous pouvez insérer de nouveaux enregistrements dans la table sans obtenir d'erreur lorsque IDENTITY_INSERT est désactivé. La clé primaire « ID » NE DOIT PAS ÊTRE PRÉSENT des déclarations « INSERT INTO » et une valeur d'identification unique sera automatiquement ajouté: . Si l'ID est présent dans INSERT dans ce cas, vous obtiendrez l'erreur "Impossible d'insérer une valeur explicite pour identifier la colonne dans le tableau ..."

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

SORTIE du TABLEAU [dbo]. [Personnes] seront:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE

2) Dans le deuxième exemple, vous pouvez insérer de nouveaux enregistrements dans la table sans obtenir d'erreur lorsque IDENTITY_INSERT est activé. L' ID " PRIMARY KEY " DOIT ÊTRE PRÉSENT à partir des instructions "INSERT INTO" tant que la valeur ID n'existe pas déjà : si l'ID n'est PAS présent dans INSERT dans ce cas, vous obtiendrez l'erreur "La valeur explicite doit être spécifié pour la table des colonnes d'identité ... "

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'); 

SORTIE du TABLEAU [dbo]. [Personnes] seront:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE
3     BLACK      JACK
5     WHITE      JOHN

2
Plus un pour expliquer le fonctionnement du drapeau. Sauvé ma journée Superman
John

20

Dans votre entité pour cette table, ajoutez le DatabaseGenerated attribut au-dessus de la colonne pour laquelle l'insertion d'identité est définie:

Exemple:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TaskId { get; set; }

Eh bien, c'est vrai, mais je voulais vraiment une réponse pour EF :-) Pourtant, ce n'est pas approprié pour l'OP qui n'a peut-être jamais utilisé, ou peut-être même rencontré, EF.
Auspex

En tout cas, la réponse est fausse. Mon entité est déjà spécifiée avec DatabaseGeneratedOption.Identityet j'obtiens toujours l'erreur. C'est ma faute, je mets des pseudo-ID dans les nouvelles lignes pour les distinguer les uns des autres sur ma page Web, et j'espère simplement les annuler avant que le insertsuffise.
Auspex

13

vous pouvez simplement utiliser cette instruction par exemple si le nom de votre table est School . Avant l'insertion, assurez-vous que identity_insert est défini sur ON et après l'insertion de la requête, désactivez identity_insert sur OFF

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

1
Pourriez-vous développer un peu votre réponse pour inclure une explication de la commande, pourquoi elle fonctionne et quel effet elle a?
gareththegeek

@gareththegeek oui c'est pour la colonne d'identité que vous devez vous assurer d'activer pour insérer des données.

6

Si vous utilisez Liquibase pour mettre à jour votre SQL Server, vous essayez probablement d'insérer une clé d'enregistrement dans un champ autoIncrement. En supprimant la colonne de l'insert, votre script devrait s'exécuter.

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

4

Il y a un OperationId pré-mentionné dans votre requête qui ne devrait pas être là car il est incrémenté automatiquement

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

donc votre requête sera

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

3

Une autre situation consiste à vérifier que la clé primaire est le même nom qu'avec vos classes où la seule différence est que votre clé primaire a un «ID» ajouté à elle ou à spécifier [clé] sur les clés primaires qui ne sont pas liées à la façon dont le la classe est nommée.


2
  1. Cela se produit lorsque vous avez une colonne (clé primaire) qui n'est pas définie sur Is Identity sur true dans SQL et que vous n'en transmettez pas de valeur explicite pendant l'insertion. Cela prendra la première ligne, puis vous ne pourrez pas insérer la deuxième ligne, l'erreur apparaîtra. Cela peut être corrigé en ajoutant cette ligne de code [DatabaseGenerated(DatabaseGeneratedOption.Identity)]dans votre colonne PrimaryKey et assurez-vous qu'elle est définie sur un type de données int . Si la colonne est la clé primaire et est définie sur IsIDentity sur true dans SQL, cette ligne de code n'est pas nécessaire[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  2. cela se produit également lorsque vous avez une colonne qui n'est pas la clé primaire, dans SQL qui est défini sur Est-ce que l'identité est vraie, et dans votre EF, vous n'avez pas ajouté cette ligne de code [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

Merci, c'était le correctif que j'ai passé des heures à chercher.
Vishav Premlall

2

La meilleure solution consiste à utiliser l'annotation GeneratedValue(strategy = ...), c'est-à-dire

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

il indique que cette colonne est générée par la base de données en utilisant la stratégie IDENTITY et que vous n'avez pas besoin de vous en occuper - la base de données le fera.


1

Si vous rencontrez ce problème lors de l'utilisation d'un serveur SQL avec le npm sequelize-typescript, assurez-vous d'ajouter @AutoIncrementà la colonne ID:

  @PrimaryKey
  @AutoIncrement
  @Column
  id!: number;

0

Et si vous utilisez Oracle SQL Developer pour vous connecter, n'oubliez pas d'ajouter / sqldev: stmt /

/ sqldev: stmt / set Identity_insert TABLE on;


Ce n'est clairement pas le cas, la question a une balise "sql-server"
DanielV

0

Je ne sais pas à quoi sert le "Insérer un tableau", mais si vous essayez simplement d'insérer des valeurs, essayez:

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

J'ai eu le même message d'erreur, mais je pense que cela devrait fonctionner. L'ID doit s'incrémenter automatiquement tant qu'il s'agit d'une clé primaire.


0

J'ai résolu ce problème en créant un nouvel objet chaque fois que je veux ajouter quelque chose à la base de données.


0

Notez que si vous fermez chaque ligne avec ;, la SET IDENTITY_INSERT mytable ONcommande ne sera pas maintenue pour les lignes suivantes.

c'est à dire
une requête comme

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

Donne l'erreur
Cannot insert explicit value for identity column in table 'mytable' when IDENTITY_INSERT is set to OFF.

Mais une requête comme celle-ci fonctionnera:

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

Il semble que la SET IDENTITY_INSERTcommande ne soit valable que pour une transaction, et le ;signifiera la fin d'une transaction.


-1

Le problème posé par l'utilisation de DBContext ou DBSet non typé si vous utilisez Interface et implémentez la méthode de savechanges de manière générique

Si tel est votre cas je vous propose par exemple de taper fortement DBContex

MyDBContext.MyEntity.Add(mynewObject)

alors .Savechangesfonctionnera


-1

Supprimez simplement les tableaux qui sont glissés dans votre fichier .dbml et faites-les à nouveau glisser. Puis Nettoyez la solution> Reconstruisez la solution> Générez la solution.

C'est ce qui a fonctionné pour moi.

Je n'ai pas fait le tableau par moi-même, j'utilisais VS et SSMS, j'ai suivi ce lien pour l'identité ASP.NET: https://docs.microsoft.com/en-us/aspnet/identity/overview/getting-started/ ajout d'une identité aspnet à un projet de formulaires Web vide ou existant

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.