在本系列的前三篇文章中,主要為大家介紹了如何將BLOB文件存儲(chǔ)在SQL Server內(nèi)部。第一篇文章SQL Server:存儲(chǔ)圖像和BLOB文件(一)簡(jiǎn)單介紹了BLOB的定義和VARCHAR的數(shù)據(jù)類型家族,并討論了將BLOB插入到SQL Server的一些簡(jiǎn)單方法。第二篇文章SQL Server:存儲(chǔ)圖像和BLOB文件(二)介紹了如何利用Response.BinaryWrite將從數(shù)據(jù)庫(kù)讀出的圖片顯示到瀏覽器網(wǎng)頁(yè)上。在第三篇文章SQL Server:存儲(chǔ)圖像和BLOB文件(三)中,通過(guò)創(chuàng)建ASPX頁(yè)面來(lái)接受來(lái)自網(wǎng)頁(yè)的圖片并直接將其存儲(chǔ)到SQL Server當(dāng)中。本文將為大家介紹第二種存儲(chǔ)BLOB文件的方法,也就是把BLOB文件存儲(chǔ)到Windows文件系統(tǒng)當(dāng)中,并利用SQL Server從一個(gè)網(wǎng)頁(yè)對(duì)這些文件進(jìn)行管理。
文件系統(tǒng)實(shí)例
首先,我們要構(gòu)建一個(gè)可以用在前面的文章中所舉例子的控件——文件上傳(File Upload)控件。該控件可以嵌入到網(wǎng)頁(yè)當(dāng)中,并搜集文件信息,例如某測(cè)試圖片的文件名、目錄路徑,最終將這些信息傳遞給SQL Server。具體操作就是,創(chuàng)建一個(gè)名為FileSystemIn.aspx的代碼分離新頁(yè)面,將四個(gè)控件拖拽到該頁(yè)面上,包括一個(gè)文件上傳控件、一個(gè)按鈕控件(button)和兩個(gè)標(biāo)簽(label),如下圖所示:
為了便于解釋,在例圖上使用的是默認(rèn)控件名,實(shí)際應(yīng)用中可自行更改。
<asp:FileUpload ID="FileUpload1" runat="server" />
<br />
<br />
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
<br />
<br />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<br />
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
在代碼分離頁(yè)面上,我們將搜集文件名和目錄路徑,并將它們分別顯示到兩個(gè)標(biāo)簽上。創(chuàng)建點(diǎn)擊事件,并插入如下代碼:
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = System.IO.Path.GetFileName(FileUpload1.PostedFile.FileName.ToString()
當(dāng)點(diǎn)擊button按鈕,就會(huì)顯示通過(guò)文件上傳控件瀏覽上傳的文件,如下圖所示:
我們還可以通過(guò)一個(gè)存儲(chǔ)過(guò)程將該數(shù)據(jù)傳遞給SQL Server,這樣數(shù)據(jù)庫(kù)就可以成為我們的圖片管理器了。首先,傳見(jiàn)一個(gè)文本數(shù)據(jù)庫(kù)來(lái)保存上述文件信息,T-SQL腳本如下:
USEmaster;
GO
CREATEDATABASEBLOBTest4;
GO
USEBLOBTest4;
GO
CREATETABLEFileInfo
(
TheNamevarchar(50),
DirPathvarchar(50)
);
然后,我們創(chuàng)建一個(gè)存儲(chǔ)過(guò)程,以便網(wǎng)頁(yè)用來(lái)插入信息:
CREATEPROCEDUREFileSystemIn
(
@TheNamevarchar(50),
@DirPathvarchar(50)
)
AS
INSERTINTOFileInfo
(TheName,DirPath)
VALUES
(@TheName,@DirPath);
接下來(lái),用存儲(chǔ)過(guò)程代碼來(lái)替換代碼分離頁(yè)面代碼。現(xiàn)在,文件信息就存儲(chǔ)在SQL Server內(nèi)部,而不是顯示在標(biāo)簽上了。
stringsTheName,sDirPath;
sTheName=System.IO.Path.GetFileName(FileUpload1.PostedFile.FileName.ToString());
sDirPath=System.IO.Path.GetDirectoryName(FileUpload1.PostedFile.FileName.ToString());
stringsConn=@"server=.;database=BLOBTest4;IntegratedSecurity=True";
SqlConnectionobjConn=newSqlConnection(sConn);
objConn.Open();
SqlCommandobjCmd=newSqlCommand("FileSystemIn",objConn);
objCmd.CommandType=CommandType.StoredProcedure;
SqlParameterpTheName=objCmd.Parameters.Add("@TheName",SqlDbType.VarChar,50);
pTheName.Direction=ParameterDirection.Input;
pTheName.Value=sTheName;
SqlParameterpDirPath=objCmd.Parameters.Add("DirPath",SqlDbType.VarChar,50);
pDirPath.Direction=ParameterDirection.Input;
pDirPath.Value=sDirPath;
objCmd.ExecuteNonQuery();
objConn.Close();
測(cè)試該網(wǎng)頁(yè),對(duì)FileInfo表使用SELECT語(yǔ)句來(lái)選擇一個(gè)對(duì)象;結(jié)果將返回如下圖所示的行:
SQL Server 2008 的文件流數(shù)據(jù)類型(FILESTREAM)
以上這些方法在實(shí)施的過(guò)程中還會(huì)出現(xiàn)一些問(wèn)題。首先,如果不是通過(guò)網(wǎng)頁(yè)應(yīng)用程序而是通過(guò)其他方法刪除或添加文件的話,SQL Server就無(wú)法察覺(jué),因此不能做到和文件系統(tǒng)同步。第二個(gè)就是備份問(wèn)題。實(shí)施上述方法后,我們不僅需要備份SQL Server,還需要備份文件存儲(chǔ)的目錄路徑。此外,對(duì)于這些文件的安全問(wèn)題,SQL Server也無(wú)法控制。
SQL Server 2008提供了解決這些問(wèn)題的方法,那就是采用新的FILESTREAM數(shù)據(jù)類型。FILESTREAM文件就和標(biāo)準(zhǔn)的MDF或LDF文件一樣,是存放在Windows的NTFS分區(qū)中的,不過(guò)FILESTREAM文件是專門(mén)為存儲(chǔ)二進(jìn)制數(shù)據(jù)而設(shè)計(jì)的。用CREATEDATABASE命令來(lái)創(chuàng)建一個(gè)特殊的文件組,并將其標(biāo)記為“流(stream)”。創(chuàng)建該數(shù)據(jù)庫(kù)后,可以將表內(nèi)的一個(gè)列指定為“VARBINARY(MAX) FILESTREAM”數(shù)據(jù)類型。想要從文件系統(tǒng)訪問(wèn)存儲(chǔ)在FILESTREAM內(nèi)的BLOB是不可行的。我們無(wú)法打開(kāi)Windows文件瀏覽器并訪問(wèn)這些文件,這意味著其安全是由SQL Server數(shù)據(jù)庫(kù)負(fù)責(zé)處理的。此外,可以對(duì)這些BLOB文件使用標(biāo)準(zhǔn)的插入、更新和刪除指令進(jìn)行操作。因此對(duì)于大型的BLOB文件或像視頻流這樣性能要求很高的BLOB文件,SQL Server現(xiàn)在就有了一個(gè)可行的辦法來(lái)處理這種類型的文件了。
總結(jié)
SQL Server提供了多個(gè)方法來(lái)管理BLOB二進(jìn)制數(shù)據(jù)文件,如SQL Server 2005中的VARBINARY (MAX),更老版本中的IMAGE數(shù)據(jù)類型、以及 SQL Server 2008中新的FILESTREAM選項(xiàng)。與標(biāo)準(zhǔn)的數(shù)據(jù)類型相比,要熟練運(yùn)用這些數(shù)據(jù)類型需要稍微努把力了,不過(guò)使用的方法和使用的對(duì)象都還是比較簡(jiǎn)單易用的。需要留意,在上述的例子中并沒(méi)有包括錯(cuò)誤檢查。實(shí)際應(yīng)用當(dāng)中,必須確保文件上傳控件測(cè)試上傳沒(méi)有問(wèn)題之后,再將數(shù)據(jù)傳送到SQL Server數(shù)據(jù)庫(kù)。
聯(lián)系客服