在網(wǎng)上看到了不少介紹
VB
如何在
SQL SERVER
中存取圖片數(shù)據(jù)的文章。
經(jīng)自己實(shí)現(xiàn)后,最終把心得拿出來(lái)和大家分享。
?
經(jīng)
GOOGLE
搜索,網(wǎng)上的對(duì)數(shù)據(jù)庫(kù)圖片進(jìn)行存儲(chǔ)的文章,絕大部分是來(lái)自一篇。都是采用
ADO Stream
方法使用
field
對(duì)象的
AppendChunk
和
GetChunk
方法將大容量的二進(jìn)制數(shù)組通過(guò)
Update
存儲(chǔ)到數(shù)據(jù)庫(kù)中。
?
Dim Conn as ADODB.Connection???? '
聲明
Connection
對(duì)象
Dim Rs as ADODB.RecordSet??? '
聲明
RecordSet
對(duì)象
CONST BLOCKSIZE=4096??? '
定義緩沖區(qū)塊大小
?
Set Conn = New ADODB.Connection
Conn.ConnectionString = " DATA SOURCE = PUBS "??? 'ODBS
數(shù)據(jù)源名稱為
PUBS
Conn.Open
Set Rs = New ADODB.RecordSet
Rs.Open "test", Conn, adOpenKeyset, adLockOptimistic??? '
數(shù)據(jù)庫(kù)表為
"test"
?
Dim Data() as Byte???? '
聲明字節(jié)型數(shù)組,存放數(shù)據(jù)庫(kù)圖片信息
Dim FileLength as Integer??? '
文件長(zhǎng)度變量
Dim BlockNum as Integer???? '
存放緩沖區(qū)塊的個(gè)數(shù)
Dim DataLeft as Integer????? '
存放取整塊后的遺留信息
?
Open "C:\TEST.BMP" for BINARY as #1??? '
假設(shè)圖片文件為
C:\TEST.BMP
Dim i as Integer
FileLength = LOF(1)
BlockNum = FileLength \ BLOCKSIZE????? '
整取塊大小,得緩沖區(qū)塊數(shù)
DataLeft = FileLength Mod BLOCKSIZE???? '
整塊取后的遺留
ReDim Data(BLOCKSIZE)??? '
重新定義緩沖區(qū)塊大小為
BLOCKSIZE
For i=1 to BlockNum
?????? Get #1,,Data()
?????? Rs(0).AppenChunk Data()??? '
將
Data()
復(fù)制至
Rs(0)
字段,假設(shè)
test
表中的
image
為第一字段
Next i
ReDim Data(DataLeft)??? '
重新定義塊大小取得遺留信息
Get #1,,Data()
Rs(0).AppendChunk Data()???? '
此時(shí)圖片信息已全部拷貝至當(dāng)前記錄
Rs(0)
字段
Close #1
...
Rs.UpDate
?
具體的存儲(chǔ)方法如上所述。
?
下面將簡(jiǎn)單的介紹取出信息的方法:
???
介紹說(shuō),將圖片二進(jìn)制存儲(chǔ)信息用
GetChunk
方法取出,將其存儲(chǔ)為臨時(shí)文件即可。
REM??
設(shè)
Rs
為打開(kāi)的數(shù)據(jù)庫(kù)表對(duì)應(yīng)的
RecordSet
對(duì)象,其中的
image
對(duì)象仍然為第一字段
REM??
接著上面的思路
?
Dim Data() as Byte??? ?'
聲明字節(jié)型數(shù)組,存放數(shù)據(jù)庫(kù)圖片信息
Dim FileLength as Integer??? '
文件長(zhǎng)度變量
Dim BlockNum as Integer???? '
存放緩沖區(qū)塊的個(gè)數(shù)
Dim DataLeft as Integer????? '
存放取整塊后的遺留信息
Dim i as Integer
ReDim Data(BLOCKSIZE)
Open "C:\TMP.BMP" for BINARY as #1
FileLength = Rs(0).ActualSize
BlockNum = FileLength \ BLOCKSIZE
DataLeft = FileLength Mod BLOCKSIZE
ReDim Data(BLOCKSIZE)
For i = 1 to BlockNum
?????? Data() = Rs(0).GetChunk(BLOCKSIZE)??? 'GetChuk
方法有一個(gè)參數(shù)為
Size
Next i
Put #1,,Data()
ReDim Data(DataLeft)
Data() = Rs(0).GetChunk(DataLeft)
Put #1,,Data()
Close #1
?
關(guān)于存取的內(nèi)容全部于上面已經(jīng)列出,組織的方法還請(qǐng)各位網(wǎng)友自行去組織一下。
如果有什么缺乏說(shuō)明或是不正確的地方,還請(qǐng)各位能夠指出。
?
對(duì)于此問(wèn)題的實(shí)現(xiàn),本人還有一個(gè)設(shè)想,打算利用
SQL SERVER
的服務(wù)器端來(lái)實(shí)現(xiàn)存儲(chǔ)過(guò)程,使得客戶端的存取數(shù)據(jù)庫(kù)圖片信息更加方便。
具體的實(shí)現(xiàn)可能還得努力等看書(shū)之后,期待中
......
后記:
在具體存儲(chǔ)過(guò)程中,遇到了一個(gè)關(guān)于Rs的屬性長(zhǎng)度的問(wèn)題,原先采用的是Len(Rs(0))[Rs(0)為image對(duì)象],但測(cè)試時(shí)總是缺少一半的字符長(zhǎng)度,后來(lái)查明對(duì)于Byte型數(shù)組進(jìn)行Len()求值時(shí),只會(huì)取到一半的數(shù)值。如:
Dim?a(4096)?as Byte
Msgbox Len(a())
結(jié)果是:2048
原因分析:可能跟VB中Len函數(shù)的ANSI或是UniCODE有關(guān)。但是了準(zhǔn)確的原因還沒(méi)有查出,因?yàn)闀r(shí)間關(guān)系,暫時(shí)還不能去做,到時(shí)查出后再附上。