什么是从数据类型nvarchar(max)到varbinary(max)的隐式转换是不允许的意思以及如何修复它?

时间:2017-03-28 15:15:52

标签: c# sql-server winforms

我正在尝试使用图片框和c#windows窗体应用程序上的保存按钮将图像保存到我的sql数据库。这是我用来保存图像的代码:

private void btnsave_Click(object sender, EventArgs e)
{
   MemoryStream ms = new MemoryStream();
   pictureBox2.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
   Byte[] picarray = ms.ToArray();
   String picbase64 = Convert.ToBase64String(picarray);

   SqlConnection con = new SqlConnection("Data Source=LAPTOP-EUNPD14B;Initial Catalog=db;Integrated Security=True");

   SqlCommand cmd = new SqlCommand();
   con.Open();
   cmd.CommandType = CommandType.Text;

   cmd.CommandText = @"INSERT INTO tblreport([entrynum],[reportdate],[reporttime],[vicfirstname],[viclastname],[vicmidname], [vicage],[vicgender],[vicaddress],[incident],[time],[date],[place],[casefiled],[susfirstname],[suslastname],[susmidname],[susage],[susgender],[susaddress],[suspic]) VALUES(@value1,@value2,@value3,@value4,@value5,@value6,@value7,@value8,@value9,@value10,@value11,@value12,@value13,@value14,@value15,@value16,@value17,@value18,@value19,@value20,@value21)";

   cmd.Parameters.AddWithValue("@value1", entryno.Text);
   cmd.Parameters.AddWithValue("@value2", dtreport.Text);
   cmd.Parameters.AddWithValue("@value3", timereport.Text);
   cmd.Parameters.AddWithValue("@value4", txtcomfirst.Text);
   cmd.Parameters.AddWithValue("@value5", txtcomlast.Text);
   cmd.Parameters.AddWithValue("@value6", txtcommid.Text);
   cmd.Parameters.AddWithValue("@value7", txtcomage.Text);
   cmd.Parameters.AddWithValue("@value8", cbocomgen.Text);
   cmd.Parameters.AddWithValue("@value9", txtcomaddress.Text);
   cmd.Parameters.AddWithValue("@value10", txtincident.Text);
   cmd.Parameters.AddWithValue("@value11", timeincident.Text);
   cmd.Parameters.AddWithValue("@value12", dtincident.Text);
   cmd.Parameters.AddWithValue("@value13", txtincidentplace.Text);
   cmd.Parameters.AddWithValue("@value14", txtcase.Text);
   cmd.Parameters.AddWithValue("@value15", susfirst.Text);
   cmd.Parameters.AddWithValue("@value16", suslast.Text);
   cmd.Parameters.AddWithValue("@value17", susmid.Text);
   cmd.Parameters.AddWithValue("@value18", susage.Text);
   cmd.Parameters.AddWithValue("@value19", cbosusgender.Text);
   cmd.Parameters.AddWithValue("@value20", susadd.Text);
   cmd.Parameters.AddWithValue("@value21", picbase64);
   cmd.Connection = con;

   cmd.ExecuteNonQuery();
   MessageBox.Show("Report Saved");

   con.Close();
}

当我使用的数据类型是Varchar但是图片不会在datagridview上显示时代码工作,所以我在发生错误后将数据类型更改为varbinary。

这是错误:

  

System.Data.dll中出现未处理的“System.Data.SqlClient.SqlException”类型异常

     

其他信息:不允许从数据类型nvarchar(max)到varbinary(max)的隐式转换。使用CONVERT函数运行此查询。

enter image description here

请帮帮我!谢谢!

2 个答案:

答案 0 :(得分:1)

当您使用AddWithValue()时,它会根据您传递的参数类型采用数据库列类型。

您将图片转换为base64字符串,在.NET中作为Unicode字符存储在内部,并作为nvarchars存储在数据库中。当您将此参数添加到参数时,它假定您要存储文本字符,这将是nvarchar,但真正的数据库类型是varbinary,正如错误所示,它们之间没有隐式转换。您希望将字节数组保存到字段中,而不是将其转换为base64。

我还应该提一下,在数据库中存储除了非常小的图片之外,通常效率不高。在大多数情况下,最好只存储图片的名称并将其保存在磁盘上。如果你坚持将它们存储在数据库中,那么你应该为你的blob创建一个单独的表。

答案 1 :(得分:0)

你的@ value21是一个字符串,请检查数据库上的那一列,如果它是nvarbinary(max),请将数据类型更改为nvarchar(max)以保存它,如@Bridge在上一个答案的注释中所述,尝试指定数据类型