IT貓撲網(wǎng):您身邊最放心的安全下載站! 最新更新|軟件分類|軟件專題|手機版|論壇轉(zhuǎn)貼|軟件發(fā)布

您當(dāng)前所在位置: 首頁數(shù)據(jù)庫MSSQL → 如何用VB存取SQL Server中的圖像數(shù)據(jù)

如何用VB存取SQL Server中的圖像數(shù)據(jù)

時間:2015-06-28 00:00:00 來源:IT貓撲網(wǎng) 作者:網(wǎng)管聯(lián)盟 我要評論(0)

本文介紹MIS SQL Server對圖像數(shù)據(jù)的存儲機制和存取方法。針對VB開發(fā)工具,介紹了一種通過ADO Field 對象的GetChunk 方法和AppendChunk 方法來存取MIS SQL Server中的圖像數(shù)據(jù)的方法。

在一個完善的醫(yī)院信息MIS中,圖像數(shù)據(jù)的存取是必不可少的,比如X光片、CT像片的保存。一方面,這些圖像數(shù)據(jù)在遠程診療為準(zhǔn)確診斷病情提供了重要的依據(jù),另一方面,也為快速查閱病人資料提供了基本條件。圖像數(shù)據(jù)的存取在其它應(yīng)用系統(tǒng)如GIS中也有廣泛的應(yīng)用。

1、 SQL Server中圖像數(shù)據(jù)的存儲機制

在MIS SQL Server 中,對于小于 8000 個字節(jié)的圖像數(shù)據(jù)可以用二進制型(binary、varbinary)來表示。但通常要保存的一些醫(yī)學(xué)影像圖片都會大于 8000個字節(jié)。SQL Server提供了一種機制,能存儲每行大到 2GB的二進制對象(BLOB),這類對象可包括image、text和ntext三種數(shù)據(jù)類型。Image數(shù)據(jù)類型存儲的是二進制數(shù)據(jù),最大長度是 231-1 (2,147,483,647)個字節(jié)。

BLOB數(shù)據(jù)在MIS SQL Server系統(tǒng)中的存儲方式不同于普通的數(shù)據(jù)類型,對于普通類型的數(shù)據(jù)系統(tǒng)直接在用戶定義的字段上存儲數(shù)據(jù)值,而對于BLOB類型數(shù)據(jù),系統(tǒng)開辟新的存儲頁面來存放這些數(shù)據(jù),表中BLOB類型數(shù)據(jù)字段存放的僅是一個16個字節(jié)的指針,該指針指向存放該條記錄的BLOB數(shù)據(jù)的頁面。

2、 SQL Server中圖像數(shù)據(jù)的存取

在MIS SQL Server中,當(dāng)數(shù)據(jù)小于 8000 個字節(jié)時,可以用普通的SQL操縱語句(SELECT、INSERT、UPDATE、DELETE)來完成對字段的操縱,當(dāng)數(shù)據(jù)大于8000個字節(jié)時,SQL提供了 WRITETEXT 、READTEXT和UPDATETEXT這三個函數(shù)來讀取和修改數(shù)據(jù)。這三個函數(shù)的使用方法為:

(1) WRITETEXT {table.column text_ptr}[WITH LOG] {data}

table.column為表中的字段,text_ptr為一個16個字節(jié)的指針,data為要寫的數(shù)據(jù)值??蛇x參數(shù)WITH LOG表示是否要寫入日志文件中。

例:

DECLARE @ptrval binary(16) --指針

SELECT @ptrval = TEXTPTR(img_ct) FROM zy_ct WHERE id_ct = 20010101001

WRITETEXT zy_ct.img_ct @ptrval 0x024324142342134214213421421454353452341

(2) READTEXT {table.column text_ptr offset size} [HOLDLOCK]

table.column為表中的字段,text_ptr為一個16個字節(jié)的指針,offset 為偏移量,即從第幾個字節(jié)開始讀數(shù)據(jù),size為要讀的字節(jié)數(shù),HOLDLOCK 為在讀數(shù)據(jù)中是否充許其他用戶修改該數(shù)據(jù)。

例:

DECLARE @ptrval varbinary(16)

SELECT @ptrval = TEXTPTR(img_ct) FROM zy_ct WHERE id_ct = 20010101001

READTEXT zy_ct.img_ct @ptrval 1 25

(3) UPDATETEXT

{table_name.dest_column_name dest_text_ptr}

{NULL|insert_offset}{ NULL | delete_length}

[WITH LOG][ inserted_data|

{table_name.src_column_name src_text_ptr}]

table_name.dest_column_name 為要修改的text, ntext, 或 image字段;dest_text_ptr為指向其的指針;insert_offset為偏移量,對于text和image為從第幾開始字節(jié)開始寫,對于ntext為從第幾個字符(雙字節(jié))開始寫;delete_length為從insert_offset開始刪除delete_length長度的字節(jié)(符),為0時不刪除,為NULL時為刪除從insert_offset開始到結(jié)束的所有數(shù)據(jù)。要插入的數(shù)據(jù)為 inserted_data為,也可是表table_name的src_column_name字段中指針 src_text_ptr所指數(shù)據(jù)。

