Comment activer et désactiver IDENTITY_INSERT à l'aide de SQL Server 2008?

461

Pourquoi est-ce que j'obtiens une erreur lors de l'insertion lorsque IDENTITY_INSERTest réglé sur OFF?

Comment l'activer correctement dans SQL Server 2008? Est-ce en utilisant SQL Server Management Studio?

J'ai exécuté cette requête:

SET IDENTITY_INSERT Database. dbo. Baskets ON

Ensuite, j'ai reçu le message dans la console que la ou les commandes se sont terminées avec succès. Cependant, lorsque j'exécute l'application, cela me donne toujours l'erreur indiquée ci-dessous:

Cannot insert explicit value for identity column in table 'Baskets' when 
IDENTITY_INSERT is set to OFF.
Débutant
la source
Veuillez développer cette question afin que nous puissions comprendre ce que vous essayez de faire. Quelle instruction exécutez-vous lorsque vous rencontrez cette erreur et quel est le texte réel du message d'erreur?
Matt Gibson
Même si vous avez posé une autre question, vous devez accepter une réponse ici: nous avons répondu à ce que vous avez demandé .
gbn
8
J'ai horreur de l'idée que quelqu'un essaie d'envoyer des valeurs d'identité à partir d'une application. Ce n'est pas quelque chose que vous devriez faire, sauf pour la migration de données peu fréquente. Si vous le faites assez régulièrement pour l'exécuter à partir d'une application, vous devrez probablement revoir votre conception de table.
HLGEM
J'utilise ceci dans ma sauvegarde scriptée SQL. Pendant la restauration, cela m'a permis de charger les données dans une table à incrémentation automatique avec les valeurs d'origine. La sauvegarde par script m'a permis de rétrograder la base de données SQL. La réalisation par Management Studio de la sauvegarde par script rend le script déchargeable si je stocke des données binaires dans un champ de texte.
Jettero

Réponses:

771

Via SQL selon MSDN

SET IDENTITY_INSERT sometableWithIdentity ON

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

SET IDENTITY_INSERT sometableWithIdentity OFF

Le message d'erreur complet vous indique exactement ce qui ne va pas ...

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

gbn
la source
@Beginner: vous l'êtes pourtant, d'où l'erreur. Comment savoir que vous ne voulez pas insérer de valeurs? Nous n'avons qu'un message d'erreur
gbn
3
L'erreur vient de mon application lorsque je fais DB.SaveChanges ();
Débutant
5
Non, arrêtez simplement d'envoyer une valeur pour la colonne d'identité. Ou définissez-le si vous le souhaitez dans votre application si vous souhaitez envoyer une valeur ..... mais alors pourquoi avoir une colonne avec la propriété d'identité définie pour générer des valeurs? Nous ne pouvons pas décider pour vous
gbn
22
@Beginner: le paramètre n'est applicable que dans la session en cours (personne ne l'a fait remarquer pour cette question), donc votre application devrait l'activer pour que l'application exécute de telles insertions (et il est probablement préférable d'activer rapidement le désactiver à nouveau lorsque ces insertions sont terminées, comme gbn montre). La façon dont vous insériez une valeur sur la colonne d'identité sans vous en rendre compte n'est pas claire, mais peut-être que les anciennes versions de SQL Server l'incluraient implicitement avec toutes les colonnes lorsque les colonnes d'insertion explicites ne sont pas spécifiées (?) Comme Ismael semble le suggérer.
Rob Parker
2
@Rob, je pense que vous avez un point et j'échoue personnellement à la révision du code sur tout code qui ne s'insère pas sans spécifier de colonnes. Mis à part le temps perdu sur une erreur, c'est une pratique risquée et vous pouvez vous retrouver avec de graves problèmes d'intégrité des données si les données de la colonne ne correspondent pas correctement.
HLGEM
59

J'ai eu un problème où il ne m'a pas permis de l'insérer même après avoir activé IDENTITY_INSERT.

Le problème était que je n'ai pas spécifié les noms des colonnes et pour une raison quelconque, il ne l'aimait pas.

INSERT INTO tbl Values(vals)

Donc, fondamentalement, faites le plein INSERT INTO tbl (cols) Valeurs (vals)

Ismael
la source
6
ne posez pas de questions dans le volet de réponses.
Duk
4
c'était exactement ce qu'il voulait de moi, pour spécifier la liste des colonnes (les deux colonnes sur la table, bof)
Maslow
36

Importer: vous devez écrire des colonnes dans l' INSERTinstruction

INSERT INTO TABLE
SELECT * FROM    

N'est pas correcte.

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

Est correct

R.Alonso
la source
2
Merci, cela a été très utile
José Romero
1
Si vous avez des colonnes identiques dans les deux tables, vous pouvez vous passer de lister les colonnes dans la sélection (Field1 ..) comme ceci .... Insérer dans la table (Field1, ...) Sélectionnez * dans TABLE ... et si vous avez Champ d'identité à insérer en premier lieu ** SET IDENTITY_INSERT Table_name ON
user3590235
@ user3590235 C'est une hypothèse risquée à faire, que la liste des colonnes est identique. En dehors des requêtes manuelles des utilisateurs, ne faites jamais cela, car je vous garantis que vous casserez PROD un jour quand quelqu'un d'autre modifiera la définition de la table sans mettre à jour votre référence.
Elaskanator
5

Je sais que c'est un fil plus ancien mais je suis juste tombé dessus. Si l'utilisateur essaie d'exécuter des insertions sur la colonne Identité après une autre session Réglez IDENTITY_INSERT ON, alors il est lié pour obtenir l'erreur ci-dessus.

La définition de la valeur d'insertion d'identité et les commandes d'insertion DML suivantes doivent être exécutées par la même session.

Ici, @Beginner définissait Identity Insert ON séparément, puis exécutait les insertions à partir de son application. C'est pourquoi il a obtenu l'erreur ci-dessous:

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

Cela est probable lorsque vous disposez d'un champ PRIMARY KEY et que vous insérez une valeur qui se duplique ou que l'indicateur INSERT_IDENTITY est défini sur on

seanyp20001
la source
0

Il semble nécessaire de mettre un SET IDENTITY_INSERT Database.dbo.Baskets ON;avant chaque INSERTlot d'envoi SQL .

Vous pouvez envoyer plusieurs INSERT ... VALUES ...commandes commencées par une SET IDENTITY_INSERT ... ON;chaîne au début. Ne mettez pas de séparateur de lots entre les deux.

Je ne sais pas pourquoi les SET IDENTITY_INSERT ... ONarrêts de travail après le bloc d'envoi (par exemple: .ExecuteNonQuery()en C #). J'ai dû mettre à SET IDENTITY_INSERT ... ON;nouveau au début de la prochaine chaîne de commande SQL.

Jettero
la source
peut-être que cela répond à votre question: stackoverflow.com/questions/5791941/…
Demetris Leptos
0

Une autre option est où vous avez des tables comme `` type '' ou `` état '', par exemple, OrderStatus, où vous voulez toujours contrôler la valeur Id, créez la colonne Id (clé primaire) sans que ce soit une colonne d'identité est la première place.

Robert Brooker
la source
-1

Vous devez ajouter la commande «go» après avoir défini l'insertion d'identité. Exemple:

SET IDENTITY_INSERT sometableWithIdentity ON
go

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

SET IDENTITY_INSERT sometableWithIdentity OFF
go
Bruce
la source
5
Cette question a quatre ans et a une réponse acceptée. Votre réponse duplique la réponse acceptée
Ghost
13
Eh bien, pas une duplication exacte - il a inclus les commandes "go" ...;)
RoastBeast