【问题标题】:Inserting a byte array larger than 8k bytes插入大于 8k 字节的字节数组
【发布时间】:2014-03-01 06:35:16
【问题描述】:

我正在使用代码

cmd.Parameters.Add("@Array", SqlDbType.VarBinary).Value = Array;

SqlDbType.VarBinary 描述声明它最多只能处理数组的 8 K 字节。我有一个代表图像的字节数组,可以达到 10k 字节。

如何使用 C# 将其存储在 varbinary(max) 列中?

创建数组没有问题。尝试执行查询时,我被困在这个 8k 限制。

编辑:让我澄清一下,在我的机器上,当我在本地运行 asp.net 应用程序时,甚至高达 15k 字节的图片也会存储在数据库的 varbinary(MAX) 列中,但是一旦我部署它,图片就不会被存储。然后我采取了大幅调整图像大小以确保它们的大小小于 8K,现在图像可以毫无问题地存储。

【问题讨论】:

  • 为什么不把图片存到硬盘里,把路径存到db里呢?
  • SQL Server 的哪个版本?发生了一些变化。 (此外,如果您遇到错误,请确保包含确切的消息 - 这也将使其他人更容易找到问题,并且可能会找到重复项。)
  • 即使Modifying Large-Value (max) Data in ADO.NET 似乎对“如何”为 VARBINARY(MAX) 列执行此操作保持沉默..
  • 但是Working with Binary Large Objects (BLOBs) Using SQL Server and ADO.NET(它创建了一个参数对象首先,然后添加它,没有提到8k大小限制)..你确定 您最初提供的代码不起作用?如果没有,请发布错误/异常。
  • 我无法存储路径,因为我将从客户端机器接收图像,然后将其保存在服务器机器上。其次,当我使用大于 8 kb 的图像时,图像不会存储在我的数据库中。 (我使用 WCF 通过 silverlight 将图像传输到我的服务器,并且该过程完成没有任何问题)。

标签: c# sql sql-server varbinary


【解决方案1】:

也许您可以查看Sql Server FILESTREAM 功能,因为它用于存储文件。它基本上存储了指向您的文件的指针,并且文件直接存储在文件系统中(在数据库数据目录中)。

我喜欢 FILESTREAM,因为这意味着您将继续使用数据库接口(例如 SQLClient),而不是使用临时方法将文件读/写到硬盘驱动器。这意味着为您管理安全性,因为您的应用不需要特殊权限即可访问文件系统。

快速谷歌提供了this acticle 在 c# 中使用文件流,但我相信还有很多其他的。

OP EDIT 后更新

所以一旦部署到其他服务器上传失败?也许问题不在于 sql 插入,而是施加了 http 请求内容长度限制 - 例如,在您的 web.config 中, httpRuntime 元素具有 maxRequestLength 属性.如果将其设置为较低的值,那么这可能就是问题所在。所以你可以设置成这样(在 10kb 问题上将最大设置为 6MB):

<system.web>
    <httpRuntime maxRequestLength="6144" />

这里唯一的限制是 4MB 购买默认:|

【讨论】:

  • 虽然 FILESTREAM 是一种方便的新类型,但我不确定它是否适合这里(并且仅在 2008 年推出)。 OP 说最大数据约为 10k,这不是使用 FS 擅长的地方。 (FS 类型基本上比手动“存储文件名和读取文件”提供了一个更好的层。)
  • 是的,我错过了 10k 的限制,我读了“我存储图像”...我过去使用的方式是在数据库中使用混合存储,如果小于限制并使用文件流如果更大...
  • 我感兴趣的是:1.为什么 ADO.NET 中存在 VARBINARY(MAX) 限制(如果有的话是什么),或者 2.如果没有,为什么 OP 认为/报告他/她的程序有这样的限制。
  • @user2864740 在尝试不同尺寸(甚至大于 1.5MB)的图像时它对我有用gist.github.com/chrismoutray/9286664
  • 所以现在整个问题/前提都是可疑的。这些是最好的>_
【解决方案2】:

不,这是描述的实际内容:

字节类型的数组。可变长度的二进制数据流 1 到 8,000 字节之间。如果字节数组隐式转换失败 大于 8,000 字节。 工作时显式设置对象 字节数组大于 8,000 字节。

我假设这实际上意味着如果字节数组超过 8000 个元素,则不能使用 AddWithValue 来让参数推断类型为 VarBinary。您必须使用 Add,自己指定参数的类型,然后设置 Value 属性,即使用此:

command.Parameters.Add("@MyColumn", SqlDbType.VarBinary).Value = myByteArray;

而不是这样:

command.Parameters.AddWithValue("@MyColumn", myByteArray);

【讨论】:

  • “使用这个”是 OP 正在使用的。
【解决方案3】:

添加数据的长度似乎是解决办法

var dataParam = cmd.Parameters.AddWithValue("@Data", (object)data.Data ?? DBNull.Value);
                if (data.Data != null)
                {
                    dataParam.SqlDbType = SqlDbType.VarBinary;
                    dataParam.Size = data.Data.Length;
                }

【讨论】:

    猜你喜欢
    • 2012-10-18
    • 2018-03-02
    • 2014-10-25
    • 2019-05-23
    • 2015-05-24
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    相关资源
    最近更新 更多