的ExecuteScalar(); 使用scope_identity()生成“System.InvalidCastException:指定的强制转换无效”

我有一个接受各种数据的表单(通过文本框和复选框列表),在click事件中,他们将所有数据插入表中并选择scope_identity,然后将其存储在变量中,以便在插入checkboxlist项时使用它使用循环到另一个表

根据许多答案和例子,这应该工作得很好!..但它给了我这个错误:

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

这是我的linkbutton方法代码:

  protected void lnkbtnUploadAndSubmit_Click(object sender, EventArgs e) { SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MOODbCenterConnection"].ConnectionString); 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(); } } } 

编辑奇怪的是,当我直接在visual studio的sql server express中运行时,查询工作正常!

对这个奇怪问题的奇怪解释

alexb的第一个解决方案:

我做到了:)我的sql server 2008将System.Decimal返回打包到’object’中。 尝试使用System.Convert.ToInt32而不是强制转换。

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

我的第二个解决方案:

而不是使用“SELECT scope_identity();” 我用“SELECT BrandId FROM Brands WHERE BrandId = @@ Identity;” 它为您提供了更多的控制权,但我亲自推出了第一个解决方案

注意:“SELECT @@ Identity;” 也会工作得很好

谢谢你们,我希望它能帮到别人!

comm.ExecuteScalar()究竟返回什么? 也许它返回longdouble包装到object
不记得确切,但似乎我曾在1 – 2年前遇到过。

如果您可以更改SQL,则可以采用更简单的方法

 SELECT CONVERT(int, SCOPE_IDENTITY()) 

正如Dimi所说,Identity是一个SQL数字(.NET Decimal)。 这应该工作:

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

来自SCOPE_IDENTITY()的文档

 Return Types numeric(38,0) 

因此,一个简单的解决方案将是以下

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

尝试添加SET NOCOUNT ON; 在插入之前。