摘 要:本文介紹了Microsoft SQL Server中大型二進制對象數據的存取機制,針對Delphi開發工具,介紹了一種通過文件流來存取Microsoft SQL Server中的圖像數據的方法。
關鍵詞:大型二進制對象 image數據類型 文件流 數據庫引擎
一、引言
隨著信息技術的發展,越來越多的系統中需要存取圖像數據,而對于圖像數據的保存有兩種方法:一種是將圖像數據以文件形式存放在磁盤中,在數據庫中只存儲這些文件的路徑和文件名;另一種是將圖像數據和其他數據一樣直接存儲在數據庫中。當要處理大量圖像數據時,把圖像數據直接存儲在數據庫中有許多優點:
易于管理 當圖像數據與其他數據一起存儲在數據庫中時,圖像數據與其他數據是一起備份和恢復的,這樣就減少了圖像數據與其他數據不同步的機會,也降低了其他用戶無意中刪除了文件系統中圖像數據文件的風險。另外,由于圖像數據與其他數據一起存儲在數據庫中,其插入、更新和刪除可在同一個事務中實現,確保了數據的一致性。
可伸縮性 盡管文件系統被設計為能夠處理大量不同大小的對象,但是文件系統不能對大量小文件進行優化。在這種情況下,數據庫系統可以進行優化。
可用性 數據庫復制允許在分布式環境中復制、分配和潛在地修改數據。在主系統失效的情況下,日志轉移提供了保留數據庫備用副本的方法。
因此,要真正做到各類數據在數據庫中安全管理,研究和探索直接將圖像數據存儲在數據庫中的方法是非常必要的。
二、 Microsoft SQL Server 系統中的 BLOB 數據及其存取機制
BLOB(binary large object,大型二進制對象)數據類型主要用于保存多媒體對象,比如圖像、視頻和聲音。在Microsoft SQL Server系統中,BLOB可以是text、ntext或image數據類型。其中,image 數據類型用來存儲變長的二進制數據,最大長度是2GB,非常適合存儲圖像數據。
BLOB數據在Microsoft SQL Server系統中的存儲方式不同于普通的數據類型,對于普通類型的數據系統直接在用戶定義的字段上存儲數據值,而對于BLOB類型數據,系統開辟新的存儲頁面來存放這些數據,表中BLOB類型數據字段存放的僅是一個16字節的指針,該指針指向存放該條記錄的BLOB數據的頁面。
在Microsoft SQL Server系統中,當數據小于 8000 字節時,可以用普通的SQL語句(SELECT、INSERT、UPDATE、DELETE)來完成對數據的查詢操縱,當數據大于8000字節時,Microsoft SQL Server提供了 WRITETEXT 、READTEXT和UPDATETEXT這三個函數來讀取和修改數據。這三個函數的使用比較復雜,以 READTEXT 為例,其一般形式為
READTEXT {table.column text_ptr offset size} [HOLDLOCK]
其中,table.column為表中的字段,text_ptr為一個16字節的指針,offset 為偏移量,即從第幾個字節開始讀數據,size為要讀的字節數,HOLDLOCK 為在讀數據時是否允許其他用戶修改該數據。
例:DECLARE @ptrval varbinary(16)
SELECT @ptrval = TEXTPTR(img_ct) FROM zy_ct WHERE id_ct = 20010101001
READTEXT zy_ct.img_ct @ptrval 1 25
但是READTEXT函數讀取的數據無法直接傳遞回前端應用程序,本文將介紹一種使用Delphi存取Microsoft SQL Server 系統中圖像數據的簡單方法。在SQL Server 系統中建立表TEST,表中的字段及屬性見表1。
表1 TEST的字段及屬性
三、使用Delphi存取Microsoft SQL Server中的圖像數據
圖像數據的存儲格式有很多種類,常見的有BMP、JPEG、GIF等等,如果按照每種格式去單獨編寫存取代碼,就會使問題復雜化。但是,不論哪種格式的存盤文件,都可以看成文件“流”的形式。Delphi中的TFileStream數據類型以流的形式對字符或非字符數據進行處理,就像在內存中開辟了一個大小可變的臨時緩存區。它不僅能方便地對外部文件進行讀寫,而且還可以將流中的全部數據直接轉入數據庫,可用它作橋梁完成圖像數據的存取。
(一)數據集組件的選擇
在Delphi 連接數據庫的BDE方式中,通常數據集組件可以選擇TTable或TQuery,如果使用TQuery組件存取image類型數據,不可避免地就要使用WRITETEXT 、READTEXT和UPDATETEXT這三個函數,不便于程序實現。而選擇TTable組件,就可利用Delphi的強大數據引擎功能,自動完成image類型數據的存取。
(二)將圖像數據保存到Microsoft SQL Server中
下面程序的功能是使用TFileStream讀取圖像文件“ c:\source.jpg ”,再轉儲到String中,然后利用TTable組件將String中的圖像數據存儲到數據庫中。
procedure TForm1.SaveToDBClick(Sender: TObject);
var
FS: TFileStream;
ImageStr: String;
PImageStr: PChar;
begin
FS := TFileStream.Create('c:\source.jpg', fmOpenRead); //讀取圖像文件
FS.Seek(0, soFromBeginning);
SetLength(ImageStr, FS.Size);
PImageStr := PChar(ImageStr);
FS.Read(PImageStr^, FS.Size); //將TFileStream中的圖像數據轉儲到String中
FS.Free;
//使用TTable連接數據庫,將String中的圖像數據存入數據庫
Table1.Close;
Table1.Open;
Table1.Append;
Table1.FieldByName('IMAGEID').AsString := Edit1.Text;
Table1.FieldByName('IMAGEDATA').AsString := ImageStr;
Table1.Post;
end;
3.3從Microsoft SQL Server中取出圖像數據
下面程序的功能是利用TTable組件讀取數據庫中的圖像數據,并保存到String中,再使用TFileStream將String中的圖像數據保存到文件“c:\target.jpg”中,然后利用TImage顯示圖像文件“c:\target.jpg”。
procedure TForm1.LoadFromDBClick(Sender: TObject);
var
FS: TFileStream;
ImageStr: String;
PImageStr: PChar;
begin
//使用TTable查詢數據庫
Table1.Close;
Table1.Open;
//將數據庫中的圖像數據導出到String中
ImageStr := Table1.FieldByName('IMAGEDATA').AsString;
//將String中的圖像數據通過TFileStream寫到文件中
PImageStr := PChar(ImageStr);
FS := TFileStream.Create('c:\target.jpg', fmCreate);
FS.Write(PImageStr^, Length(ImageStr));
FS.Free;
//使用TImage組件顯示導出的圖像數據
Image1.Picture.LoadFromFile('c:\target.jpg');
end;
4結束語
Microsoft SQL Server系統為保存BLOB型數據提供了存儲平臺,Delphi為存取這種數據提供了靈活的接口。本文介紹的用Delphi存取 Microsoft SQL Server中image類型數據的方法,不但適用于各種圖像文件,同樣適用于其它類型的文件。其原理同樣適合Sybase、Oracle等數據庫和Powerbuilder、VB等前端開發工具。
(作者單位:湖北省廣播電視學校)
參考文獻:
[1]閃四清.SQL Server系統管理和應用開發指南.北京:清華大學出版社,2000
[2]黃文鈺.Delphi程序設計經典.科學出版社,2005