2012-09-27 4 views
2

J'ai une table avec une colonne d'identité dont je souhaite obtenir la valeur après un INSERT. Le code suivant, qui n'utilise pas les paramètres, fonctionne parfaitement:SCOPE_IDENTITY ne semble pas fonctionner avec les requêtes paramétrées

string query = "INSERT INTO aTable ([aColumn]) VALUES (42)"; 
SqlCommand command = new SqlCommand(query, connection); 
command.ExecuteNonQuery(); 

query = "SELECT CAST(SCOPE_IDENTITY() AS bigint)"; 
command = new SqlCommand(query, connection); 
object identity = command.ExecuteScalar(); 

Si je change la partie INSERT du code ci-dessus pour utiliser une requête paramétrées, ExecuteScalar() retourne soudainement une valeur System.DBNull. Voici comment le code de requête paramétrées ressemble:

string query = "INSERT INTO aTable ([aColumn]) VALUES (@aColumn)"; 
SqlCommand command = new SqlCommand(query, connection); 
command.Parameters.AddWithValue("@aColumn", 42); 
command.ExecuteNonQuery(); 

J'ai essayé de changer le code SCOPE_IDENTITY afin qu'il utilise un paramètre de sortie et invoque ExecuteNonQuery(), mais je reçois encore une valeur nulle dans le paramètre out. J'ai également essayé d'exécuter le code contre deux versions différentes de SQL Server (2012 et 2008, les deux Express Edition), toujours avec le même résultat.

Des idées de ce que je fais mal ici?

+6

requêtes paramétrées vent probablement appeler 'sp_executesql'. Cela s'exécute dans une portée enfant et quand il sort 'SCOPE_IDENTITY()' est null dans la portée externe. –

+1

En plus de les combiner en un seul lot, une autre solution consiste à arrêter l'incorporation de SQL dynamique dans votre application et à mettre cette logique dans une procédure stockée. –

+0

Vous pouvez également essayer 'INSERT INTO aTable (...) OUTPUT Inserted.ID VALUES (.....)' pour afficher automatiquement toutes les nouvelles valeurs 'ID' insérées. –

Répondre

6

Essayez de combiner votre INSERT et SELECT dans une instruction

string query = "INSERT INTO aTable ([aColumn]) VALUES (@aColumn);SELECT CAST(SCOPE_IDENTITY() AS bigint)"; 
SqlCommand command = new SqlCommand(query, connection); 
command.Parameters.AddWithValue("@aColumn", 42); 
object identity = command.ExecuteScalar(); 
+0

Pour un néophyte comme moi qui semble incroyable, mais avec le commentaire de Martin Smith, cela a du sens :-) En tout cas, merci beaucoup! – herzbube