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

时间:2011-09-06 18:05:07

标签: c# sql sql-server sql-server-2008

在将图像插入sql server 2008时,我得到了这个以下的SQL异常。

  

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

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

修改

代码取消评论

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

4 个答案:

答案 0 :(得分:13)

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

    // 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
)

答案 1 :(得分:4)

您收到错误是因为您尝试将文本插入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();

答案 2 :(得分:2)

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

答案 3 :(得分:1)

看看这两篇文章:

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