执行标量();使用scope_identity()生成“System.InvalidCastException:指定的强制转换无效”
我有一个接受各种数据的表单(通过文本框和复选框列表),并且在单击事件时,它们将所有数据插入表中并选择scope_identity,然后将其存储在变量中以在插入复选框列表项时使用它 使用循环进入另一个表,
根据许多答案和示例,
Exception Details: System.InvalidCastException: Specified cast is not valid.
Line 66: int NewBrandId = (int)comm.ExecuteScalar();
这应该可以完美工作!..但是它给了我这个错误:这是我的链接按钮方法代码:
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();
}
}
}
编辑奇怪的是,当我直接在 sql server express 中运行它时,查询工作正常视觉工作室!
对这个奇怪问题的奇怪解释
alexb 的第一个解决方案:
我做到了:) 我的 sql server 2008 返回 System.Decimal 打包到“对象”中。 尝试使用 System.Convert.ToInt32 而不是演员。
Example : int NewBrandId = System.Convert.ToInt32(comm.ExecuteScalar());
我的第二个解决方案:
而不是使用“选择 scope_identity();”我用了“SELECT BrandId 来自品牌 WHERE BrandId = @@Identity;”它为您提供更多 控制但我个人倾向于 第一个解决方案
注意:“选择@@Identity;”也会 工作得很好
谢谢大家,我希望它能帮助其他人!
I've have a form which accept various data (through textboxes and a checkboxlist) and on the click event they insert all the data into a table and selects the scope_identity then store it in a variable to use it in the insertion of the checkboxlist items using a loop into another table
according to many answers and examples this should work perfectly!..but it gives me this error :
Exception Details: System.InvalidCastException: Specified cast is not valid.
Line 66: int NewBrandId = (int)comm.ExecuteScalar();
Here's my linkbutton method code :
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();
}
}
}
Edit Strangely the query works fine when I run it directly in the sql server express of the visual studio!
THE Weird Explanation For This Weird Problem
First Solution by alexb :
I did it :) My sql server 2008 returns
System.Decimal packed into 'object'.
Try to use System.Convert.ToInt32
instead of cast.
Example : int NewBrandId = System.Convert.ToInt32(comm.ExecuteScalar());
Second Solution by me :
instead of using "SELECT
scope_identity();" I used "SELECT
BrandId FROM Brands WHERE BrandId =
@@Identity;" it gives you even more
controlm but I personally prefare the
first solutionN.B : "SELECT @@Identity;" would also
work just fine
Thanks guys and I hope it help others!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您可以更改 SQL,则更简单的方法是
If you can change the SQL, an even easier way would be to
comm.ExecuteScalar()
到底返回什么?也许它会返回打包到
object
中的long
或double
。记不太清楚了,但好像我一两年前就遇到过一些事情。
What exactly
comm.ExecuteScalar()
returns?Maybe it returns
long
ordouble
packed intoobject
.can't remember exactly, but seems like I had faced something 1-2 years ago.
正如 Dimi 所说,Identity 是一个 SQL 数字(.NET 十进制)。这应该有效:
As Dimi said, Identity is a SQL Numeric (.NET Decimal). This should work:
从 SCOPE_IDENTITY() 的文档中,
一个简单的解决方案如下
From the documentation for SCOPE_IDENTITY()
So an easy solution would be the following
尝试在插入之前添加
SET NOCOUNT ON;
。try adding
SET NOCOUNT ON;
before the insert.