【问题标题】:How do I select just a portion of huge binary (file)?如何只选择一部分巨大的二进制文件(文件)?
【发布时间】:2012-11-26 12:03:12
【问题描述】:

我的问题是:我有可能将巨大的文件存储在 SQL Server 2008 (> 1GB) 上的二进制(图像)字段中。

如果我使用常规 select 语句返回整个二进制文件,则查询需要一分钟以上才能将结果返回到我的 .NET 程序,并且我的客户端应用程序会超时。我正在寻找的是 TSQL 代码,它将限制返回的数据大小(可能是 300mb),允许我遍历剩余的块并防止超时。

这必须发生在 SQL 查询中,而不是在数据返回后的处理中。

我试过 SubString,MS 说它适用于二进制数据,但我得到的只是最大 8000 字节。我尝试的最后一件事是这样的:

select substring(Package,0,300000000) 'package', ID from rplPackage where ID=0
--where package is the huge binary stored in a image field

数据流也不是一个真正的选择,因为客户端应用程序。

有什么想法吗?

【问题讨论】:

  • 您应该重新计算,将文件存储为数据库 BLOBS 是否真的满足您的需求:将文件作为文件存储并仅将其路径和元数据存储在数据库中可能会更好。经验法则是:如果数据库不能“理解”文件的内容,请考虑将其移出。
  • @EugenRieck 来吧,根据理解的论点,甚至不应该有二进制数据类型。
  • 有一些用例(想想穷人的共享 FS),但 OQ 很清楚地表明,这里 BLOB 并不是一个完美的解决方案

标签: sql sql-server sql-server-2008 tsql blob


【解决方案1】:

好的,我想通了。做到这一点的方法是使用 substring 函数,MS 准确地说它适用于二进制文件。他们没有说的是 substring 只会返回 8,000 字节,这就是让我震惊的地方。

换句话说,如果 blob 数据类型是图像并且你使用这个:

 select substring(BlobField,0,100000000) 
 from TableWithHugeBlobField
 where ID = SomeIDValue

 --all you'll get is the first 8K bytes (use DataLength function to get the size)

但是,如果您声明一个变量 varbinary(max) 并且 blob 字段数据类型是 varbinary(max) - 或某个对您有用的大小 - 然后使用 substring 函数将部分二进制带回您的变量宣布。这工作得很好。就像这样:

 Declare @PartialImage varbinary(max) 
 select @PartialImage = substring(BlobField, 0, 100000000) --1GB
 from TableWithHugeBlobField
 where ID = SomeIDValue

 select DataLength(@PartialImage) -- should = 1GB

前面提过问题,为什么要使用SQL来存储文件数据?这是一个有效的问题;想象一下,您必须将数据作为文件复制到数百个不同的客户端设备(如 iPhone),每个包都是独一无二的,因为不同的客户端有不同的需求,然后将文件包作为 blob 存储在数据库上更容易编程与以编程方式挖掘文件夹以找到正确的包以流式传输到客户端相比。

【讨论】:

  • 对于子字符串,第一个字节是 1 而不是 0。
【解决方案2】:

使用这个:

select substring(*cast(Package as varbinary(max))*,0,300000000) 'package', ID  
from rplPackage 
where ID=0

【讨论】:

  • 发表评论以解释上述如何回答问题对 OP 和任何未来的访问者都有好处。
【解决方案3】:

考虑使用 FileStream

FILESTREAM Overview

Managing FILESTREAM Data by Using Win32

sqlFileStream.Seek(0L, SeekOrigin.Begin);

numBytes = sqlFileStream.Read(buffer, 0, buffer.Length);

【讨论】:

  • Blam ... 感谢您的意见。我会看看那个星期一,看看它是否对我有用。我现在很绝望。
  • 抱歉,Blam,但这行不通。我没有从文件系统中读取。这些文件已作为记录存储在数据库中,以便更轻松地将数据复制到客户端应用程序。正如我上面所说,流媒体也不起作用。解决方案需要在 TSQL 中。
猜你喜欢
  • 2017-06-18
  • 2011-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-02
  • 1970-01-01
  • 2015-06-02
  • 1970-01-01
相关资源
最近更新 更多