例:

DECLARE @ptrval binary(16)

SELECT @ptrval = TEXTPTR(img_ct) FROM zy_ct WHERE id_ct = 20010101001

UPDATETEXT zy_ct.img_ct @ptrval 16 0x54345

可以看出,這三個函數(shù)的使用比較復(fù)雜,雖然可以通過生成存貯過程來調(diào)用執(zhí)行,但有一個缺陷是在讀取數(shù)據(jù)時,READTEXT函數(shù)讀取的數(shù)據(jù)無法直接傳遞回前端應(yīng)用程序。

3、 VB 6.0中圖像數(shù)據(jù)的存取

VB 6.0 的ADO Field 對象提供了GetChunk 方法和AppendChunk 方法來存取BLOB數(shù)據(jù),這兩個函數(shù)實質(zhì)是通過API調(diào)用WRITETEXT 、READTEXT和UPDATETEXT這三個函數(shù),簡化了調(diào)用的方法。

(1)GetChunk 和AppendChunk方法介紹

GetChunk 方法檢索其部分或全部長二進制或字符數(shù)據(jù)。GetChunk 調(diào)用返回的數(shù)據(jù)將賦給"變量"。如果 Size 大于剩余的數(shù)據(jù),則 GetChunk 僅返回剩余的數(shù)據(jù)而無需用空白填充"變量"。如果字段為空,則 GetChunk 方法返回 Null。每個后續(xù)的 GetChunk 調(diào)用將檢索從前一次 GetChunk 調(diào)用停止處開始的數(shù)據(jù)。但是,如果從一個字段檢索數(shù)據(jù)然后在當(dāng)前記錄中設(shè)置或讀取另一個字段的值,ADO 將認(rèn)為已從第一個字段中檢索出數(shù)據(jù)。如果在第一個字段上再次調(diào)用 GetChunk 方法,ADO 將把調(diào)用解釋為新的 GetChunk 操作并從記錄的起始處開始讀取。Field 對象的第一個 AppendChunk 調(diào)用將數(shù)據(jù)寫入字段,覆蓋所有現(xiàn)有的數(shù)據(jù),隨后的 AppendChunk 調(diào)用則添加到現(xiàn)有數(shù)據(jù)。

由于系統(tǒng)資源總是有限的,如果一次讀(存)取大量數(shù)據(jù),可能會引起服務(wù)器、客戶機死機或是服務(wù)器的性能大大下降,因此使用這兩個函數(shù)時,要將圖像數(shù)據(jù)進行分段讀寫。

(2)程序?qū)崿F(xiàn)

程序一:寫數(shù)據(jù)函數(shù)

Public Function AppendBlobFromFile

(blobColumn As ADODB.Field, ByVal FileName) As Boolean

Dim FileNumber As Integer '文件號

Dim DataLen As Long '文件長度

Dim Chunks As Long '數(shù)據(jù)塊數(shù)

Dim ChunkAry() As Byte '數(shù)據(jù)塊數(shù)組

Dim ChunkSize As Long '數(shù)據(jù)塊大小

Dim Fragment As Long '零碎數(shù)據(jù)大小

Dim lngI As Long '計數(shù)器

On Error GoTo ErrorHandle

AppendBlobFromFile = False

ChunkSize = 2048 '限制每次讀取的塊大小為 2K

FileNumber = FreeFile '產(chǎn)生隨機的文件號

Open FileName For Binary Access Read As FileNumber '打開圖像文件

DataLen = LOF(FileNumber) '獲得文件長度

If IsNull(blobColumn) Then Exit Function

If DataLen = 0 Then '文件長度為0

Close FileNumber

AppendBlobFromFile = True

Exit Function

End If

Chunks = DataLen \ ChunkSize '數(shù)據(jù)塊的個數(shù)

Fragment = DataLen Mod ChunkSize

If Fragment > 0 Then '先寫零碎數(shù)據(jù)

ReDim ChunkAry(Fragment - 1)

Get FileNumber, , ChunkAry() '讀出文件

blobColumn.AppendChunk ChunkAry '調(diào)用AppendChunk函數(shù)寫數(shù)據(jù)

End If

ReDim ChunkAry(ChunkSize - 1) '為數(shù)據(jù)塊開辟空間

For lngI = 1 To Chunks '循環(huán)讀出所有數(shù)據(jù)塊

Get FileNumber, , ChunkAry() '讀出一塊數(shù)據(jù)

blobColumn.AppendChunk ChunkAry '在數(shù)據(jù)庫中增加數(shù)據(jù)塊

Next lngI

Close FileNumber '關(guān)閉文件

