如何将图像存储到varbinary(max)列?

我在将一个Image插入sql server 2008时遇到了这个以下的SQLexception。

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

在数据库中,Image列的数据类型是Varbinary(MAX)。

编辑

代码解除了评论

paramaters.Add(getParam("@imageFilePath", DbType.AnsiString, imageFilePath)); 

使用它将文件读入字节数组:

  // Old fashioned way public static byte[] ReadFile(string filePath) { byte[] buffer; FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); try { int length = (int)fileStream.Length; // get file length buffer = new byte[length]; // create buffer int count; // actual number of bytes read int sum = 0; // total number of bytes read // read until Read method returns 0 (end of the stream has been reached) while ((count = fileStream.Read(buffer, sum, length - sum)) > 0) sum += count; // sum is a buffer offset for next reading } finally { fileStream.Close(); } return buffer; } 

要么

  // Thanks Magnus! byte[] data = System.IO.File.ReadAllBytes(filePath); 

然后使用此保存图像数据(我使用的图像类“实例”包含我在instance.Data中的图像信息和字节数组):

  using(SqlCommand cm = new SqlCommand("SaveImage", connection, transaction)){ cm.CommandType = CommandType.StoredProcedure; cm.Parameters.Add(new SqlParameter("@Id", SqlDbType.Int,0, ParameterDirection.InputOutput, false, 10, 0, "Id", DataRowVersion.Current, (SqlInt32)instance.Id)); cm.Parameters.Add(new SqlParameter("@Title", SqlDbType.NVarChar,50, ParameterDirection.Input, false, 0, 0, "Title", DataRowVersion.Current, (SqlString)instance.Title)); if (instance.Data.Length > 0) { cm.Parameters.Add(new SqlParameter("@Data", SqlDbType.VarBinary,instance.Data.Length, ParameterDirection.Input, false, 0, 0, "Data", DataRowVersion.Current, (SqlBinary)instance.Data)); } else { cm.Parameters.Add(new SqlParameter("@Data", SqlDbType.VarBinary,0, ParameterDirection.Input, false, 0, 0, "Data", DataRowVersion.Current, DBNull.Value)); } cm.ExecuteNonQuery(); ) 

这是一个示例存储过程:

 CREATE PROCEDURE SaveImage ( @Id int OUTPUT ,@Title nvarchar(50) ,@Data varbinary(MAX) ) AS SET NOCOUNT ON SET XACT_ABORT ON IF @Id IS NULL OR @Id <= 0 BEGIN SELECT @Id = ISNULL(MAX([Id]),0) + 1 FROM [dbo].[Images] END INSERT INTO [dbo].[Images] ( [Id] ,[Title] ,[Data] ) VALUES ( @Id ,@Title ,@Data ) 

您收到错误是因为您尝试将文本插入varbinary(max)列; 因此,您不是存储图像而是存储PATH到图像。

如果您只想存储PATH ,请将列类型从varbinary(max)更改为varchar(max)如果您确实要存储IMAGE BYTES,那么您需要代码从文件中读取图像作为字节数组,然后您像这样插入数据:

 byte [] buffer = File.ReadAllBytes("Path/to/your/image/"); ... SqlCommand command = .... command.CommandType=CommandType.StoredProcedure; command.Parameters.AddWithValue("@image",buffer); command.ExecuteNonQuery(); 

要么

 SqlCommand command = .... command.Text="INSERT INTO YOUR_TABLE_NAME (image) values (@image)"; command.Parameters.AddWithValue("@image",buffer); command.ExecuteNonQuery(); 

您似乎正在尝试将图像数据设置为设置为NVARCHAR(基本文本)数据类型的列。 将图像数据设置为VARBINARY(MAX)的正确列 – 或者如果该列尚不存在,则将该列添加到表中。 或者,您可以通过ALTER TABLE命令将当前使用的列更改为VARBINARY(MAX)数据类型,如果它确实是正确的列,并且它刚刚创建时使用了错误的数据类型。

看看这两篇文章:

  • 通过ASP.Net MVC从SQL Server下载和上载图像
  • FILESTREAM MVC:从SQL Server下载和上传图像

它们不仅展示了如何做,而且展示了如何使用流语义有效地完成它。 将整个映像加载到内存byte []中的天真解决方案将在ASP进程中消耗太多内存。 显示的代码使用MVC,但您可以轻松地将其调整为APS表单。