使用Microsoft SQL Server 存儲和檢索數據是一項與大多數應用程序相關的任務
在最近的一個項目中
我提出了一個新的交互手段——大數據類型或者 BLOB
項目必須存儲和檢索Microsoft Word 文檔和圖像文件
本文覆蓋了使用 ADO
NET 所完成任務的後台部分
後面將會有一期專欄討論使用 ASP
NET 的前台表現
什麼是 BLOB? BLOB 是二進制大對象(binary large object)的首字母縮寫
是在 SQL Server 中作為一個單一實體存儲的二進制數據集合
BLOB 主要用於保存多媒體對象
比如圖像
視頻和聲音
但是它們還可以存儲程序
甚至是代碼片斷
雖然 SQL Server 支持 BLOB
但不是所有數據都支持
訪問 BLOB 數據 有幾種方法可以用來從 SQL Server 數據庫讀取數據
首先
你可以逐行讀取數據
或者
你可以選擇從特定列中讀取數據
最簡單的方法是訪問特定的列
下面我們先討論這種方法
讀取 BLOB 數據要求工作在字節級
幸運的是
SqlDataReader 對象有一個 GetBytes 方法用於以字節方式訪問一個列的數據
一旦字節被讀取
它們就可以與一個 FileStream 對象組合
以將 BLOB 對象保存到一個文件中
下面的 C# 代碼給出了這個例子
Byte[] blob = null;
FileStream fs = null;
const string sConn =
server=(local);Initial
Catalog=Northwind;UID=ctester;PWD=password
;
try {
SqlConnection conn = new SqlConnection(sConn);
SqlCommand cmd = new SqlCommand(
SELECT Picture FROM Categories WHERE
CategoryName=
Builder
conn);
cn
Open();
SqlDataReader sdr = cmd
ExecuteReader();
sdr
Read();
blob = new Byte[(sdr
GetBytes(
null
int
MaxValue))];
sdr
GetBytes[
blob
blob
Length);
sdr
Close();
conn
Close();
fs = new FileStream(
c:\\Builder
doc
FileMode
Create
FileAccess
Write);
fs
Write(blob
blob
Length);
fs
Close();
} catch (SqlException e){
Console
WriteLine(
SQL Exception:
+ e
Message);
} catch (Exception e) {
Console
WriteLine(
Exception:
+ e
Message);
}
這段代碼從一個特定的數據單元(行和列的交叉點)中讀取一個 BLOB 對象
注意
它(通過 Using 語句)使用了System
Data
SqlClient 和System
IO 命名空間
FileStream 類的 Write 方法被用於將 BLOB 存儲到一個本地驅動器中
在這種情況下
我們知道正在處理的是文檔和圖像文件
所以存儲它們有意義
另外一種場景涉及到讀取一個數據庫記錄行
這條記錄中一個列是 BLOB 類型而其它列不是
SqlDataReader 對象的默認行為是
只要可以得到整行數據
就將傳入數據以一行記錄裝載
BLOB 對象的大小使這個方法不兼容
所以它們很難對待
這可以通過SqlCommand 類的ExecuteReader 方法來完成
你可以將CommandBehavior
SequentialAccess 傳遞給ExecuteReader 方法去修改SqlDataReader 的默認行為
以取代裝載成行的數據
它將按其接收數據的順序裝載數據
使用SequentialAccess 的主要方面是知道字段被訪問的順序
SqlDataReader 的默認行為是允許你訪問你想要訪問的任何字段
但是SequentialAccess 使你以SqlDataReader 對象返回的順序訪問字段
數據被順序讀取
所以數據在被讀取之後
它將不再可用
在訪問 BLOB 字段的數據時
SqlDataReader 類的GetBytes
GetString 和 GetChars 方法可以用來檢索數據
GetBytes 和 GetChars 允許你使用 BLOB 字段的數據填充一個數組(它們都返回 long 型數值)
下面的代碼展示了它們的使用方法
SqlConnection conn = null;
SqlCommand cmd = null;
SqlDataReader sdr = null;
FileStream fs = null;
BinaryWriter bw = null;
long blob;
byte[] outBuffer = new byte[
];
const string sConn =
server=(local);Initial
Catalog=Northwind;UID=ctester;PWD=password
;
try {
conn = new SqlConnection(sConn);
cmd = new SqlCommand(
SELECT CategoryID
Picture FROM Categories WHERE
CategoryName=
Builder
conn);
conn
Open();
sdr = cmd
ExecuteReader(CommandBehavior
SequentialAccess);
while (sdr
Read()) {
id = sdr
getString(
);
fs = new FileStream(
c:\\Builder
doc
FileMode
OpenOrCreate
FileAccess
Write);
bw = new BinaryWriter(fs);
blob = sdr
GetBytes(
startIndex
outBuffer
);
while (blob ==
) {
bw
Write(outBuffer);
bw
Flush();
startIndex +=
;
bw
Flush();
bw
Close();
fs
Close();
}
sdr
Close();
conn
Close();
} }
存儲 BLOB 數據 檢索和保存 BLOB 對象是一個很簡單的過程
相反的過程
在 SQL Server 中存儲 BLOB 對象
也一樣簡單
這裡我要指出的是
前面的例子中使用了由這個例子中的代碼存儲到表中的 BLOB 數據(Builder
doc)
SqlConnection conn =null;
SqlCommand cmd = null;
SqlParameter param = null;
FileStream fs = null;
const string sConn =
server=(local);Initial
Catalog=Northwind;UID=ctester;PWD=password
;
try {
conn = new SqlConnection(sConn);
cmd = new SqlCommand(
UPDATE Categories SET Picture = @Picture WHERE
CategoryName =
Seafood
conn);
fs = new FileStream(
c:\\Builder
doc
FileMode
Open
FileAccess
Read);
Byte[] blob = new Byte[fs
Length];
fs
Read(blob
blob
Length);
fs
Close();
param = new SqlParameter(
@Picture
SqlDbType
VarBinary
blob
Length
ParameterDirection
Input
false
null
DataRowVersion
Current
blob);
cmd
Parameters
Add(param);
conn
Open();
cmd
ExecuteNonQuery();
} catch (SqlException e){
Console
Write(
SQL Exception:
+ e
Message());
} catch (Exception e) {
Console
Write(
Exception:
e
Message());
}
示例代碼從本地文件系統插入一個 Word 文檔到數據庫中
它與常規的數據庫更新操作類似
然而
FileStream 和 Bytes 對象用於處理將 Word 文檔插入到數據庫中
另外一個變化是使用SqlParameter 對象將 BLOB 插入到數據庫字段中
這就允許數據可以直接從內存寫出到數據庫中
不是所有的數據都是相等的 雖然字符串值是開發人員與數據庫交互時最常用的數據類型
但是其它數據類型也經常使用
比如數字和 BLOB
在編程時
將將這些對象視為二進制流對待
From:http://tw.wingwit.com/Article/program/net/201311/13272.html