AppendBlobFromFile = True

Exit Function

ErrorHandle:

AppendBlobFromFile = False

MsgBox Err.Description, vbCritical, "寫圖像數(shù)據(jù)出錯!"

End Function

程序二:讀數(shù)據(jù)函數(shù)

Public Function ReadbolbToFile

(blobColumn As ADODB.Field, ByVal FileName) As Boolean

Dim FileNumber As Integer '文件號

Dim DataLen As Long '文件長度

Dim Chunks As Long '數(shù)據(jù)塊數(shù)

Dim ChunkAry() As Byte '數(shù)據(jù)塊數(shù)組

Dim ChunkSize As Long '數(shù)據(jù)塊大小

Dim Fragment As Long '零碎數(shù)據(jù)大小

Dim lngI As Long '計數(shù)器

On Error GoTo ErrorHandle

ReadbolbToFile= False

ChunkSize = 2048 '定義塊大小為 2K

If IsNull(blobColumn) Then Exit Function

DataLen = blobColumn.ActualSize '獲得圖像大小

If DataLen < 8 Then Exit Function '圖像大小小于8字節(jié)時認(rèn)為不是圖像信息

FileNumber = FreeFile '產(chǎn)生隨機的文件號

Open FileName For Binary Access Write As FileNumber '打開存放圖像數(shù)據(jù)文件

Chunks = DataLen \ ChunkSize '數(shù)據(jù)塊數(shù)

Fragment = DataLen Mod ChunkSize '零碎數(shù)據(jù)

If Fragment > 0 Then '有零碎數(shù)據(jù),則先讀該數(shù)據(jù)

ReDim ChunkAry(Fragment - 1)

ChunkAry = blobColumn.GetChunk(Fragment)

Put FileNumber, , ChunkAry '寫入文件

End If

ReDim ChunkAry(ChunkSize - 1) '為數(shù)據(jù)塊重新開辟空間

For lngI = 1 To Chunks '-循環(huán)讀出所有塊

ChunkAry = blobColumn.GetChunk(ChunkSize) '在數(shù)據(jù)庫中連續(xù)讀數(shù)據(jù)塊

Put FileNumber, , ChunkAry() '將數(shù)據(jù)塊寫入文件中

Next lngI

Close FileNumber '關(guān)閉文件

ReadbolbToFile= True

Exit Function

ErrorHandle:

ReadbolbToFile= False

MsgBox Err.Description, vbCritical, "讀圖像數(shù)據(jù)出錯!"

End Function

當(dāng)BLOB類型的字段為空時,調(diào)用AppendChunk或 GetChunk函數(shù)將出錯。此時如果想給該字段插入圖像數(shù)據(jù),應(yīng)該先使用 Update語句給該字段賦初值如0x0,以便數(shù)據(jù)庫系統(tǒng)為該字段分配一個頁面地址來存放BLOB數(shù)據(jù)。

4、 總結(jié)

Microsoft SQL Server為保存大二進制數(shù)據(jù)提供了存儲平臺,Visual Basic 6.0為存取這種數(shù)據(jù)提供了靈活的接口。本文介紹的用VB接口存取 MIS SQL Server中大二進制數(shù)據(jù)的方法,不但適用于圖像文件,同樣適用于其它類型的文件。該方法應(yīng)用于醫(yī)院管理系統(tǒng)的圖像存取中,在存取速度、對系統(tǒng)的

關(guān)鍵詞標(biāo)簽:SQL Server

相關(guān)閱讀

文章評論
發(fā)表評論

熱門文章 淺談JSP JDBC來連接SQL Server 2005的方法 淺談JSP JDBC來連接SQL Server 2005的方法 SqlServer2005對現(xiàn)有數(shù)據(jù)進行分區(qū)具體步驟 SqlServer2005對現(xiàn)有數(shù)據(jù)進行分區(qū)具體步驟 sql server系統(tǒng)表損壞的解決方法 sql server系統(tǒng)表損壞的解決方法 MS-SQL2005服務(wù)器登錄名、角色、數(shù)據(jù)庫用戶、角色、架構(gòu)的關(guān)系 MS-SQL2005服務(wù)器登錄名、角色、數(shù)據(jù)庫用戶、角色、架構(gòu)的關(guān)系

相關(guān)下載

    人氣排行 配置和注冊O(shè)DBC數(shù)據(jù)源-odbc數(shù)據(jù)源配置教程 如何遠程備份(還原)SQL2000數(shù)據(jù)庫 SQL2000數(shù)據(jù)庫遠程導(dǎo)入(導(dǎo)出)數(shù)據(jù) SQL2000和SQL2005數(shù)據(jù)庫服務(wù)端口查看或修改 修改Sql Server唯一約束教程 SQL Server 2005降級到2000的正確操作步驟 sql server系統(tǒng)表損壞的解決方法 淺談JSP JDBC來連接SQL Server 2005的方法