web-dev-qa-db-fra.com

Désactiver IDENTITY_INSERT pour l'insertion de l'ensemble de données

J'utilise un ensemble de données pour insérer des données en cours de conversion à partir d'une ancienne base de données. L'obligation est de conserver les numéros Order_ID actuels.

J'ai essayé d'utiliser:

SET IDENTITY_INSERT orders ON;

Cela fonctionne lorsque je suis dans SqlServer Management Studio, je suis en mesure de réussir

INSERT INTO orders (order_Id, ...) VALUES ( 1, ...);

Cependant, cela ne me permet pas de le faire via l'insertion de jeu de données que j'utilise dans mon script de conversion. Qui ressemble essentiellement à ceci:

dsOrders.Insert(oldorderId, ...);

J'ai également exécuté le SQL (SET IDENTITY_INSERT Orders ON) pendant le processus. Je sais que je ne peux le faire que contre une table à la fois et je le suis.

Je reçois toujours cette exception:

Exception lors de la tentative d'insertion d'une valeur dans la table de commandes System.Data.SqlClient.SqlException: impossible d'insérer une valeur explicite pour la colonne d'identité dans la table 'commandes' lorsque IDENTITY_INSERT est défini sur OFF.

Des idées?

Mise à jour

AlexS et AlexKuznetsov ont mentionné que Set Identity_Insert est un paramètre de niveau de connexion, cependant, lorsque je regarde le SQL dans SqlProfiler, je remarque plusieurs commandes.

  • Première - SET IDENTITY_INSERT DEAL ON
  • Seconde - exec sp_reset_connection
  • Troisième à n - mes diverses commandes sql, y compris les select & insert

Il y a toujours un exec sp_reset_connection entre les commandes cependant, je pense que cela est responsable de la perte de valeur sur le paramètre Identity_Insert.

Existe-t-il un moyen d'empêcher mon ensemble de données de réinitialiser la connexion?

27
Nathan Koop

Vous avez les options mélangées:

SET IDENTITY_INSERT orders ON

va activer SUR la possibilité d'insérer des valeurs spécifiques (que vous spécifiez) dans un tableau avec une colonne IDENTITY.

SET IDENTITY_INSERT orders OFF

Désactive à nouveau ce comportement et le comportement normal (vous ne pouvez pas spécifier de valeurs pour les colonnes IDENTITY car elles sont générées automatiquement) est rétabli.

Marc

53
marc_s

Vous voulez faire SET IDENTITY_INSERT SUR pour vous permettre d'insérer dans les colonnes d'identité.

Cela semble un peu en arrière, mais c'est ainsi que cela fonctionne.

5
Eric Petroelje

Il semble que vous fassiez tout correctement: les commandes SET IDENTITY_INSERT ON sont la bonne façon côté SQL Server . Mais le problème est que vous utilisez des ensembles de données. D'après le code que vous avez fourni, je peux dire que vous utilisez ensemble de données typé - celui qui a été généré dans Visual Studio basé sur la base de données.

Si tel est le cas (le plus probable), alors cet ensemble de données contient une contrainte qui ne vous permet pas de définir des valeurs pour orderId , c'est-à-dire que c'est le code qui ne permet pas de spécifier une valeur explicite, pas SQL Server. Vous devez aller au concepteur de jeu de données et modifier les propriétés du champ orderId: définissez AutoIncrement et ReadOnly sur false. Mais les mêmes modifications peuvent être effectuées lors de l'exécution. Cela vous permettra d'ajouter une ligne avec une valeur explicite pour orderId à un ensemble de données et de l'enregistrer plus tard dans la table SQL Server (vous aurez toujours besoin de SET IDENTITY_INSERT).

Notez également que IDENTITY_INSERT est un paramètre au niveau de la connexion, vous devez donc être sûr d'exécuter le SET correspondant exactement pour la même connexion que vous utiliserez pour enregistrer vos modifications dans la base de données.

3
AlexS

AlexS était correct, le problème était que Insert_Identity fonctionnait, mais c'est un paramètre de niveau de connexion, donc j'avais besoin de définir Insert_Identity dans une transaction.

J'ai utilisé le code TableAdapterHelper de Ryan Whitaker

et j'ai créé une commande de mise à jour sur mon adaptateur de table qui exécutait Identity_Insert. J'ai ensuite dû créer une nouvelle commande Insérer avec la colonne Identité spécifiée. J'ai ensuite exécuté ce code

SqlTransaction transaction = null;

try
{
     using (myTableAdapter myAdapter = new myTableAdapter())
     {   
         transaction = TableAdapterHelper.BeginTransaction(myAdapter);
         myAdapter.SetIdentityInsert();
         myAdapter.Insert(myPK,myColumn1,myColumn2,...);
     }

     transaction.Commit();
 }
 catch(Exception ex)
 {
     transaction.Rollback();
 } 
 finally
 {
     transaction.Dispose();
 }
1
Nathan Koop

J'utiliserais Profiler pour déterminer si vos commandes SET IDENTITY_INSERT ON; est émis à partir de la même connexion que vos insertions suivantes, ainsi que le SQL exact exécuté lors des insertions.

1
A-K

Dans le cas où vous avez toujours des problèmes avec "insérer l'identité", vous pouvez essayer d'utiliser un instruction d'insertion complète comme:

0
user3447006