2012-12-08 50 views
5

我的問題是這樣的:我有可能將巨大的文件存儲在SQL Server 2008(> 1GB)上的二進制(圖像)字段中。如何只選擇一部分巨大的二進制文件?

如果我使用常規選擇語句返回整個二進制文件,則查詢花費的時間超過一分鐘會將結果返回到我的.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 

由於客戶端應用程序的原因,數據流並不是一個真正的選項。

任何想法?

+0

你應該reecaluate,無論是存儲文件,數據庫中的BLOB真正適合您的需要:這可能只是更好地Stroe的文件的文件,並只保存在數據庫的路徑和元數據。經驗法則是:如果數據庫不「理解」文件的**內容**,請考慮將其移出。 –

+0

@EugenRieck來吧,理解的參數甚至不應該是一個二進制數據類型。 – Paparazzi

+0

有一些用例(認爲窮人的共享FS),但是OQ顯示得相當清楚,BLOB在這裏不是一個完美的解決方案。 –

回答

0

考慮使用的FileStream

FILESTREAM Overview

Managing FILESTREAM Data by Using Win32

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

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

Blam ...感謝您的意見。我會在星期一看看它是否適合我。我在這一點上絕望。 – Brian

+0

對不起,Blam,但那不行。我沒有從文件系統讀取數據。這些文件已經作爲記錄存儲在數據庫中,以便使數據複製更容易進行到客戶端應用程序。正如我上面所說的,流式傳輸也不行。 解決方案需要在TSQL內。 – Brian

5

OK,我想它了。要做到這一點的方法是使用子字符串函數,MS準確地說這是與二進制文件一起工作的。他們沒有說的是,子字符串將只返回8,000字節,這是扔給我的東西。

換句話說,如果斑數據類型爲圖像,並且使用此:

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(最大)的一個變量,並且所述斑點字段數據類型爲VARBINARY(最大) - 或者對你有用的一些大小 - 然後使用子字符串函數將部分二進制返回到你聲明的變量中。這工作得很好。就像這樣:

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

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

問題提出之前,爲什麼使用SQL來存儲文件數據?這是一個有效的問題;想象你不得不將數據作爲文件複製到數百個不同的客戶端設備(如iPhone),每個包都是獨一無二的,因爲不同的客戶端有不同的需求,然後將文件包作爲blob存儲在數據庫上比編程更容易而不是通過編程方式挖掘文件夾以找到正確的包流到客戶端。

+2

對於子字符串,第一個字節是1而不是0. – DavidsAlias

1

使用此:

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

留下評論以解釋上述如何回答問題對OP和任何未來的訪問者都有益。 – SnareChops