ExecuteScalar (); Avec scope_identity () Génération de «System.InvalidCastException: la dissortingbution spécifiée n’est pas valide»

J’ai un formulaire qui accepte diverses données (via des zones de texte et une liste de cases à cocher) et insère toutes les données dans une table lors de l’événement click, sélectionne ensuite le scope_identity, puis le stocke dans une variable pour l’utiliser utiliser une boucle dans une autre table

selon de nombreuses réponses et exemples, cela devrait fonctionner parfaitement! .. mais cela me donne cette erreur:

Exception Details: System.InvalidCastException: Specified cast is not valid. Line 66: int NewBrandId = (int)comm.ExecuteScalar(); 

Voici mon code de méthode linkbutton:

  protected void lnkbtnUploadAndSubmit_Click(object sender, EventArgs e) { SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionSsortingngs["MOODbCenterConnection"].ConnectionSsortingng); SqlCommand comm = new SqlCommand("INSERT INTO Brands (BrandName, BrandLogo, BrandWebsite, IsBrandVisible) VALUES (@Name, @Logo, @Website, @IsVisible); SELECT scope_identity();", conn); comm.Parameters.Add("@Name", System.Data.SqlDbType.NVarChar, 50); comm.Parameters["@Name"].Value = txtbxBrandName.Text; comm.Parameters.Add("@Logo", System.Data.SqlDbType.Text); comm.Parameters["@Logo"].Value = fileuploadLogo.PostedFile.FileName; comm.Parameters.Add("@Website", System.Data.SqlDbType.Text); comm.Parameters["@Website"].Value = txtbxWebsite.Text; comm.Parameters.Add("@IsVisible", System.Data.SqlDbType.Bit); comm.Parameters["@IsVisible"].Value = chkbxIsPublished.Checked; conn.Open(); int NewBrandId = (int)comm.ExecuteScalar(); conn.Close(); foreach (ListItem li in chkbxlstCuisines.Items) { if (li.Selected) { conn.Open(); SqlCommand comm2 = new SqlCommand("INSERT INTO BrandCuisines (CuisineId, BrandId) VALUES (@CuisineId, @NewBrandId)", conn); comm2.Parameters.Add("@CuisineId", System.Data.SqlDbType.Int); comm2.Parameters["@CuisineId"].Value = li.Value; comm2.Parameters.Add("@NewBrandId", System.Data.SqlDbType.Int); comm2.Parameters["@NewBrandId"].Value = NewBrandId; comm2.ExecuteNonQuery(); conn.Close(); } } } 

Modifier Étrangement, la requête fonctionne bien lorsque je l’exécute directement dans le serveur SQL Express du studio visuel!

L’explication étrange de cet étrange problème

Première solution par alexb:

Je l’ai fait 🙂 Mon serveur SQL 2008 renvoie System.Decimal dans “object”. Essayez d’utiliser System.Convert.ToInt32 au lieu de la conversion.

 Example : int NewBrandId = System.Convert.ToInt32(comm.ExecuteScalar()); 

Deuxième solution par moi:

au lieu d’utiliser “SELECT scope_identity ();” J’ai utilisé “SELECT BrandId FROM Brands WHERE BrandId = @@ Identity;” cela vous donne encore plus de contrôle mais je préfère personnellement la première solution

NB: “SELECT @@ Identity;” fonctionnerait aussi très bien

Merci les gars et j’espère que ça aide les autres!

Qu’est-ce que comm.ExecuteScalar() renvoie exactement? Peut-être qu’il retourne long ou double emballé dans un object .
Je ne me souviens pas exactement, mais il semble que j’avais affronté quelque chose il y a un ou deux ans.

Si vous pouvez changer le code SQL, un moyen encore plus simple serait de

 SELECT CONVERT(int, SCOPE_IDENTITY()) 

Comme Dimi l’a dit, Identity est un fichier numérique SQL (.NET Decimal). Cela devrait fonctionner:

 decimal decimalBrandId = (decimal)comm.ExecuteScalar(); int NewBrandId = (int)decimalBrandId; 

De la documentation pour SCOPE_IDENTITY ()

 Return Types numeric(38,0) 

Donc, une solution facile serait la suivante

 DECLARE @ReturnValue INT; /* Do your insert stuff here. */ SELECT @ReturnValue = SCOPE_IDENTITY(); SELECT @ReturnValue; 

essayez d’append SET NOCOUNT ON; avant l’insertion.